Hal utama di sini adalah agregasi $slice
untuk mendapatkan elemen terakhir dari array,
db.chat.aggregate([
{ "$match": { "user1": 1, "messages.capty": "B" } },
{ "$redact": {
"$cond": {
"if": {
"$eq": [ { "$slice": [ "$messages.capty", -1 ] }, ["B"] ]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"user2": 1,
"body": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": { "$slice": [ "$messages",-1 ] },
"as": "m",
"cond": { "$eq": [ "$$m.capty", "B" ] }
}
},
"as": "m",
"in": "$$m.body"
}},
0
]
}
}}
])
Saya sebenarnya "ekstra aman" di $project
panggung dengan $filter
tapi pada dasarnya semua sama.
Pertama query memilih dokumen, kita tidak bisa mengatakan pada titik ini untuk "hanya" cocok dengan elemen terakhir dari array tetapi kita ingin memfilter dokumen yang tidak memiliki kondisi pada array sama sekali.
$redact
adalah hal aktual yang melihat entri array "terakhir" dan menguji nilai bidang. Kita dapat menandai hanya field dari array dengan $messages.capty
yang mengembalikan hanya sebuah array dari item-item itu. Di sini kita kemudian $slice
atau bahkan $arrayElemAt
jika Anda ingin mendapatkan nilai terakhir, menjadi indeks -1
.
Pada titik ini kami hanya "memfilter" "dokumen" yang tidak sesuai dengan kondisi. $project
terakhir
stage mengambil elemen terakhir dari array, memeriksanya agar sesuai dengan kondisi (yang seharusnya dilakukan oleh tahapan sebelumnya), mengekstrak nilai "body"
dan mengubah konten larik tunggal menjadi nilai biasa saja.
Anda dapat secara bergantian mengabaikan "kehati-hatian" dan cukup ambil elemen array terakhir sejak $redact
seharusnya melakukan tugasnya:
db.chat.aggregate([
{ "$match": { "user1": 1, "messages.capty": "B" } },
{ "$redact": {
"$cond": {
"if": {
"$eq": [ { "$arrayElemAt": [ "$messages.capty", -1 ] }, "B" ]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"user2": 1,
"body": {
"$arrayElemAt": [ "$messages.body", -1 ]
}
}}
])
Semuanya benar-benar rusak untuk "mencocokkan mungkin dokumen dengan kueri" lalu "bandingkan dan ekstrak elemen terakhir dengan $slice
atau $arrayElemAt
".
Hasilnya adalah:
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}