2012-11-02 12 views
7

Korzystanie z architektury agregującej, jaki jest najlepszy sposób uzyskania dokumentów o maksymalnej wartości pola na grupę, więc korzystając z kolekcji poniżej, jak mieć funkcjonalność zwracania jednego dokumentu dla każdego group_id mającego najnowszą datę. Druga lista pokazuje pożądany wynik.Agregacja według pola i wybieranie dokumentu z maksymalną wartością innego pola jako kolekcji

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 

pożądanego rezultatu

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

[? Co próbowałeś] (http://whathaveyoutried.com) – JohnnyHK

+0

wiem, że to nie jest całkiem to, czego szukaliśmy, ale można iteracyjne poprzez identyfikatory grupowe i wykonaj coś takiego: db.foo.find ({id_grupy: n}) .sort ({data: -1}) .limit (1) - dla każdego group_id = n. Spowoduje to uporządkowanie wszystkich dokumentów o danym identyfikatorze grupy według daty, a następnie zwróci tylko najnowszą. – Louisa

Odpowiedz

6

Można użyć funkcji grupowania w ramach Aggregation z $max znaleźć najnowszy dokument dla każdego group_id. Będziesz potrzebował dodatkowych zapytań, aby pobrać pełne dokumenty na podstawie pogrupowanych kryteriów.

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)); 
}); 

Wyniki Przykład:

{ 
    "_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

Dzięki, więc jak mam je zdobyć jako całość dokumentów z maksymalną datą? Czy powinienem projektować po grupowaniu i chwytać wszystkie pola jawnie? – user1795267

+0

Grupowanie będzie łączyć dokumenty, co prawdopodobnie nie jest tym, co zamierzacie. Zaktualizowałem przykład użycia struktury agregacji do znalezienia najnowszego dokumentu '_id' oraz zapytania' $ in' w celu pobrania pełnych dokumentów. – Stennie

+2

@Stennie Dzięki, to jest świetne! Ale czy nie powinna być wybrana opcja $ max id tylko wybrać najwyższy _id, a nie id dokumentu z datą $ max? Czy zamawianie ma tu znaczenie? – Timothy055

Powiązane problemy