복붙노트

[MONGODB] 봄의 데이터 일치 및 필터 중첩 배열

MONGODB

봄의 데이터 일치 및 필터 중첩 배열

어떻게 중첩 된 배열에서 데이터를 추출 할 수 있습니까?

I는 WIND_SPEED 파라미터 값과 vitRange.min vitRange.max (twaRange 풍향에 대한 동일한 조건) 사이이고 배열 항목 "값"을 추출 할

데이터 :

{
    "name" : "race"
    ,"polaire" : [
        {
            "voile" : "foc"
            , "matrice" :[
                {
                    "vitRange" : { "min" : 0, "max" : 4}
                    ,"twaRange" : { "min" : 0, "max" : 30}
                    ,"values" : [0, 0, 0, 2.4]
                },
                {
                    "vitRange" : { "min" : 4, "max" : 6}
                    ,"twaRange" : { "min" : 30, "max" : 33}
                    ,"values" : [0, 0, 2.4, 3.7]
                }
            ]
        },
        {
            "voile" : "spi"
            , "matrice" :[
                {
                    "vitRange" : { "min" : 0, "max" : 4}
                    ,"twaRange" : { "min" : 0, "max" : 30}
                    ,"values" : [0, 0, 0, 1.4]
                },
                {
                    "vitRange" : { "min" : 4, "max" : 6}
                    ,"twaRange" : { "min" : 30, "max" : 33}
                    ,"values" : [0, 0, 1.4, 2.2]
                }
            ]
        }
    ]
}

첫 번째 방법 :

Query query = new Query(
  Criteria.where("name").is(name)
  .andOperator(
    Criteria.where("polaire.voile").is(sail),
    Criteria.where("polaire.matrice.twaRange.max").lt(wind_direction),
    Criteria.where("polaire.matrice.twaRange.min").gte(wind_direction),
    Criteria.where("polaire.matrice.vitRange.max").lt(wind_speed),
    Criteria.where("polaire.matrice.vitRange.min").gte(wind_speed)
  )
);
query.fields().include("polaire.matrice.values");
Polaires data = mongoTemplate.findOne(query, Polaires.class);

두번째 방법 :

Criteria findPolaireCriteria = Criteria.where("name").is(name);
Criteria findValueCriteria = Criteria.where("polaire").elemMatch(Criteria.where("voile").is(sail))
      .andOperator(
            Criteria.where("polaire.matrice.twaRange").elemMatch(Criteria.where("max").lt(wind_direction)),
            Criteria.where("polaire.matrice.twaRange").elemMatch(Criteria.where("min").gte(wind_direction)),
            Criteria.where("polaire.matrice.vitRange").elemMatch(Criteria.where("max").lt(wind_speed)),
            Criteria.where("polaire.matrice.vitRange").elemMatch(Criteria.where("min").gte(wind_speed)));

BasicQuery query = new BasicQuery(findPolaireCriteria.getCriteriaObject(), findValueCriteria.getCriteriaObject());

query.fields().include("polaire.matrice.values");
Polaires data = mongoTemplate.findOne(query, Polaires.class);

마지막 방법 : (쿼리 참조 문서와 MongoDB를에 조건을 일치의 모든 하위 문서 (사용 봄))

Aggregation aggregation = newAggregation(
        match(Criteria.where("name").is(name)
                .and("polaire").elemMatch(Criteria.where("voile").is(sail))),
        project( "_id", "matrice")
            .and(new AggregationExpression() {
            @Override
            public DBObject toDbObject(AggregationOperationContext aggregationOperationContext ) {
                DBObject filter = new BasicDBObject("input", "$matrice")
                    .append("as", "result")
                    .append("cond",
                        new BasicDBObject("$and", Arrays.<Object> asList(
                                new BasicDBObject("$gte", Arrays.<Object> asList("$$result.vitRange.min", 0)),
                                new BasicDBObject("$lt", Arrays.<Object> asList("$$result.vitRange.max", 4))
                                )
                        )
                );
                return new BasicDBObject("$filter", filter);
            }
        }).as("matrice")
);

List<BasicDBObject> dbObjects = mongoTemplate.aggregate(aggregation, "collectionname", BasicDBObject.class).getMappedResults();     

아니면 또 다른 하나 ...

List<AggregationOperation> list = new ArrayList<AggregationOperation>();
list.add(Aggregation.match(Criteria.where("name").is(name)));
list.add(Aggregation.unwind("polaire"));
list.add(Aggregation.match(Criteria.where("polaire.voile").is(sail)));
list.add(Aggregation.unwind("polaire.matrice"));
list.add(Aggregation.match(Criteria.where("polaire.matrice.twaRange").elemMatch(Criteria.where("max").lt(wind_direction))));
list.add(Aggregation.match(Criteria.where("polaire.matrice.twaRange").elemMatch(Criteria.where("min").gte(wind_direction))));
list.add(Aggregation.match(Criteria.where("polaire.matrice.vitRange").elemMatch(Criteria.where("max").lt(wind_speed))));
list.add(Aggregation.match(Criteria.where("polaire.matrice.vitRange").elemMatch(Criteria.where("min").gte(wind_speed))));
list.add(Aggregation.group("id", "polaire.matrice").push("polaire.matrice.values").as("values"));
list.add(Aggregation.project("polaire.matrice","values"));

TypedAggregation<Polaires> agg = Aggregation.newAggregation(Polaires.class, list);
List<BasicDBObject> dbObjects = mongoTemplate.aggregate(agg, "collectionname", BasicDBObject.class).getMappedResults();     

포럼에 또 다시 돌아서하지만 그들 중 누구도 나를 도와 않습니다. 문제는 JSON 구조 (쉽게 요구에 적응)에 작업에 아마?

감사

해결법

  1. ==============================

    1.난 그냥 "폴 레어 '및 데모에 대한"matrice "의"두 번째 "배열 인덱스의"첫 번째 "배열 인덱스에 맞게 여기에 몇 가지 값을 하드 코딩거야. 여기에 $ 일치 집계 파이프 라인 단계에서 $ elemMatch의 사용 및 $지도의 사용과 $ 프로젝트 파이프 라인 단계에서 $ 필터를 참고 :

    난 그냥 "폴 레어 '및 데모에 대한"matrice "의"두 번째 "배열 인덱스의"첫 번째 "배열 인덱스에 맞게 여기에 몇 가지 값을 하드 코딩거야. 여기에 $ 일치 집계 파이프 라인 단계에서 $ elemMatch의 사용 및 $지도의 사용과 $ 프로젝트 파이프 라인 단계에서 $ 필터를 참고 :

    Aggregation aggregation = newAggregation(
      match(
        Criteria.where("name").is("race").and("polaire").elemMatch(
          Criteria.where("voile").is("foc")
            .and("matrice").elemMatch(
              Criteria.where("vitRange.min").lt(5)
                .and("vitRange.max").gt(5)
                .and("twaRange.min").lt(32)
                .and("twaRange.max").gt(32)
            )
        )
      ),
      project("name")
        .and(new AggregationExpression() {
          @Override
          public DBObject toDbObject(AggregationOperationContext context) {
            return new BasicDBObject("$map",
              new BasicDBObject("input",new BasicDBObject(
                "$filter", new BasicDBObject(
                  "input", "$polaire")
                  .append("as","p")
                  .append("cond", new BasicDBObject("$eq", Arrays.asList("$$p.voile","foc")))
              ))
              .append("as","p")
              .append("in", new BasicDBObject(
                "voile", "$$p.voile")
                .append("matrice",new BasicDBObject(
                  "$filter", new BasicDBObject(
                    "input", "$$p.matrice")
                    .append("as","m")
                    .append("cond", new BasicDBObject(
                      "$and", Arrays.asList(
                        new BasicDBObject("$lt", Arrays.asList("$$m.vitRange.min", 5)),
                        new BasicDBObject("$gt", Arrays.asList("$$m.vitRange.max", 5)),
                        new BasicDBObject("$lt", Arrays.asList("$$m.twaRange.min", 32)),
                        new BasicDBObject("$gt", Arrays.asList("$$m.twaRange.max", 32))
                      )
                    ))
                ))
              )
            );
          }
        }).as("polaire")
    );
    

    어떤이 직렬화로 변환 :

    [
      { "$match": {
        "name": "race",
        "polaire": {
          "$elemMatch": {
            "voile": "foc",
            "matrice": {
              "$elemMatch": {
                "vitRange.min": { "$lt": 5 },
                "vitRange.max": { "$gt": 5 },
                "twaRange.min": { "$lt": 32 },
                "twaRange.max": { "$gt": 32 }
              }
            }
          }
        }
      }},
      { "$project": {
        "name": 1,
        "polaire": {
           "$map": {
             "input": {
               "$filter": {
                 "input": "$polaire",
                 "as": "p",
                 "cond": { "$eq": [ "$$p.voile", "foc" ] }
               } 
             },
             "as": "p",
             "in": {
               "voile": "$$p.voile",
               "matrice": {
                 "$filter": {
                   "input": "$$p.matrice",
                   "as": "m",
                   "cond": {
                     "$and": [
                       { "$lt": [ "$$m.vitRange.min", 5 ] },
                       { "$gt": [ "$$m.vitRange.max", 5 ] },
                       { "$lt": [ "$$m.twaRange.min", 32 ] },
                       { "$gt": [ "$$m.twaRange.max", 32 ] }
                     ]
                   }
                 }
               }
             }
           }
         }
      }}
    ]
    

    그리고 일치하는 문서 출력으로 생성합니다

    {
        "_id" : ObjectId("593bc2f15924d4206cc6e399"),
        "name" : "race",
        "polaire" : [
            {
                "voile" : "foc",
                "matrice" : [
                        {
                                "vitRange" : {
                                        "min" : 4,
                                        "max" : 6
                                },
                                "twaRange" : {
                                        "min" : 30,
                                        "max" : 33
                                },
                                "values" : [
                                        0,
                                        0,
                                        2.4,
                                        3.7
                                ]
                        }
                ]
            }
        ]
    }
    

    $ 일치의 "쿼리"부분은 실제로 "문서 (들)"그 충족 조건을 선택하는 것이 중요합니다. $ elemMatch의 사용없이 표현은 실제로 모든 배열 요소에 걸쳐 확산 문서 (들)에 존재하는 것과 같은 내부 요소와 사실에 올바른 조건없이 문서를 일치시킬 수 있습니다.

    중첩 된 최초의 사용은 "내부"배열 요소부터 $ 맵 배열을 필터링하는 것은 "필터링"자신의 대상이 될 것입니다. 은 $지도뿐만 아니라 배열의 특정 요소 (들)과 일치하기 위해 $ 필터 조건에 메이크업 참조 "의"와 "출력"의 "입력"소스 모두 그래서.

    $ 필터에 "조건"( "COND")으로 우리는 부울 $ 및뿐만 아니라 "쿼리 연산자"대응의 모방 동일한 조건으로 다른 "비교 연산자"로 "논리적 집합 식"을 사용한다. 다음은 올바른 배열 항목이 "필터링"결과에 반환과 일치하는 논리에 대한 책임이 있습니다.

    참고로,이 결과는 질문에 전기와 동일해야하는 수득되는 소스 데이터이다 :

    {
            "_id" : ObjectId("593bc2f15924d4206cc6e399"),
            "name" : "race",
            "polaire" : [
                    {
                            "voile" : "foc",
                            "matrice" : [
                                    {
                                            "vitRange" : {
                                                    "min" : 0,
                                                    "max" : 4
                                            },
                                            "twaRange" : {
                                                    "min" : 0,
                                                    "max" : 30
                                            },
                                            "values" : [
                                                    0,
                                                    0,
                                                    0,
                                                    2.4
                                            ]
                                    },
                                    {
                                            "vitRange" : {
                                                    "min" : 4,
                                                    "max" : 6
                                            },
                                            "twaRange" : {
                                                    "min" : 30,
                                                    "max" : 33
                                            },
                                            "values" : [
                                                    0,
                                                    0,
                                                    2.4,
                                                    3.7
                                            ]
                                    }
                            ]
                    },
                    {
                            "voile" : "spi",
                            "matrice" : [
                                    {
                                            "vitRange" : {
                                                    "min" : 0,
                                                    "max" : 4
                                            },
                                            "twaRange" : {
                                                    "min" : 0,
                                                    "max" : 30
                                            },
                                            "values" : [
                                                    0,
                                                    0,
                                                    0,
                                                    1.4
                                            ]
                                    },
                                    {
                                            "vitRange" : {
                                                    "min" : 4,
                                                    "max" : 6
                                            },
                                            "twaRange" : {
                                                    "min" : 30,
                                                    "max" : 33
                                            },
                                            "values" : [
                                                    0,
                                                    0,
                                                    1.4,
                                                    2.2
                                            ]
                                    }
                            ]
                    }
            ]
    }
    
  2. from https://stackoverflow.com/questions/44471800/spring-data-match-and-filter-nested-array by cc-by-sa and MIT license