Non c'è niente di sbagliato nel comportamento di $elemMatch
. Funziona come previsto. Il documento dice anche:
Come regola pratica ogni volta che proietti un array
usando $elemMatch
, solo uno degli elementi verranno proiettati al massimo . Se nessuno degli elementi nell'array corrisponde, il campo non verrà proiettato affatto.
Quindi il risultato che ottieni è corretto, solo il primo elemento nell'array che ha soddisfatto la condizione in $elemMatch
sarà projected
.
{
"_id" : ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses" : [{
....
"StatusID": NumberLong(525623822633172993),
....
}]
}
Puoi provare a modificare l'ordine dei documenti nell'array degli stati e potresti ottenere un documento corrispondente diverso se quel documento viene visualizzato prima degli altri documenti corrispondenti nell'array.
Fare riferimento a:$elemMatch
Venendo alla tua esigenza, se vuoi che tutti gli elementi della matrice corrispondenti nel tuo risultato, devi eseguire un'operazione di aggregazione.
Match
quei documenti che hanno l'_id richiesto e quei documenti che contengono il sottodocumento di stato che stiamo cercando.unwind
la matrice degli stati.- Ancora
match
i singoli documenti srotolati. - Finalmente
group
i documenti abbinati da_id
.
Il codice:
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"}}}
])
che ti darà tutti i documenti secondari corrispondenti nell'array.