Am Verhalten von $elemMatch ist nichts auszusetzen . Es funktioniert wie erwartet. Das Dokument sagt auch:
Als Faustregel gilt, wann immer Sie ein array projizieren mit $elemMatch , nur eine der Elemente werden höchstens projiziert . Wenn keines der Elemente im Array übereinstimmt, wird das Feld überhaupt nicht projiziert.
Das Ergebnis, das Sie erhalten, ist also korrekt, nur das erste Element im Array, das der Bedingung in $elemMatch entspricht wird projected .
{
"_id" : ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses" : [{
....
"StatusID": NumberLong(525623822633172993),
....
}]
}
Sie können versuchen, die Reihenfolge der Dokumente im status-Array zu ändern, und erhalten möglicherweise ein anderes übereinstimmendes Dokument, wenn dieses Dokument vor den anderen übereinstimmenden Dokumenten im Array angezeigt wird.
Siehe:$elemMatch
Um zu Ihrer Anforderung zu kommen:Wenn Sie alle übereinstimmenden Array-Elemente in Ihrem Ergebnis haben möchten, müssen Sie eine Aggregationsoperation durchführen.
Matchdie Dokumente mit der erforderlichen _id und die Dokumente, die das Status-Unterdokument enthalten, nach dem wir suchen.unwinddas Status-Array.- Erneut
matchdie einzelnen abgewickelten Dokumente. - Schließlich
groupdie übereinstimmenden Dokumente nach_id.
Der Code:
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"}}}
])
wodurch Sie alle übereinstimmenden Unterdokumente im Array erhalten.