$ (projection)
On this page本页内容
Definition定义
$
-
The positional位置$
operator limits the contents of an<array>
to return the first element that matches the query condition on the array.$
运算符限制<array>
的内容以返回与数组上的查询条件匹配的第一个元素。Use当您在所选文档中只需要一个特定的数组元素时,请在$
in the projection document of thefind()
method or thefindOne()
method when you only need one particular array element in selected documents.find()
方法或findOne()
方法的projection
文档中使用$
。See the aggregation operator请参阅聚合运算符$filter
to return an array with only those elements that match the specified condition.$filter
,以返回一个仅包含与指定条件匹配的元素的数组。NoteDisambiguation消除歧义To specify an array element to update, see the positional $ operator for updates.要指定要更新的数组元素,请参阅用于更新的位置$
运算符。
Usage Considerations使用注意事项
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.有关示例,请参阅数组字段限制。
视图上的db.collection.find()
operations on views do not support $
projection operator.db.collection.find()
操作不支持$
投影运算符。
Behavior行为
Syntax语法
To return the first array element that matches the specified query condition on the array:要返回与数组上指定查询条件匹配的第一个数组元素,请执行以下操作:
db.collection.find( { <array>: <condition> ... },
{ "<array>.$": 1 } )
db.collection.find( { <array.field>: <condition> ...},
{ "<array>.$": 1 } )
Changed in version 4.4.4.4版更改。You can use the 您可以使用$
operator to limit an <array>
field which does not appear in the query document. In previous versions of MongoDB, the <array>
field being limited must appear in the query document.$
运算符来限制未出现在query
文档中的<array>
字段。在MongoDB的早期版本中,被限制的<array>
字段必须出现在查询文档中。
db.collection.find( { <someOtherArray>: <condition> ... },
{ "<array>.$" : 1 } )
To ensure expected behavior, the arrays used in the query document and the projection document must be the same length. If the arrays are different lengths, the operation may error in certain scenarios.为了确保预期的行为,查询文档和投影文档中使用的数组必须具有相同的长度。如果数组的长度不同,则在某些情况下操作可能会出错。
Array Field Limitations数组字段限制
MongoDB requires the following when dealing with projection over arrays:MongoDB在处理数组投影时需要以下内容:
Only one positional$
operator may appear in the projection document.projection
文档中只能出现一个位置$
运算符。Only one array field should appear in the query document. Additional array fields in the query document may lead to undefined behavior.query
文档中只应显示一个数组字段。查询文档中的其他数组字段可能会导致未定义的行为。For example, the following projection may lead to undefined behavior:例如,以下投影可能导致未定义的行为:db.collection.find( { <array>: <value>, <someOtherArray>: <value2> },
{ "<array>.$": 1 } )The query document should only contain a single condition on the array field to which it is applied.query
文档应仅在应用它的数组字段上包含一个条件。Multiple conditions may override each other internally and lead to undefined behavior.多个条件可能在内部相互覆盖,并导致未定义的行为。To specify criteria on multiple fields of documents inside that array, use the要在该数组中的多个文档字段上指定条件,请使用$elemMatch
query operator.$elemMatch
查询运算符。The following query returns the first document inside a以下查询返回grades
array that has amean
of greater than 70 and agrade
of greater than 90.mean
值大于70
且grade
大于90
的grades
数组中的第一个文档。db.students.find( { grades: { $elemMatch: {
mean: { $gt: 70 },
grade: { $gt:90 }
} } },
{ "grades.$": 1 } )You must use the如果需要单独的条件来选择文档和在这些文档中选择字段,则必须使用$elemMatch
operator if you need separate conditions for selecting documents and for choosing fields within those documents.$elemMatch
运算符。
Sorts and the Positional Operator排序和位置运算符
When the 当find()
method includes a sort()
, the find()
method applies the sort()
to order the matching documents before it applies the positional $
projection operator.find()
方法包含sort()
时,find()
方法适用于sort()
从而在它应用位置$
投影运算符之前排序匹配的文档。
If an array field contains multiple documents with the same field name and the 如果一个数组字段包含多个具有相同字段名称的文档,并且find()
method includes a sort()
on that repeating field, the returned documents may not reflect the sort order because the sort was applied to the elements of the array before the $
projection operator.find()
方法在该重复字段上包含sort()
,则返回的文档可能不会反映排序顺序,因为排序是在$
投影运算符之前应用于数组元素的。
Positional Operator Placement Restriction位置运算符安置限制
Starting in MongoDB 4.4, the 从MongoDB 4.4开始,$
projection operator can only appear at the end of the field path, for example "field.$"
or "fieldA.fieldB.$"
.$
投影运算符只能出现在字段路径的末尾,例如"field.$"
或"fieldA.fieldB.$"
。
For example, starting in MongoDB 4.4, the following operation is invalid:例如,在MongoDB 4.4中启动时,以下操作无效:
db.inventory.find( { }, { "instock.$.qty": 1 } ) // Invalid starting in 4.4
To resolve, remove the component of the field path that follows the 若要解决此问题,请删除$
projection operator.$
投影运算符后面的字段路径的组件。
In previous versions, MongoDB ignores the part of the path that follows the 在以前的版本中,MongoDB会忽略$
; i.e. the projection is treated as "instock.$"
.$
;即投影被视为"instock.$"
。
Positional Operator and $slice
Restriction位置运算符和$slice
限制
$slice
RestrictionStarting in MongoDB 4.4, 从MongoDB 4.4开始,find
and findAndModify
projection cannot include $slice
projection expression as part of a $
projection expression.find
和findAndModify
投影不能包含$slice
投影表达式作为$
投影表达式的一部分。
For example, starting in MongoDB 4.4, the following operation is invalid:例如,在MongoDB 4.4中启动时,以下操作无效:
db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } ) // Invalid starting in 4.4
In previous versions, MongoDB returns the first element (在以前的版本中,MongoDB返回instock.$
) in the instock
array that matches the query condition; i.e. the positional projection "instock.$"
takes precedence and the $slice:1
is a no-op. instock
数组中与查询条件匹配的第一个元素(instock.$
);即,位置投影"instock.$"
优先,$slice:1
是no-op。The "instock.$": { $slice: 1 }
does not exclude any other document field."instock.$": { $slice: 1 }
不排除任何其他文档字段。
Examples实例
Project Array Values投影数组值
A collection students
contains the following documents:students
集合包含以下文档:
{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] }
{ "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] }
{ "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] }
{ "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] }
{ "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] }
{ "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }
In the following query, the projection 在以下查询中,投影{ "grades.$": 1 }
returns only the first element greater than or equal to 85
for the grades
field.{ "grades.$": 1 }
只返回grades
字段的第一个大于或等于85
的元素。
db.students.find( { semester: 1, grades: { $gte: 85 } },
{ "grades.$": 1 } )
The operation returns the following documents:该操作返回以下文档:
{ "_id" : 1, "grades" : [ 87 ] }
{ "_id" : 2, "grades" : [ 90 ] }
{ "_id" : 3, "grades" : [ 85 ] }
Although the array field 尽管数组字段grades
may contain multiple elements that are greater than or equal to 85
, the $
projection operator returns only the first matching element from the array.grades
可以包含大于或等于85
的多个元素,$
投影运算符仅返回数组中的第一个匹配元素。
Project Array Documents投影数组文档
A students
collection contains the following documents where the grades
field is an array of documents; each document contain the three field names grade
, mean
, and std
:students
集合包含以下文档,其中grades
字段是文档的数组;每个文档包含三个字段名称grade
、mean
和std
:
{ "_id" : 7, semester: 3, "grades" : [ { grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 90, mean: 85, std: 3 } ] }
{ "_id" : 8, semester: 3, "grades" : [ { grade: 92, mean: 88, std: 8 },
{ grade: 78, mean: 90, std: 5 },
{ grade: 88, mean: 85, std: 3 } ] }
In the following query, the projection 在以下查询中,投影{ "grades.$": 1 }
returns only the first element with the mean
greater than 70
for the grades
field:{ "grades.$": 1 }
只返回grades
字段的第一个mean
大于70
的元素:
db.students.find(
{ "grades.mean": { $gt: 70 } },
{ "grades.$": 1 }
)
The operation returns the following documents:该操作返回以下文档:
{ "_id" : 7, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 } ] }
{ "_id" : 8, "grades" : [ { "grade" : 92, "mean" : 88, "std" : 8 } ] }