Najważniejszą rzeczą jest tutaj agregacja $slice
aby pobrać ostatni element z tablicy,
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
]
}
}}
])
W rzeczywistości jestem „bardzo bezpieczny” w $project
etap z $filter
ale wszystko jest w zasadzie takie samo.
Najpierw zapytanie wybiera dokumenty, nie możemy w tym momencie powiedzieć, że „tylko” pasuje do ostatniego elementu tablicy, ale chcemy filtrować dokumenty, które w ogóle nie mają warunku w tablicy.
$redact
jest rzeczywistą rzeczą, która patrzy na "ostatni" wpis tablicy i testuje wartość pola. Możemy zapisać tylko pole z tablicy przez $messages.capty
co zwraca tylko tablicę tych elementów. Tutaj następnie $slice
lub nawet $arrayElemAt
jeśli chcesz uzyskać ostatnią wartość, będącą indeksem -1
.
W tym momencie „przefiltrowaliśmy” tylko „dokumenty”, które nie spełniają warunku. Ostateczny $project
stage pobiera ostatni element tablicy, sprawdza, czy pasuje do warunku (który powinien być we wcześniejszych etapach), wyodrębnia wartość "body"
i zamienia zawartość pojedynczej tablicy w zwykłą wartość.
Możesz na przemian zrezygnować z "ostrożności" i po prostu pobrać ostatni element tablicy od $redact
powinien był wykonać swoją pracę:
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 ]
}
}}
])
Całość naprawdę sprowadza się do „dopasowania możliwego dokumenty z zapytaniem”, a następnie „porównaj i wyodrębnij ostatni element za pomocą $slice
lub $arrayElemAt
".
Wyniki to:
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}