MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Пролетни данни Съвпадение и филтриране на вложен масив

Просто ще кодирам твърдо някои стойности тук, за да съответстват на индекса на "първия" масив на "polaire" и индекса на "втория" масив на "matrice" за демонстрация. Забележете тук използването на $elemMatch в $match етап на тръбопровода за агрегиране и използването на $map и $filter в $project етап на тръбопровода:

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
                            ]
                    }
            ]
        }
    ]
}

Частта „заявка“ на $match Важно е действително да изберете "документа(ите)", които отговарят на условията. Без използването на $elemMatch изразът може действително да съвпада с документи без правилните условия за едни и същи вътрешни елементи и всъщност ще бъде разпространен във всички елементи на масива, присъстващи в документа(ите).

Филтрирането на масива, който е вложен първи, използва $map тъй като "вътрешният" елемент на масива също ще бъде обект на собствено "филтриране". Така че и двете "input" източник за $map както и "изхода" като "in" направи препратка към $filter условия, за да съответстват на конкретния елемент(и) на масивите.

Като "условия" ( "cond" ) към $filter ние използваме "логически изрази за агрегиране" като булевия $and както и другите "оператори за сравнение", за да имитират същите условия на техните "оператори на заявка". Те са отговорни за логиката, която съответства на правилните елементи от масива, за да се върне в „филтриран“ резултат.

За справка това са изходните данни, от които се получават резултатите, които трябва да са същите като публикуваните във въпроса:

{
        "_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
                                        ]
                                }
                        ]
                }
        ]
}



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. $unionWith – Еквивалент на MongoDB на UNION ALL

  2. Динамични ключове след $group by

  3. Обявяване на ClusterControl 1.4.2 - изданието DevOps

  4. C# mongodb - как да актуализирате вложени елементи на масив

  5. MongoDB Актуализация Deep Array