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.