O principal aqui é a agregação
$slice
para obter o último elemento da matriz, 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
]
}
}}
])
Na verdade, estou sendo "extra seguro" no
$project
estágio com o $filter
mas tudo basicamente o mesmo. Primeiro, a consulta seleciona os documentos, não podemos dizer neste momento para "apenas" corresponder ao último elemento da matriz, mas queremos filtrar documentos que não têm a condição na matriz.
O
$redact
é a coisa real que analisa a "última" entrada da matriz e testa o valor do campo. Podemos anotar apenas o campo do array por $messages.capty
que retorna apenas uma matriz desses itens. Aqui nós então $slice
ou mesmo $arrayElemAt
se você deseja obter o último valor, sendo o índice de -1
. Neste ponto, apenas "filtramos" os "documentos" que não correspondem à condição. O
$project
final
stage pega o último elemento do array, verifica se ele corresponde à condição (o que deveria nos estágios anteriores), extrai o valor de "body"
e transforma o conteúdo da matriz única em apenas o valor simples. Você pode alternadamente renunciar ao "cuidado" e simplesmente pegar o último elemento do array desde
$redact
deveria ter feito seu trabalho: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 ]
}
}}
])
A coisa toda realmente se resume a "combinar com o possível documentos com uma consulta" e depois "compare e extraia o último elemento com
$slice
ou $arrayElemAt
". Os resultados são:
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}