MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Temukan di MongoDB Array Bersarang Ganda

Dalam pengertian yang paling sederhana ini hanya mengikuti bentuk dasar dari "notasi titik" seperti yang digunakan oleh MongoDB. Itu akan berfungsi terlepas dari anggota array mana anggota array dalam berada, selama itu cocok dengan nilai:

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

Itu bagus untuk nilai "satu bidang", untuk mencocokkan beberapa bidang, Anda akan menggunakan $elemMatch :

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

Itu cocok dengan dokumen yang akan berisi sesuatu dengan bidang di "jalur" yang cocok dengan nilainya. Jika Anda bermaksud untuk "mencocokkan dan memfilter" hasilnya sehingga hanya elemen yang cocok yang dikembalikan, hal ini tidak mungkin dilakukan dengan proyeksi operator posisional, seperti dikutip:

Array Bersarang

Operator $ posisional tidak dapat digunakan untuk kueri yang melintasi lebih dari satu larik, seperti kueri yang melintasi larik bersarang di dalam larik lain, karena pengganti $ placeholder adalah nilai tunggal

MongoDB modern

Kita dapat melakukannya dengan menerapkan $filter dan $map di sini. $map sangat diperlukan karena larik "dalam" dapat berubah sebagai akibat dari "pemfilteran", dan larik "luar" tentu saja tidak cocok dengan kondisi ketika "dalam" dilucuti dari semua elemen.

Sekali lagi mengikuti contoh sebenarnya memiliki beberapa properti untuk dicocokkan dalam setiap array:

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

Oleh karena itu pada larik "luar" $filter sebenarnya melihat $size dari larik "dalam" setelah "difilter" itu sendiri, sehingga Anda dapat menolak hasil tersebut ketika seluruh larik dalam sebenarnya cocok dengan catatan.

MongoDB lama

Untuk "memproyeksikan" hanya elemen yang cocok, Anda memerlukan .aggregate() metode:

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

Itu memungkinkan Anda untuk "memfilter" kecocokan dalam array bersarang untuk satu atau beberapa hasil dalam dokumen.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana menghubungkan klien mongodb ke Meteor MongoDB lokal

  2. Tumbuh Signifikansi MongoDB di Bidang Ilmu Data

  3. Mengapa kita membutuhkan 'arbiter' dalam replikasi MongoDB?

  4. MongoDB hapus Banyak ()

  5. mongoDB/luwak:unik jika bukan nol