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

Намерете в Double Nested Array MongoDB

В най-простия смисъл това просто следва основната форма на "точкова нотация", използвана от MongoDB. Това ще работи независимо в кой член на масива се намира вътрешният член на масива, стига да съответства на стойност:

db.mycollection.find({
    "someArray.someNestedArray.name": "value"
})

Това е добре за стойност "единично поле", за съвпадение на множество полета ще използвате $elemMatch :

db.mycollection.find({
    "someArray": { 
        "$elemMatch": {
            "name": "name1",
            "someNestedArray": {
                "$elemMatch": {
                    "name": "value",
                    "otherField": 1
                }
            }
        }
    }
})

Това съвпада с документа, който би съдържал нещо с поле в този "път", съответстващ на стойността. Ако сте възнамерявали да „съпоставите и филтрирате“ резултата, така че да бъде върнат само съвпадащият елемент, това не е възможно с проекцията на позиционния оператор, както е цитирано:

Вложени масиви

Позиционният оператор $ не може да се използва за заявки, които преминават през повече от един масив, като например заявки, които преминават през масиви, вложени в други масиви, тъй като заместването на заместващия $ е една стойност

Модерен MongoDB

Можем да направим това, като приложим $filter и $map тук. $map е наистина необходим, защото "вътрешният" масив може да се промени в резултат на "филтрирането", а "външният" масив, разбира се, не отговаря на условията, когато "вътрешният" е бил лишен от всички елементи.

Отново следвайки примера за действително наличието на множество свойства, които да съвпадат във всеки масив:

db.mycollection.aggregate([
  { "$match": {
    "someArray": {
      "$elemMatch": {
         "name": "name1",
         "someNestedArray": {
           "$elemMatch": {
             "name": "value",
             "otherField": 1
           }
         }
       }
    }
  }},
  { "$addFields": {
    "someArray": {
      "$filter": {
        "input": {
          "$map": {
            "input": "$someArray",
            "as": "sa",
            "in": {
              "name": "$$sa.name",
              "someNestedArray": {
                "$filter": {
                  "input": "$$sa.someNestedArray",
                  "as": "sn",
                  "cond": {
                    "$and": [
                      { "$eq": [ "$$sn.name", "value" ] },
                      { "$eq": [ "$$sn.otherField", 1 ] }
                    ]
                  }
                }
              }             
            }
          },
        },
        "as": "sa",
        "cond": {
          "$and": [
            { "$eq": [ "$$sa.name", "name1" ] },
            { "$gt": [ { "$size": "$$sa.someNestedArray" }, 0 ] }
          ]
        }
      }
    }
  }}
])

Следователно във "външния" масив $filter всъщност разглежда $size на „вътрешния“ масив, след като самият той е бил „филтриран“, така че можете да отхвърлите тези резултати, когато целият вътрешен масив действително съвпада с отбелязването.

По-стара MongoDB

За да "проектирате" само съвпадащия елемент, имате нужда от .aggregate() метод:

db.mycollection.aggregate([
    // Match possible documents
    { "$match": {
        "someArray.someNestedArray.name": "value"
    }},

    // Unwind each array
    { "$unwind": "$someArray" },
    { "$unwind": "$someArray.someNestedArray" },

    // Filter just the matching elements
    { "$match": {
        "someArray.someNestedArray.name": "value"
    }},

    // Group to inner array
    { "$group": {
        "_id": { 
            "_id": "$_id", 
            "name": "$someArray.name"
        },
        "someKey": { "$first": "$someKey" },
        "someNestedArray": { "$push": "$someArray.someNestedArray" }
    }},

    // Group to outer array
    { "$group": {
        "_id": "$_id._id",
        "someKey": { "$first": "$someKey" },
        "someArray": { "$push": {
            "name": "$_id.name",
            "someNestedArray": "$someNestedArray"
        }}
    }} 
])

Това ви позволява да „филтрирате“ съвпаденията във вложени масиви за един или повече резултати в документа.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да генерирате уникален идентификатор на обект в mongodb

  2. Всичко, което трябва да знаете за MongoDB Client

  3. Как да добавите json във вложен масив на mongodb документ с помощта на Spring?

  4. Moongoose агрегат $match не съвпада с идентификатори

  5. MongoDB - Създаване на колекция