2012-11-02 8 views
7

das Aggregat Framework, was ist der beste Weg, um Dokumente mit einem maximalen Wert eines Feldes erhalten pro Gruppierung so mit der Sammlung unten Ich würde möchte Funktionalität haben, um ein Dokument für jede Gruppen-ID zurückzugeben, die das späteste Datum hat. Die zweite Auflistung zeigt das gewünschte Ergebnis.Aggregieren von einem Feld und Auswahl des Dokuments mit dem Max-Wert eines anderen Feldes als eine Sammlung

group_id date 
1  11/1/12 
1  11/2/12 
1  11/3/12 
2  11/1/12 
3  11/2/12 
3  11/3/12 

Gewünschtes Ergebnis

group_id date 
1  11/3/12 
2  11/1/12 
3  11/3/12 
+3

[? Was Sie versucht haben] (http://whathaveyoutried.com) – JohnnyHK

+0

Ich weiß, das ist nicht ganz, was Sie suchen, aber man konnte iterieren durch die Gruppen-IDs, und tun Sie etwas wie: db.foo.find ({group_id: n}) .sort ({Datum: -1}) .limit (1) - für jede group_id = n. Dies wird alle Dokumente mit einer bestimmten Gruppenkennung nach Datum sortieren und dann nur die letzte zurückgeben. – Louisa

Antwort

6

können Sie verwenden, um die $max Gruppierungsfunktion in der Aggregation Framework das neueste Dokument für jeden group_id zu finden. Sie benötigen zusätzliche Abfragen, um die vollständigen Dokumente basierend auf den gruppierten Kriterien abzurufen.

var results = new Array(); 
db.groups.aggregate(
    // Find documents with latest date for each group_id 
    { $group: { 
     _id: '$group_id', 
     date: { $max: '$date' }, 
    }}, 
    // Rename _id to group_id, so can use as find criteria 
    { $project: { 
     _id: 0, 
     group_id:'$_id', 
     date: '$date' 
    }} 
).result.forEach(function(match) { 
    // Find matching documents per group and push onto results array 
    results.push(db.groups.findOne(match)); 
}); 

Beispiel Ergebnisse:

{ 
    "_id" : ObjectId("5096cfb8c24a6fd1a8b68551"), 
    "group_id" : 1, 
    "date" : ISODate("2012-11-03T00:00:00Z"), 
    "foo" : "bar" 
} 
{ 
    "_id" : ObjectId("5096cfccc24a6fd1a8b68552"), 
    "group_id" : 2, 
    "date" : ISODate("2012-11-01T00:00:00Z"), 
    "foo" : "baz" 
} 
{ 
    "_id" : ObjectId("5096cfddc24a6fd1a8b68553"), 
    "group_id" : 3, 
    "date" : ISODate("2012-11-03T00:00:00Z"), 
    "foo" : "bat" 
} 
+0

Danke, also wie würde ich diese als die ganzen Dokumente mit dem maximalen Datum bekommen? Soll ich nach der Gruppierung nach oben und alle Felder explizit greifen? – user1795267

+0

Gruppierung wird die Dokumente kombinieren, was wahrscheinlich nicht das ist, was Sie beabsichtigen. Ich habe das Beispiel aktualisiert, um das Aggregationsframework zu verwenden, um das letzte Dokument '_id' zu finden, und eine' $ in'-Abfrage, um die vollständigen Dokumente zu holen. – Stennie

+2

@Stennie Danke, das ist großartig! Aber sollte nicht die $ max-ID-Auswahl nur die höchste _id und nicht die ID des Dokuments mit dem $ max-Datum wählen? Ist das Bestellen hier wichtig? – Timothy055

Verwandte Themen