Nie ma nic złego w zachowaniu $elemMatch . Działa zgodnie z oczekiwaniami. Dokument mówi również:
Ogólna zasada za każdym razem, gdy projektujesz array używając $elemMatch , tylko jeden elementów będzie wyświetlanych co najwyżej . Jeśli żaden z elementów w tablicy nie pasuje, pole nie będzie w ogóle wyświetlane.
Więc otrzymany wynik jest poprawny, tylko pierwszy element w tablicy, który pasuje do warunku w $elemMatch będzie projected .
{
"_id" : ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses" : [{
....
"StatusID": NumberLong(525623822633172993),
....
}]
}
Możesz spróbować zmienić kolejność dokumentów w tablicy statusów i możesz otrzymać inny pasujący dokument, jeśli ten dokument pojawi się przed innymi pasującymi dokumentami w tablicy.
Zobacz:$elemMatch
Przechodząc do Twoich wymagań, jeśli chcesz, aby wszystkie pasujące elementy tablicy znalazły się w wyniku, musisz wykonać operację agregacji.
Matchte dokumenty, które mają wymagany _id i te dokumenty, które zawierają poddokument statusu, którego szukamy.unwindtablica statusów.- Ponownie
matchposzczególne rozwinięte dokumenty. - Nareszcie
groupdopasowane dokumenty według_id.
Kodeks:
db.collection.aggregate([
{$match:{ "_id": ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses.StatusID":{$gte : NumberLong(525623822633172993)}}},
{$unwind:"$Statuses"},
{$match:{"Statuses.StatusID":{$gte : NumberLong(525623822633172993)}}},
{$group:{"_id":"$_id",statuses:{$push:"$Statuses"}}}
])
co da ci wszystkie pasujące dokumenty podrzędne w tablicy.