sql >> Databáze >  >> NoSQL >> MongoDB

Najděte v Double Nested Array MongoDB

V nejjednodušším smyslu to jen následuje základní formu „tečkové notace“, kterou používá MongoDB. To bude fungovat bez ohledu na to, ve kterém členu pole je člen vnitřního pole, pokud odpovídá hodnotě:

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

To je v pořádku pro hodnotu "jednoho pole", pro shodu více polí byste použili $elemMatch :

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

To odpovídá dokumentu, který by obsahoval něco s polem na této "cestě" odpovídající hodnotě. Pokud jste zamýšleli „porovnat a filtrovat“ výsledek tak, aby byl vrácen pouze odpovídající prvek, není to možné s projekcí pozičního operátora, jak je uvedeno:

Vnořená pole

Poziční operátor $ nelze použít pro dotazy, které procházejí více než jedním polem, jako jsou dotazy, které procházejí pole vnořená do jiných polí, protože zástupný symbol $ je nahrazen jedinou hodnotou

Moderní MongoDB

Můžeme to udělat použitím $filter a $map tady. $map je skutečně potřeba, protože „vnitřní“ pole se může změnit v důsledku „filtrování“ a „vnější“ pole samozřejmě neodpovídá podmínkám, kdy bylo „vnitřní“ zbaveno všech prvků.

Opět následuje příklad skutečného použití více vlastností pro shodu v každém poli:

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

Proto na "vnějším" poli $filter ve skutečnosti se dívá na $size "vnitřního" pole poté, co bylo "filtrováno", takže tyto výsledky můžete odmítnout, když celé vnitřní pole ve skutečnosti odpovídá poznámce.

Starší MongoDB

Abyste mohli „promítnout“ pouze odpovídající prvek, potřebujete .aggregate() metoda:

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

To vám umožňuje "filtrovat" shody ve vnořených polích pro jeden nebo více výsledků v dokumentu.



  1. Projděte všechny kolekce Mongo a spusťte dotaz

  2. Jak spustit vlastního pracovníka RQ v kontejneru Docker (Python, Flask a Redis)

  3. Jak nainstalovat mongoDB na Windows?

  4. Naplňte model mongoose polem, které není id