MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como retornar apenas a primeira ocorrência de um ID com o Mongoose?


Podemos usar a estrutura de agregação para fazer isso. Primeiro precisamos $sort por user e "_id". A partir daí, $group por "usuário" e use o $last operador acumulador para retornar o último documento para cada usuário. Observe que também podemos usar o $first operador acumulador se ordenarmos nossos documentos em ordem decrescente, mas ordenando em ordem crescente e usando $last deixar clara a nossa intenção.
db.collection.aggregate([
    { "$sort": { "user": 1, "_id": -1 } }, 
    { "$group": { 
        "_id": "$user", 
        "user": { "$last": "$$ROOT" } 
    }} 
])

que produz:
{
    "_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"
    }
}

Podemos querer adicionar um $project ao nosso pipeline, mas isso causará uma queda no desempenho. No entanto, reduzirá a quantidade de dados enviados pela rede e o tempo e a memória usados ​​para decodificar documentos no lado do cliente se não precisar de todos os pares de chave/valor em um documento retornado.

O $project palco fica assim:
{ "$project": {
    "_id": "$user._id",
    "user": "$user.user",
    "event": "$user.event",
    "group": "$user.group",
    "name": "$user.name",
    "text": "$user.text"
}}