MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Renvoie la dernière valeur vraie pour chaque groupe

La meilleure façon de le faire est d'utiliser le cadre d'agrégation. Vous devez $group vos documents par "utilisateur" et retournez le dernier document pour chaque utilisateur en utilisant le $last opérateur d'accumulateur mais pour que cela fonctionne, vous avez besoin d'une étape de tri préalable en utilisant le $sort opérateur de pipeline d'agrégation. Pour trier vos documents, vous devez tenir compte à la fois du champ "createdAt" et du champ "user".

La dernière étape du pipeline est le $match étape où vous ne sélectionnez que les derniers documents où "isAbandoned" est égal à true .

db.students.aggregate([
    { "$sort": { "user": 1, "createdAt": 1 } }, 
    { "$group": { 
        "_id": "$user", 
        "last": { "$last": "$$ROOT" }
    }}, 
    { "$match": { "last.isAbandoned": true } }
])

qui renvoie quelque chose comme ceci :

{ 
    "_id" : ObjectId("56c85244bd5f92cd78ae4bc1"),
    "last" : {
        "_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
        "user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
        "studentName" : "Rajeev",
        "createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
        "isAbandoned" : true
    }
}

Pour obtenir le résultat attendu, nous devons utiliser le $replaceRoot opérateur de pipeline à partir de la version 3.4 pour promouvoir le document intégré au plus haut niveau

{
    $replaceRoot: { newRoot: "$last" }
}

Dans l'ancienne version, vous devez utiliser le $project opération de pipeline d'agrégation pour remodeler nos documents. Donc, si nous étendons notre pipeline avec l'étape suivante :

{ 
    "$project": { 
        "_id": "$last._id", 
        "user": "$last.user", 
        "studentName": "$last.studentName", 
        "createdAt": "$last.createdAt", 
        "isAbandoned": "$last.isAbandoned"
}}

il produit la sortie attendue :

{
    "_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
    "user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
    "studentName" : "Rajeev",
    "createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
    "isAbandoned" : true
}