Vi kan använda aggregeringsramverket för att göra detta. Först måste vi $sort
av user
och "_id". Därifrån $group
av "user" och använd $last
ackumulatoroperatör för att returnera det sista dokumentet för varje användare. Observera att vi också kan använda $first
ackumulatoroperator om vi sorterar våra dokument i fallande ordning, men sorterar i stigande ordning och använder $last
göra vår avsikt tydlig.
db.collection.aggregate([
{ "$sort": { "user": 1, "_id": -1 } },
{ "$group": {
"_id": "$user",
"user": { "$last": "$$ROOT" }
}}
])
som producerar:
{
"_id" : "fje93jrg4",
"user" : {
"_id" : 2,
"user" : "fje93jrg4",
"event" : null,
"group" : null,
"name" : "Bob",
"text" : "Testing"
}
}
{
"_id" : "94fg844f",
"user" : {
"_id" : 1,
"user" : "94fg844f",
"event" : null,
"group" : null,
"name" : "Jake",
"text" : "Hello world"
}
}
{
"_id" : null,
"user" : {
"_id" : 4,
"user" : null,
"event" : "d0j3n9fn3",
"group" : null,
"name" : "My Event",
"text" : "Testing 2"
}
}
Vi kanske vill lägga till ett $project
till vår pipeline, men om du gör det kommer det att leda till sämre prestanda. Det kommer dock att minska både mängden data som skickas över tråden och tiden och minnet som används för att avkoda dokument på klientsidan om alla nyckel/värdepar i ett dokument inte behöver returneras.
$project
scenen ser ut så här:
{ "$project": {
"_id": "$user._id",
"user": "$user.user",
"event": "$user.event",
"group": "$user.group",
"name": "$user.name",
"text": "$user.text"
}}