Podemos usar el marco de agregación para hacer esto. Primero necesitamos $sort
por user
y "_id". A partir de ahí, $group
por "usuario" y utilice el $last
operador acumulador para devolver el último documento para cada usuario. Tenga en cuenta que también podemos usar el $first
operador acumulador si ordenamos nuestros documentos en orden descendente, pero ordenando en orden ascendente y usando $last
dejar clara nuestra intención.
db.collection.aggregate([
{ "$sort": { "user": 1, "_id": -1 } },
{ "$group": {
"_id": "$user",
"user": { "$last": "$$ROOT" }
}}
])
que produce:
{
"_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"
}
}
Es posible que deseemos agregar un $project
a nuestra canalización, pero hacerlo provocará una caída del rendimiento. Sin embargo, reducirá tanto la cantidad de datos enviados por cable como el tiempo y la memoria utilizados para decodificar documentos en el lado del cliente si no necesita devolver todos los pares clave/valor en un documento.
El $project
el escenario se ve así:
{ "$project": {
"_id": "$user._id",
"user": "$user.user",
"event": "$user.event",
"group": "$user.group",
"name": "$user.name",
"text": "$user.text"
}}