Няма нищо лошо в поведението на $elemMatch
. Работи според очакванията. Документът също казва:
Като основно правило, когато проектирате array
използвайки $elemMatch
,само един от елементите ще бъдат проектиранинай-много . Ако нито един от елементите в масива не съвпадне, полето изобщо няма да бъде проектирано.
Така че резултатът, който получавате, е правилен, само първият елемент в масива, който отговаря на условието в $elemMatch
ще бъдат projected
.
{
"_id" : ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses" : [{
....
"StatusID": NumberLong(525623822633172993),
....
}]
}
Можете да опитате да промените реда на документите в масива със състояния и може да получите различен съвпадащ документ, ако този документ се появи пред другите съвпадащи документи в масива.
Вижте:$elemMatch
Що се отнася до вашето изискване, ако искате всички съответстващи елементи на масива във вашия резултат, трябва да извършите операция за агрегиране.
Match
тези документи, които имат необходимия _id, и тези документи, които съдържат поддокумента на състоянието, който търсим.unwind
масивът от състояния.- Отново
match
отделните размотани документи. - Най-накрая
group
съответстващите документи по_id
.
Кодът:
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"}}}
])
което ще ви даде всички съответстващи поддокументи в масива.