Huvudsaken här är aggregeringen $slice
för att hämta det sista elementet från arrayen,
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
]
}
}}
])
Jag är faktiskt "extra säker" i $project
steg med $filter
men allt är i princip likadant.
Först väljer frågan dokumenten, vi kan faktiskt inte säga att vi "bara" matchar det sista elementet i arrayen, men vi vill filtrera dokument som inte har villkoret på arrayen alls.
$redact
är den faktiska sak som tittar på den "sista" array-posten och testar värdet på fältet. Vi kan bara notera fältet från arrayen med $messages.capty
som bara returnerar en mängd av dessa föremål. Här har vi sedan $slice
eller till och med $arrayElemAt
om du vill få det sista värdet, som är indexet för -1
.
Vid det här laget "filtrerade" vi bara de "dokument" som inte matchar villkoret. Det sista $project
stage tar det sista elementet i arrayen, kontrollerar att det matchar villkoret (vilket det borde i de tidigare stegen), extraherar värdet på "body"
och förvandlar innehållet i en array till bara det vanliga värdet.
Du kan alternativt avstå från "försiktighet" och helt enkelt bara ta det sista arrayelementet sedan $redact
borde ha gjort sitt jobb:
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 ]
}
}}
])
Det hela går verkligen sönder för att "matcha det möjliga dokument med en fråga" och sedan "jämför och extrahera det sista elementet med $slice
eller $arrayElemAt
".
Resultaten är:
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}