2013-01-25 17 views
11

Próbuję najpierw sortować dane według daty, a następnie grupować w innym polu. To nie działa dla mnie.Struktura agregacji Mongo, sortowanie, a następnie grupa nie działa

Pytanie, na które usiłuję odpowiedzieć, brzmi: Wybierz najnowszy wyraźny numer identyfikacyjny?

podane dane:

db.summary.save({"lid" : 5, "date" : 5, "cid" : 2, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 2, "date" : 2, "cid" : 1, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 4, "date" : 0, "cid" : 3, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 3, "date" : 3, "cid" : 2, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 1, "date" : 1, "cid" : 1, "circles" : [ 2 ] }) 

db.summary.aggregate({$match :{circles: 2}, $sort: {date: -1}, $group: {_id: '$cid'}}) 

robie mecz najpierw na kołach, następnie rodzajem na bieżąco, następnie grupa na cid

Wynik Dostaję:

{ 
    "result" : [ 
     { 
      "_id" : 3 
     }, 
     { 
      "_id" : 1 
     }, 
     { 
      "_id" : 2 
     } 
    ], 
    "ok" : 1 
} 

Oto moja analiza:

przed dopasowania lub sortowania według daty, dane było:

"lid" : 5, "date" : 5, "cid" : 2 
"lid" : 2, "date" : 2, "cid" : 1 
"lid" : 4, "date" : 0, "cid" : 3 
"lid" : 3, "date" : 3, "cid" : 2 
"lid" : 1, "date" : 1, "cid" : 1 

Po sortowaniu według daty, zbiór danych będzie:

"lid" : 5, "date" : 5, "cid" : 2 
"lid" : 3, "date" : 3, "cid" : 2 
"lid" : 2, "date" : 2, "cid" : 1 
"lid" : 1, "date" : 1, "cid" : 1 
"lid" : 4, "date" : 0, "cid" : 3 

Więc po zgrupowania, wynik Spodziewam się:

{ 
    "result" : [ 
     { 
      "_id" : 2 
     }, 
     { 
      "_id" : 1 
     }, 
     { 
      "_id" : 3 
     } 
    ], 
    "ok" : 1 
} 

Jakie zapytanie rozwiązuje mój problem?

Dlaczego bieżące zapytanie nie działa dla mnie?

+0

Twoje parametry potoku do "agregatu" muszą być umieszczone w tablicy lub przekazane jako niezależne obiekty zamiast jednego dużego obiektu. A twoje pytanie mówi o grupowaniu na 'cid', ale polecenie grupuje się na' $ date'. – JohnnyHK

+0

To był błąd. Powinien to być $ group: {_id: '$ cid'} – ben39

Odpowiedz

17

Po przejściu $group po $sort poprzedni sortowanie zostanie utracone. Trzeba by zrobić coś takiego, a nie tak, że data chcesz sortować według dostępna jest po zgrupowania:

db.summary.aggregate(
    {$match: {circles: 2}}, 
    {$group: {_id: '$cid', date: {$max: '$date'}}}, 
    {$sort: {date: -1}}); 

wynik:

[ { _id: 2, date: 5 }, 
    { _id: 1, date: 2 }, 
    { _id: 3, date: 0 } ] 

Dodaj $project na końcu rurociągu jeśli chcesz zmienić kształt wyjściowy.

+0

Dzięki! Dokładnie tego szukałem, mimo że już to zrozumiałem do czasu, gdy odpowiedziałeś :) – ben39

+1

nie zapominaj, że jeśli chcesz posortować coś w grupie $, musisz to uwzględnić w $ sort za pomocą '_id .data'. sprawdź http://stackoverflow.com/questions/21265170/mongodb-aggregation-sort-not-working – mwm

+2

"Kiedy $ group po $ sort w przygotowaniu, poprzedni sort jest tracony." To nie jest tak naprawdę (prawdopodobnie nieaktualne). Nie tylko jest to możliwe, ale jest to preferowany sposób, ponieważ w ten sposób sortowanie może korzystać z indeksów: https://docs.mongodb.com/manual/reference/operator/aggregation/sort/#sort-operator-and-performance – slouc

Powiązane problemy