Kueri standar tidak dapat "membandingkan" nilai dalam dokumen. Ini sebenarnya sesuatu yang Anda lakukan menggunakan .aggregate()
dan $redact
:
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Di sini kami menggunakan $filter
untuk membandingkan nilai "amount"
di dokumen induk ke yang ada di dalam array. Jika setidaknya satu "sama" maka kita "$$KEEP"
dokumen, jika tidak kita "$$PRUNE"
Di versi terbaru, kami dapat mempersingkatnya menggunakan $indexOfArray
.
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$ne": [
{ "$indexOfArray": [ "$offers.amount", "$amount" ] },
-1
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Jika Anda sebenarnya hanya menginginkan "elemen larik yang cocok" juga, maka Anda akan menambahkan $filter
dalam proyeksi:
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"amount": 1,
"offers": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}
}}
])
Namun prinsip utamanya tentu saja untuk "mengurangi" jumlah dokumen yang dikembalikan menjadi hanya yang benar-benar cocok dengan kondisi sebagai prioritas "pertama". Jika tidak, Anda hanya melakukan perhitungan yang tidak perlu dan pekerjaan yang memakan waktu dan sumber daya, untuk hasil yang nantinya akan Anda buang.
Jadi "filter" terlebih dahulu, dan "bentuk ulang" kedua sebagai prioritas.