MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Restituisce l'ultimo valore vero per ogni gruppo

Il modo migliore per farlo è utilizzare il framework di aggregazione. Devi $group i tuoi documenti per "utente" e restituisci l'ultimo documento per ogni utente usando il $last accumulatore, ma affinché funzioni, è necessaria una fase di ordinamento preliminare utilizzando il $sort operatore della pipeline di aggregazione. Per ordinare i tuoi documenti, devi considerare sia il campo "createdAt" che il campo "utente".

L'ultima fase della pipeline è il $match fase in cui selezioni solo gli ultimi documenti in cui "isAbandoned" è uguale a true .

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

che restituisce qualcosa del genere:

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

Per ottenere il risultato atteso, dobbiamo usare il $replaceRoot operatore della pipeline a partire dalla versione 3.4 per promuovere il documento incorporato al livello superiore

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

Nella versione precedente, devi usare il $project operazione di pipeline di aggregazione per rimodellare i nostri documenti. Quindi, se estendiamo la nostra pipeline con la fase seguente:

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

produce l'output atteso:

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