2015-01-13 14 views
11

Załóżmy, że mam kolekcję takiego:Mongo zapytań na wielu polach Sub-Dokumentu

{ "arr" : [ { "name" : "a", "num" : 1 }, { "name" : "a", "num" : 2 } ] }, 
{ "arr" : [ { "name" : "b", "num" : 1 }, { "name" : "a", "num" : 2 } ] }, 
{ "arr" : [ { "name" : "b", "num" : 1 }, { "name" : "b", "num" : 2 } ] } 

i chcę znaleźć wszystkie dokumenty Kto arr zawiera sub-dokument o name = „b” i num = 2.

Jeśli zrobić kwerendę tak:

db.collection.find({ 
    $and: [ 
     { "arr.name": "b" }, 
     { "arr.num": 2 } 
    ] 
}); 

zwróci wszystkie dokumenty w kolekcji, ponieważ każdy z nich zawierają su b-dokument z albo name z „b” lub num od 2.

Próbowałem też tak:

db.collection.find({ 
    arr: [ 
     { "name": "b", "num": 2 } 
    ] 
}); 

który nie rzucać żadnych błędów, ale nie zwraca żadnych wyników .

Zapytanie w wielu polach dokumentów podrzędnych w MongoDB?

Odpowiedz

22

Faktycznie jest to operator $elemMatch, mimo że jest często nadużywany. Zasadniczo wykonuje warunki zapytania dla każdego elementu "wewnątrz" tablicy. Wszystkie argumenty MongoDB są „i” Operacja o ile wyraźnie nie nazywa inaczej:

db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2 } } }) 

Prawdopodobnie też chcą „projekt” również tutaj jeśli spodziewasz się tylko pole dopasowane i nie że cały dokument:

db.collection.find(
    { "arr": { "$elemMatch": { "name": "b", "num": 2 } } }, 
    { "arr.$": 1 } 
) 

wreszcie wyjaśnić, dlaczego druga próba nie działa, to zapytanie:

db.collection.find({ 
    "arr": [ 
     { "name": "b", "num": 2 } 
    ] 
}) 

nie pasuje do niczego, ponieważ nie ma rzeczywisty zrób cument gdzie "arr" zawiera pojedynczy element dokładnie pasujący do twoich warunków.

Twój pierwszy przykład udało ..:

db.collection.find({ 
    $and: [ 
     { "arr.name": "b" }, 
     { "arr.num": 2 } 
    ] 
}); 

Ponieważ istnieje kilka elementów tablicy, które spełniają warunki, a to nie jest po prostu uznali, że oba warunki odnoszą się do tego samego elementu. To właśnie dodaje, a kiedy potrzebujesz więcej niż jednego warunku do dopasowania, to tutaj go używasz.

+1

Bardzo przydatna i kompletna odpowiedź, przepraszam, że nie mogliśmy dwukrotnie głosować. Dzięki Neil! – Moppo

Powiązane problemy