Docs 菜单

Docs 主页开发应用程序MongoDB Manual

$elemMatch(投影)

在此页面上

  • 定义
  • 使用注意事项
  • 举例

提示

另请参阅:

$elemMatch(查询)

$elemMatch

$elemMatch操作符将查询结果中<array> 字段的内容限制为仅包含与 条件匹配的 第一个 $elemMatch元素。

$操作符和$elemMatch操作符都会根据条件从数组中投影第一个匹配元素。

$ 操作符根据查询语句中的某些条件投影一个集合中的每个文档的第一个匹配数组元素。

$elemMatch投影操作符接受显式条件参数。这允许您根据不在查询中的条件进行投影,或者如果您需要根据数组的嵌入式文档中的多个字段进行投影。有关示例,请参阅数组字段限制

无论文档中字段的顺序如何,现有字段的$elemMatch投影都会在包含其他现有字段之后返回该字段。

例如,考虑包含以下文档的 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字段,即使在文档中,该字段列在joinedlastLogin字段之前:

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 } ]
}

在版本4中。 2及更早版本中,现有字段的$elemMatch投影支持文档中的顺序:

{
"_id" : ObjectId("5edef91e76ddff7d92f118e1"),
"games" : [ { "game" : "abc", "score" : 8 } ],
"joined" : ISODate("2020-01-01T00:00:00Z"),
"lastLogin" : ISODate("2020-05-01T00:00:00Z")
}

$elemMatch投影操作符的示例假定集合schools包含以下文档:

{
_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 },
]
}
{
_id: 3,
zipcode: "63109",
students: [
{ name: "ajax", school: 100, age: 7 },
{ name: "achilles", school: 100, age: 8 },
]
}
{
_id: 4,
zipcode: "63109",
students: [
{ name: "barney", school: 102, age: 7 },
{ name: "ruth", school: 102, age: 16 },
]
}

以下find()操作查询zipcode字段的值为63109的所有文档。 $elemMatch投影仅返回students数组的第一个匹配元素,其中school字段的值为102

db.schools.find( { zipcode: "63109" },
{ students: { $elemMatch: { school: 102 } } } )

该操作返回zipcode等于63109的以下文档,并使用$elemMatch投影students数组:

{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }
{ "_id" : 3 }
{ "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
  • 对于_id等于1的文档, students数组包含多个school字段等于102的元素。但是, $elemMatch投影仅返回数组中第一个匹配的元素。

  • _id等于3的文档在结果中不包含students字段,因为其students数组中没有与$elemMatch条件匹配的元素。

$elemMatch投影可以指定多个字段的条件:

如下 find() 操作将查询 zipcode 字段值为 63109 的所有文档。投影包括 students 数组的第一个匹配元素,其中 school 字段的值为 102,并且 age 字段大于 10

db.schools.find( { zipcode: "63109" },
{ students: { $elemMatch: { school: 102, age: { $gt: 10} } } } )

此操作将返回 zipcode 等于 63109 的三个文档:

{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] }
{ "_id" : 3 }
{ "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] }

_id等于3的文档不包含students字段,因为没有与$elemMatch条件匹配的数组元素。

提示

另请参阅:

$ (projection) 运算符

← $(投影)