2012-09-16 20 views
27

Mam bazę danych studentów i ich dane kontaktowe. Próbuję znaleźć kod pocztowy, w którym mieszka większość studentów. Dokumenty dla studentów wyglądać tak ...agregacja mongodb sortowanie

{studentcode: 'smi0001', imię: 'bob', nazwisko: 'Smith', kod pocztowy: 2001}

I że mogę użyć ramy agregacji, aby dowiedzieć się pocztowego z większości studentów robiąc coś podobnego ...

db.students.aggregate({$project: { postcode: 1 }, $group: {_id: '$postcode', students: {$sum: 1}}}) 

to działa zgodnie z oczekiwaniami (zwraca kody pocztowe jak _id oraz liczbę uczniów w każdy kod pocztowy to "studenci", ale jeśli dodaję $sort do potoku, wydaje się, że próbuję sortować według całej kolekcji uczniów zamiast wyników operacji $group.

co próbuję wyglądać ...

db.students.aggregate({$project: { postcode: 1 }, $group: {_id: '$postcode', students: {$sum: 1}}, $sort: {_id: -1}}) 

ale zwraca całą kolekcję i pomija $project i $group ... jestem brakuje czegoś? Myślałem, że będę mógł sortować według malejącej liczby studentów i zwrócić pierwszy przedmiot. Z góry dziękuję za pomoc.

Odpowiedz

47

Prawie pędził ...

db.test.aggregate(
    {$group: {_id: '$postcode', students: {$sum: 1}}}, 
    {$sort: {_id: -1}} 
); 

daje (dodałam trochę danych testowych pasujących próby):

{ 
    "result" : [ 
    { 
     "_id" : 2003, 
     "students" : 3 
    }, 
    { 
     "_id" : 2002, 
     "students" : 1 
    }, 
    { 
     "_id" : 2001, 
     "students" : 2 
    } 
    ], 
    "ok" : 1 
} 

Miałeś zewnętrzną {} wokół wszystkiego, co było przyczyną pewne zamieszanie . Grupa i sortowanie nie działały jako oddzielne operacje w potoku.

Nie potrzebowałeś projektu dla tej sprawy.

Aktualizacja Prawdopodobnie chcesz, aby posortować według „studenci”, jak tak, aby uzyskać największe zipcodes (pod względem liczby ludności) pierwsza:

db.test.aggregate(
    {$group: {_id: '$postcode', students: {$sum: 1}}}, 
    {$sort: {students: -1}} 
); 
+0

Dziękuję za porady. Nie mogę uwierzyć, że to był po prostu niesłuszny problem z nawiasami. Są to problemy, z którymi miałem do czynienia podczas nauki języka SQL 15 lat temu, przejście do mongody oznaczało pozostawienie tylu wcześniejszych informacji, ale sądzę, że warto. Pozdrawiam, –

+0

Działa na Twój przypadek użycia, ale to podejście nie zawsze gwarantuje oczekiwane rezultaty. Na przykład wyniki będą niepoprawne, gdy zachodzi potrzeba grupowania według 'field1', ale zachowaj je posortowane według' field2'. – astronaut

+0

Posiadałem kody pocztowe POST1, POST2, POST3, każdy kod pocztowy ma inną niż liczba studentów. Jakie powinno być moje zapytanie sortujące, aby uzyskać sumę poszczególnych testów POST. db.test.aggregate ( {$ grupa: {_id: {'kody pocztowe:' $ kody pocztowe}}, studenci: {$ suma: 1}}}, Co powinno być zapytaniem sortowania tutaj: ); –

3

Myślę, że składnia jest nieco źle. Każda operacja agregacji w potoku powinna być własnym dokumentem.

db.students.aggregate({$project: ...}, {$group: ...}, {$sort: ...}) 

W twoim przypadku, powinno być:

db.students.aggregate(
    {$project: { postcode: 1 }}, 
    {$group: {_id: '$postcode', students: {$sum: 1}}}, 
    {$sort: {students: -1}} 
) 

Przetestowałem go na pobierania próbek oparty na schemacie i działa dla mnie, sortowania pogrupowane według kodów pocztowych liczby studentów , schodząc.

+0

Czy '$ project' coś dla ciebie robi w tym przypadku? –

+0

@WesFreeman Masz rację, projekt $ można pominąć. Wydaje mi się, że gdybyś miał naprawdę duże dokumenty, przycinanie ich tylko do niezbędnych informacji do dalszego przetwarzania może przynieść korzyści, ale w tym przypadku niewiele zyskuje. – Thomas

+0

Tak, moje "studenckie" dokumenty mają w rzeczywistości więcej pól, więc używam projektu do wycięcia niepotrzebnych pól. –

Powiązane problemy