Definition定义
$elemMatchThe$elemMatchoperator limits the contents of an<array>field from the query results to contain only the first element matching the$elemMatchcondition.$elemMatch运算符将查询结果中的<array>字段的内容限制为仅包含与$elemMmatch条件匹配的第一个元素。
Usage Considerations使用注意事项
Returned Element返回元素
Both the $ operator and the $elemMatch operator project the first matching element from an array based on a condition.$运算符和$elemMatch运算符都根据条件投影数组中的第一个匹配元素。
The $ operator projects the first matching array element from each document in a collection based on some condition from the query statement.$运算符根据查询语句中的某些条件,从集合中的每个文档中投影第一个匹配的数组元素。
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. $elemMatch投影运算符接受显式条件参数。这允许您根据查询中没有的条件进行投影,或者如果您需要根据数组嵌入文档中的多个字段进行投影。See Array Field Limitations for an example.示例请参见数组字段限制。
Field Order字段顺序
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.$elemMatch投影都会在其他现有字段包含之后返回该字段。
For example, consider a 例如,考虑一个具有以下文档的players collection with the following document: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")
} )
The following projection returns the 以下投影在投影中包含的其他现有字段之后返回games field after the other existing fields included in the projection even though in the document, the field is listed before joined and lastLogin fields:games字段,即使在文档中,该字段列在joind和lastLogin字段之前:
db.players.find( {}, { games: { $elemMatch: { score: { $gt: 5 } } }, joined: 1, lastLogin: 1 } )
That is, the operation returns the following document:也就是说,该操作返回以下文档:
{
"_id" : ObjectId("5edef64a1c099fff6b033977"),
"joined" : ISODate("2020-01-01T00:00:00Z"),
"lastLogin" : ISODate("2020-05-01T00:00:00Z"),
"games" : [ { "game" : "abc", "score" : 8 } ]
}Restrictions限制
视图上的db.collection.find()operations on views do not support$elemMatchprojection operator.db.collection.find()操作不支持$elemMatch投影运算符。You cannot specify a不能在$textquery operator in an$elemMatch.$elemMatch中指定$text查询运算符。
Examples示例
The examples on the $elemMatch projection operator assumes a collection schools with the following documents:$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 },
]
}
MongoDB Shell
C#
You can model these documents by using the following C# classes:您可以使用以下C#类对这些文档进行建模:
public class School
{
public string Id { get; set; }
[]
public string ZipCode { get; set; }
public Student[] Students { get; set; }
public string[] Athletics { get; set; }
}
public class Student
{
public string Id { get; set; }
public string Name { get; set; }
public int School { get; set; }
public int Age { get; set; }
}Zipcode Search邮政编码搜索
MongoDB Shell
The following 以下find() operation queries for all documents where the value of the zipcode field is "63109". find()操作查询邮政编码字段值为"63109"的所有文档。The $elemMatch projection returns only the first matching element of the students array where the school field has a value of 102:$elemMatch投影仅返回students数组的第一个匹配元素,其中school字段的值为102:
db.schools.find( { zipcode: "63109" },
{ students: { $elemMatch: { school: 102 } } } )C#
To perform an $elemMatch projection when using the .NET/C# driver, call the ElemMatch() method on the projection builder. Pass the name of the array field to project and the filter to apply to the array elements.
The following code example finds all documents in which the value of the Zipcode field is "63109". For each matching document, the projection returns the following fields:
Id- The first element of the
Studentsarray in which the value of the nestedSchoolfield has the value102
var results = schoolsCollection
.Find(s => s.ZipCode == "63109")
.Project(Builders<School>.Projection.ElemMatch(
field: school => school.Students,
filter: student => student.School == 102
)
).ToList();The operation returns the following documents that have a 该操作返回以下zipcode value of "63109" and projects the students array using $elemMatch:zipcode值为"63109"的文档,并使用$elemMatch投影students数组:
{ "_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._id等于1的文档,students数组包含多个school字段等于102的元素。However, the但是,$elemMatchprojection returns only the first matching element from the array.$elemMatch投影只返回数组中的第一个匹配元素。The document with_idequal to3does not contain thestudentsfield in the result since no element in itsstudentsarray matched the$elemMatchcondition._id等于3的文档在结果中不包含students字段,因为其students数组中没有元素符合$elemMatch条件。
$elemMatch with Multiple Fields具有多个字段
The $elemMatch projection can specify criteria on multiple fields.$elemMatch投影可以在多个字段上指定条件。
MongoDB Shell
The following 以下find() operation queries for all documents where the value of the zipcode field is "63109". find()操作查询zipcode字段值为"63109"的所有文档。The projection includes the first matching element of the 投影包括students array where the school field has a value of 102 and the age field is greater than 10:students数组的第一个匹配元素,其中school字段的值为102,age字段大于10:
db.schools.find( { zipcode: "63109" },
{ students: { $elemMatch: { school: 102, age: { $gt: 10} } } } )C#
The following code example finds all documents in which the value of the 以下代码示例查找Zipcode field is "63109". For each matching document, the projection returns the following fields:Zipcode字段值为"63109"的所有文档。对于每个匹配的文档,投影返回以下字段:
IdThe first element of theStudentsarray in which the value of the nestedSchoolfield has the value102and theAgefield has a value greater than10Students数组的第一个元素,其中嵌套的School字段的值为102,Age字段的值大于10
var results = schoolsCollection
.Find(s => s.ZipCode == "63109")
.Project(Builders<School>.Projection.ElemMatch(
field: school => school.Students,
filter: student => (student.School == 102) && (student.Age > 10)
)
).ToList();The operation returns the three documents that have a 该操作返回三个zipcode value of "63109":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._id等于3的文档不包含students字段,因为没有数组元素符合$elemMatch标准。
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. $elemMatch的参数与$elemMack正在投影的数组元素相匹配。如果将字段名的相等项指定为$elemMatch,它将尝试匹配数组中的对象。For example, 例如,$elemMatch attempts to match objects, instead of scalar values, within the array for the following in the projection:$elemMatch尝试匹配投影中以下对象的数组中的对象,而不是标量值:
MongoDB Shell
db.schools.find( { zipcode: "63109" },
{ athletics: { $elemMatch: { athletics: "basketball" } } })C#
var results = schoolsCollection
.Find(s => s.ZipCode == "63109")
.Project(Builders<School>.Projection.ElemMatch(
"athletics",
Builders<School>.Filter.Eq("athletics", "basketball"))
).ToList();The preceding examples return the documents that have a 前面的示例返回了zipcode value of "63109", but these documents include only the _id field because the projection operation found no matching elements.zipcode值为"63109"的文档,但这些文档仅包含_id字段,因为投影操作没有找到匹配的元素。
MongoDB Shell
To match scalar values, use the equality operator along with the scalar value that you want to match (要匹配标量值,请使用相等运算符以及要匹配的标量值({$eq: <scalar value>}). {$eq: <scalar value>})。For example, the following 例如,以下find() operation queries for all documents where the value of the zipcode field is "63109". find()操作查询所有zipcode字段值为"63109"的文档。The projection includes the matching element of the 投影包括athletics array where the value is basketball:athletics数组的匹配元素,其中值是basketball:
db.schools.find( { zipcode: "63109" },
{ athletics: { $elemMatch: { $eq: "basketball" } } })C#
To perform an 要在使用.NET/C#驱动程序时对数组中的标量值执行$elemMatch operation against scalar values in an array when using the .NET/C# driver, call the ElemMatch() method on the projection builder. $elemMatch操作,请在投影生成器上调用elemMatch()方法。Pass the name of the array field to project and an equality filter for the field 将数组字段的名称传递给项目,并为字段"$eq" and the value you want to compare against."$eq"和要比较的值传递相等筛选器。
var results = schoolsCollection
.Find(s => s.ZipCode == "63109")
.Project(Builders<School>.Projection.ElemMatch(
field: "athletics",
filter: Builders<School>.Filter.Eq("$eq", "basketball"))
).ToList();The operation returns the three documents that have 该操作返回zipcode value of "63109". The returned documents include the _id field and matching elements of the athletics array, if any.zipcode值为"63109"的三个文档。返回的文档包括_id字段和田径数组的匹配元素(如果有的话)。
[
{ _id: 1 },
{ _id: 3, athletics: [ 'basketball' ] },
{ _id: 4 }
]
The document with _id equal to 3 is the only document that matched the $elemMatch criteria._id等于3的文档是唯一符合$elemMatch条件的文档。
Tip
$ (projection) operator