Det vigtigste her er sammenlægningen $slice
for at hente det sidste element fra arrayet,
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
]
}
}}
])
Jeg er faktisk "ekstra sikker" i $project
fase med $filter
men det hele er stort set det samme.
Først vælger forespørgslen dokumenterne, vi kan faktisk ikke på nuværende tidspunkt sige, at vi "kun" matcher det sidste element i arrayet, men vi ønsker at filtrere dokumenter, der slet ikke har betingelsen på arrayet.
$redact
er den faktiske ting, der ser på den "sidste" array-indgang og tester værdien af feltet. Vi kan kun notere feltet fra arrayet med $messages.capty
som kun returnerer en række af disse varer. Her er vi så $slice
eller endda $arrayElemAt
hvis du ønsker at få den sidste værdi, som er indekset for -1
.
På dette tidspunkt har vi kun "filtreret" de "dokumenter", som ikke matcher betingelsen. Det endelige $project
stage tager det sidste element i arrayet, kontrollerer, at det stemmer overens med betingelsen (hvilket det burde i de tidligere stadier), udtrækker værdien af "body"
og forvandler enkelt array-indholdet til kun den almindelige værdi.
Du kan skiftevis give afkald på "omhyggeligheden" og simpelthen bare gribe det sidste array-element siden $redact
skulle have gjort sit arbejde:
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 hele bryder virkelig sammen for at "matche det mulige dokumenter med en forespørgsel" og derefter "sammenlign og udtræk det sidste element med $slice
eller $arrayElemAt
".
Resultaterne er:
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}