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.
Match
die Dokumente mit der erforderlichen _id und die Dokumente, die das Status-Unterdokument enthalten, nach dem wir suchen.unwind
das Status-Array.- Erneut
match
die einzelnen abgewickelten Dokumente. - Schließlich
group
die ü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.