文档菜单
文档首页
/
MongoDB 手册
/ / / /

$elemMatch (投影)

本页

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

提示

另请参阅

$elemMatch (查询)

$elemMatch

$elemMatch运算符限制了查询结果中<数组>字段的值,只包含符合$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 } ]
}

关于 $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 },
],
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 },
]
}

以下 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 字段值为 102age 字段大于 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 准则。

《$elemMatch》参数匹配数组中由《$elemMatch》投影的元素。如果您将字段名与《$elemMatch》指定为相等,它将尝试匹配数组中的对象。例如,在投影中,《$elemMatch》尝试匹配对象,而不是标量值。

db.schools.find( { zipcode: "63109" },
{ athletics: { $elemMatch: { athletics: "basketball" } } })

要匹配标量值,请使用相等运算符以及您想要匹配的标量值({$eq: <标量值>})。例如,以下find()操作查询所有zipcode字段值为63109的文档。投影包括值为basketballathletics数组中的匹配元素。

db.schools.find( { zipcode: "63109" },
{ athletics: { $elemMatch: { $eq: "basketball" } } })

操作返回三个具有 zipcode 值等于 63109 的文档

[
{ _id : 1 },
{ _id: 3, athletics: [ 'basketball' ] },
{ _id : 4 }
]

具有_id等于3的文档是唯一符合《$elemMatch》条件的文档。

提示

另请参阅

$ (投影)运算符

返回

$