2012-02-05 21 views
5

Powiedzmy, że mam kolekcję w mongodb, której obiekty mają zagnieżdżoną tablicę. Chcę sortować na podstawie wartości określonego elementu tablicy. czy to możliwe?Czy mogę sortować według elementu w zagnieżdżonej tablicy w Mongo?

Na przykład (i właśnie podałem przykład), jeśli mam kolekcję typów filmów (akcja, komedia, romans) i przykłady przesłane przez użytkowników, mogę znaleźć wszystkie obiekty, w których dany użytkownik został posortowany posortowany według data filmu?

Na przykład chciałbym znaleźć wszystkie typy, w których "Aaron" przedstawił przykład, posortowany według roku podanego przykładu "Aaron".

To prawie jak potrzeba, gdzie klauzula w tym rodzaju.

> db.movies.find(). Pretty();

{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 

> db.movies.find ({ 'examples.submitter': 'Aaron'}) sort.. ({ 'Examples.year': 1}) ładna();

{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 

Uwaga dokumenty zwracane są klasyfikowane według roku zbiorów (zgodnie z oczekiwaniami) - dowolny sposób sortować według tylko te złożone przez danego użytkownika? dla niektórych dodatkowych szczegółów używam ngo-macierzystego sterownika dla nodejów.

Odpowiedz

5

... jakikolwiek sposób sortowania według przesłanych przez danego użytkownika?

Nie sądzę, że to zadziała tak, jak tego chcesz.

W MongoDB zapytania zwracają całe dokumenty. Gdy wykonasz następujące zapytanie, znajdziesz wszystkie dokumenty, w których dowolny nadawca pasuje do 'Aaron'.

> db.movies.find({'examples.submitter': 'Aaron'}) 

Zauważ, że 'Aaron' teoretycznie może dopasować dwa razy w tym samym dokumencie, ale tylko raz zwrócić ten dokument. To komplikuje problem z sortowaniem.

> db.movies.find({'examples.submitter': 'Aaron'}).sort({'examples.year': 1}) 

Więc czego się spodziewać, gdy jeden dokument zawiera dwie rzeczy przez 'Aaron' z różnymi latami? Pamiętaj, że możemy tylko sortować dokumenty, nie możemy posortować wewnętrznej tablicy za pomocą zapytania.

Problem polega na tym, że używasz "tablic obiektów", co komplikuje cały proces. Twoje pytanie sortujące zakłada, że ​​możemy działać na obiektach wewnętrznych i naprawdę nie możemy.

Proszę spojrzeć na nowy Aggregation Framework, który może dostarczyć tego, czego szukasz. Zauważ, że jest to obecnie funkcja w gałęzi niestabilnej.

+0

Nie sądziłem, że będę w stanie to zrobić, ale uznałem, że warto było spróbować. Cieszę się, że podniosłem to, o czym wspominasz w Aggregation Framework, o którym wspomniałeś, że uda mi się tam dotrzeć, gdy będę gotowy/stabilny. Dzięki! – Zugwalt

0

Dla Twojego przypadku będziesz musiał użyć eval i wykonać niestandardowe sortowanie na server side. Spójrz na here dla konkretnego przykładu sortowania. Twoja funkcja porównania będzie nieco bardziej złożona, ponieważ będziesz musiał przejść przez tablicę "przykłady" i przefiltrować ją przez przesyłającego.

1

W przypadku, ktoś inny natyka się na to, udało mi się rozwiązać podobny problem, tworząc indeks jak:

{'examples.submitter': 1, 'examples.year': 1} 

Jeśli zmusić zapytanie do korzystania z tego indeksu za pomocą podpowiedzi („indexname”), Twoje wyniki powrócą w kolejności indeksu.

+0

Czy mógłbyś dokładniej opisać, gdzie umieścisz ten plik/jak to działa? Walczę też z problemem bardzo podobnym do tego tutaj. – ritmatter

+1

Musisz użyć .ensureIndex w swojej kolekcji. Zwykle robisz to za pomocą mongo db lub w wierszu poleceń. http://docs.mongodb.org/manual/reference/method/db.collection.ensureIndex/ Aby uzyskać podpowiedź, możesz użyć mongodb http://docs.mongodb.org/manual/reference/operator/meta/hint/ lub z mangą użyj funkcji podpowiedzi w zapytaniu. query.hint ({indexA: 1, indexB: -1}) –

Powiązane problemy