MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Gibt den letzten wahren Wert für jede Gruppe zurück

Der beste Weg, dies zu tun, ist die Verwendung des Aggregation Frameworks. Sie müssen $group Ihre Dokumente nach "Benutzer" und geben Sie das letzte Dokument für jeden Benutzer mit $last zurück Akkumulator-Operator, aber damit das funktioniert, benötigen Sie eine Vorsortierung mit dem $sort Aggregation-Pipeline-Betreiber. Um Ihre Dokumente zu sortieren, müssen Sie sowohl das Feld „createdAt“ als auch das Feld „user“ berücksichtigen.

Die letzte Stufe in der Pipeline ist $match Phase, in der Sie nur die letzten Dokumente auswählen, bei denen "isAbandoned" gleich true ist .

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

was so etwas zurückgibt:

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

Um das erwartete Ergebnis zu erhalten, müssen wir $replaceRoot verwenden Pipeline-Operator ab Version 3.4, um das eingebettete Dokument auf die oberste Ebene zu befördern

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

In älteren Versionen müssen Sie das $project verwenden Aggregations-Pipeline-Betrieb, um unsere Dokumente umzugestalten. Wenn wir also unsere Pipeline um die folgende Stufe erweitern:

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

es erzeugt die erwartete Ausgabe:

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