Hlavní věc je zde agregace $slice
získat poslední prvek z pole,
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
]
}
}}
])
Ve skutečnosti jsem "extra bezpečný" v $project
fázi s $filter
ale v podstatě je to stejné.
Nejprve dotaz vybere dokumenty, v tuto chvíli vlastně nemůžeme říci, že „pouze“ odpovídá poslednímu prvku pole, ale chceme filtrovat dokumenty, které podmínku pole vůbec nemají.
$redact
je skutečná věc, která se dívá na "poslední" položku pole a testuje hodnotu pole. Můžeme označit pouze pole z pole pomocí $messages.capty
který vrátí pouze pole těchto položek. Zde pak $slice
nebo dokonce $arrayElemAt
pokud chcete získat poslední hodnotu, kterou je index -1
.
V tomto okamžiku jsme pouze "filtrovali" "dokumenty", které neodpovídají podmínce. Konečný $project
stage vezme poslední prvek pole, zkontroluje, zda odpovídá podmínce (což by měl v dřívějších fázích), extrahuje hodnotu "body"
a změní obsah jednoho pole pouze na prostou hodnotu.
Můžete se střídavě vzdát "opatrnosti" a jednoduše chytit poslední prvek pole od $redact
měl udělat svou práci:
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 ]
}
}}
])
Celá věc se skutečně rozpadá tak, aby „odpovídala možnému dokumenty s dotazem“ a poté „porovnejte a extrahujte poslední prvek pomocí $slice
nebo $arrayElemAt
".
Výsledky jsou:
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}