定义
$elemMatchThe
$elemMatchoperator limits the contents of an<array>field from the query results to contain only the first element matching the$elemMatchcondition.
使用注意事项
返回的元素
Both the $ operator and the $elemMatch operator project the first matching element from an array based on a condition.
$ 操作符根据查询语句中的某些条件投影一个集合中的每个文档的第一个匹配数组元素。
The $elemMatch projection operator takes an explicit condition argument. This allows you to project based on a condition not in the query, or if you need to project based on multiple fields in the array's embedded documents. See Array Field Limitations for an example.
字段排序
Regardless of the ordering of the fields in the document, the $elemMatch projection of an existing field returns the field after the other existing field inclusions.
例如,考虑包含以下文档的 players 集合:
db.players.insertOne( { name: "player1", games: [ { game: "abc", score: 8 }, { game: "xyz", score: 5 } ], joined: new Date("2020-01-01"), lastLogin: new Date("2020-05-01") } )
以下投影会在投影中包含的其他现有字段之后返回 games 字段,即使在文档中,该字段位于 joined 和 lastLogin 字段之前:
db.players.find( {}, { games: { $elemMatch: { score: { $gt: 5 } } }, joined: 1, lastLogin: 1 } )
换言之,该操作会返回以下文档:
{ "_id" : ObjectId("5edef64a1c099fff6b033977"), "joined" : ISODate("2020-01-01T00:00:00Z"), "lastLogin" : ISODate("2020-05-01T00:00:00Z"), "games" : [ { "game" : "abc", "score" : 8 } ] }
限制
db.collection.find()operations on views do not support$elemMatchprojection operator.You cannot specify a
$textquery operator in an$elemMatch.
示例
The examples on the $elemMatch projection operator assumes a collection schools with the following documents:
{ _id: 1, zipcode: "63109", students: [ { name: "john", school: 102, age: 10 }, { name: "jess", school: 102, age: 11 }, { name: "jeff", school: 108, age: 15 } ] }, { _id: 2, zipcode: "63110", students: [ { name: "ajax", school: 100, age: 7 }, { name: "achilles", school: 100, age: 8 }, ], athletics: [ "swimming", "basketball", "football" ] }, { _id: 3, zipcode: "63109", students: [ { name: "ajax", school: 100, age: 7 }, { name: "achilles", school: 100, age: 8 }, ], athletics: [ "baseball", "basketball", "soccer" ] }, { _id: 4, zipcode: "63109", students: [ { name: "barney", school: 102, age: 7 }, { name: "ruth", school: 102, age: 16 }, ] }
邮政编码搜索
The operation returns the following documents that have a zipcode value of "63109" and projects the students array using $elemMatch:
{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
For the document with
_idequal to1, thestudentsarray contains multiple elements with theschoolfield equal to102. However, the$elemMatchprojection returns only the first matching element from the array.The document with
_idequal to3does not contain thestudentsfield in the result since no element in itsstudentsarray matched the$elemMatchcondition.
$elemMatch (针对多个字段)
The $elemMatch projection can specify criteria on multiple fields.
此操作将返回 zipcode 值为 "63109" 的三个文档:
{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] }
The document with _id equal to 3 does not contain the students field since no array element matched the $elemMatch criteria.
The argument to $elemMatch matches elements of the array that $elemMatch is projecting. If you specify an equality with a field name to $elemMatch, it attempts to match objects within the array. For example, $elemMatch attempts to match objects, instead of scalar values, within the array for the following in the projection:
前面的示例返回 zipcode 值为 "63109" 的文档,但这些文档仅包含 _id字段,因为投影操作未找到匹配元素。
此操作将返回 zipcode 值为 "63109" 的三个文档。返回的文档包括 _id 字段和 athletics 数组中的匹配元素(如果有)。
[ { _id: 1 }, { _id: 3, athletics: [ 'basketball' ] }, { _id: 4 } ]
The document with _id equal to 3 is the only document that matched the $elemMatch criteria.
提示
$ (projection) 运算符