$project (aggregation)
On this page本页内容
Definition定义
$project
-
Passes along the documents with the requested fields to the next stage in the pipeline.将带有请求字段的文档传递到管道中的下一阶段。The specified fields can be existing fields from the input documents or newly computed fields.指定的字段可以是输入文档中的现有字段,也可以是新计算的字段。The$project
stage has the following prototype form:$project
阶段具有以下原型形式:{ $project: { <specification(s)> } }
The$project
takes a document that can specify the inclusion of fields, the suppression of the_id
field, the addition of new fields, and the resetting of the values of existing fields.$project
采用一个文档,该文档可以指定包含字段、取消显示_id
字段、添加新字段以及重置现有字段的值。Alternatively, you may specify the exclusion of fields.或者,您可以指定字段的排除。The$project
specifications have the following forms:$project
规范具有以下形式:Form Description描述<field>: <1 or true>
Specifies the inclusion of a field.指定包含字段。Non-zero integers are also treated as非零整数也被视为true
.true
。_id: <0 or false>
Specifies the suppression of the指定取消显示_id
field._id
字段。
To exclude a field conditionally, use the若要有条件地排除字段,请改用REMOVE
variable instead.REMOVE
变量。For details, see Exclude Fields Conditionally.有关详细信息,请参阅有条件地排除字段。<field>: <expression>
Adds a new field or resets the value of an existing field.添加新字段或重置现有字段的值。
If the expression evaluates to如果表达式的计算结果为$$REMOVE
, the field is excluded in the output.$$REMOVE
,则该字段将被排除在输出中。For details, see Exclude Fields Conditionally.有关详细信息,请参阅有条件地排除字段。<field>:<0 or false>
Specifies the exclusion of a field.指定字段的排除。
To exclude a field conditionally, use the若要有条件地排除字段,请改用REMOVE
variable instead.REMOVE
变量。For details, see Exclude Fields Conditionally.有关详细信息,请参阅有条件地排除字段。
If you specify the exclusion of a field other than如果指定排除_id
, you cannot employ any other$project
specification forms._id
以外的字段,则不能使用任何其他$project
规范形式。This restriction does not apply to conditionally exclusion of a field using the此限制不适用于使用REMOVE
variable.REMOVE
变量有条件排除字段。
See also the另请参阅$unset
stage to exclude fields.$unset
阶段以排除字段。
Considerations注意事项
Include Existing Fields包括现有字段
The默认情况下,_id
field is, by default, included in the output documents._id
字段包含在输出文档中。To include any other fields from the input documents in the output documents, you must explicitly specify the inclusion in若要在输出文档中包含输入文档中的任何其他字段,必须明确指定包含在$project
.$project
中。If you specify an inclusion of a field that does not exist in the document,如果指定包含文档中不存在的字段,$project
ignores that field inclusion and does not add the field to the document.$project
将忽略该字段包含,并且不会将该字段添加到文档中。
Suppress the _id
Field取消显示_id
字段
_id
FieldBy default, the 默认情况下,_id
field is included in the output documents. _id
字段包含在输出文档中。To exclude the 要从输出文档中排除_id
field from the output documents, you must explicitly specify the suppression of the _id
field in $project
._id
字段,必须在$project
中显式指定取消显示_id
字段。
Exclude Fields排除字段
If you specify the exclusion of a field or fields, all other fields are returned in the output documents.如果指定排除一个或多个字段,则输出文档中将返回所有其他字段。
{ $project: { "<field1>": 0, "<field2>": 0, ... } } // Return all but the specified fields
If you specify the exclusion of a field other than 如果指定排除_id
, you cannot employ any other $project
specification forms: i.e. if you exclude fields, you cannot also specify the inclusion of fields, reset the value of existing fields, or add new fields. _id
以外的字段,则不能使用任何其他$project
规范形式:即,如果排除字段,则也不能指定包含字段、重置现有字段的值或添加新字段。This restriction does not apply to conditional exclusion of a field using the 此限制不适用于使用REMOVE
variable.REMOVE
变量的字段的条件排除。
See also the 另请参阅$unset
stage to exclude fields.$unset
阶段以排除字段。
Exclude Fields Conditionally有条件地排除字段
You can use the variable 可以在聚合表达式中使用变量REMOVE
in aggregation expressions to conditionally suppress a field. For an example, see Conditionally Exclude Fields.REMOVE
来有条件地抑制字段。有关示例,请参阅有条件排除字段。
Add New Fields or Reset Existing Fields添加新字段或重置现有字段
MongoDB also provides MongoDB还提供$addFields
to add new fields to the documents.$addFields
来向文档中添加新字段。
To add a new field or to reset the value of an existing field, specify the field name and set its value to some expression. 若要添加新字段或重置现有字段的值,请指定字段名称并将其值设置为某个表达式。For more information on expressions, see Expressions.有关表达式的详细信息,请参阅表达式。
Literal Values文字值
To set a field value directly to a numeric or boolean literal, as opposed to setting the field to an expression that resolves to a literal, use the 要将字段值直接设置为数字或布尔文本,而不是将字段设置为解析为文本的表达式,请使用$literal
operator. $literal
运算符。Otherwise, 否则,$project
treats the numeric or boolean literal as a flag for including or excluding the field.$project
将数字或布尔文字视为包含或排除字段的标志。
Field Rename字段重命名
By specifying a new field and setting its value to the field path of an existing field, you can effectively rename a field.通过指定新字段并将其值设置为现有字段的字段路径,可以有效地重命名字段。
New Array Fields新建数组字段
The $project
stage supports using the square brackets []
to directly create new array fields. $project
阶段支持使用方括号[]
直接创建新的数组字段。If you specify array fields that do not exist in a document, the operation substitutes 如果指定的数组字段在文档中不存在,则操作会将null
as the value for that field. null
替换为该字段的值。For an example, see Project New Array Fields.有关示例,请参阅投影新数组字段。
You cannot use an array index with the 不能将数组索引与$project
stage. $project
阶段一起使用。See Array Indexes are Unsupported.请参阅不支持数组索引。
Embedded Document Fields嵌入式文档字段
When projecting or adding/resetting a field within an embedded document, you can either use dot notation, as in在嵌入文档中投影或添加/重置字段时,可以使用点表示法,如
"contact.address.country": <1 or 0 or expression>
Or you can nest the fields:或者可以嵌套字段:
contact: { address: { country: <1 or 0 or expression> } }
When nesting the fields, you cannot use dot notation inside the embedded document to specify the field, e.g. 嵌套字段时,不能在嵌入文档中使用点符号来指定字段,例如contact: { "address.country": <1 or 0 or expression> }
is invalid.contact: { "address.country": <1 or 0 or expression> }
无效。
Path Collision Errors in Embedded Fields嵌入字段中的路径冲突错误
You cannot specify both an embedded document and a field within that embedded document in the same projection.不能在同一投影中同时指定嵌入文档和该嵌入文档中的字段。
The following 以下$project
stage fails with a Path collision
error because it attempts to project both the embedded contact
document and the contact.address.country
field:$project
阶段失败,出现Path collision
错误,因为它试图投影嵌入的contact
文档和contact.address.country
字段:
{ $project: { contact: 1, "contact.address.country": 1 } }
The error occurs regardless of the order in which the parent document and embedded field are specified. The following 无论父文档和嵌入字段的指定顺序如何,都会发生错误。以下$project
fails with the same error:$project
失败,并出现相同错误:
{ $project: { "contact.address.country": 1, contact: 1 } }
$project
Stage Placement舞台布置
When you use a 当您使用$project
stage it should typically be the last stage in your pipeline, used to specify which fields to return to the client.$project
阶段时,它通常应该是管道中的最后一个阶段,用于指定要返回给客户端的字段。
Using a 在管道的开始或中间使用$project
stage at the beginning or middle of a pipeline to reduce the number of fields passed to subsequent pipeline stages is unlikely to improve performance, as the database performs this optimization automatically.$project
阶段来减少传递到后续管道阶段的字段数量不太可能提高性能,因为数据库会自动执行此优化。
Restrictions限制
An error is returned if the 如果$project
specification is an empty document.$project
规范是空文档,则返回错误。
You cannot use an array index with the 不能将数组索引与$project
stage. See Array Indexes are Unsupported.$project
阶段一起使用。请参阅不支持数组索引。
Examples实例
Include Specific Fields in Output Documents在输出文档中包含特定字段
Consider a 考虑一个包含以下文档的books
collection with the following document:books
集合:
{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}
The following 以下$project
stage includes only the _id
, title
, and the author
fields in its output documents:$project
阶段在其输出文档中仅包括_id
、title
和author
字段:
db.books.aggregate( [ { $project : { title : 1 , author : 1 } } ] )
The operation results in the following document:操作结果如下:
{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
Suppress _id
Field in the Output Documents取消输出文档中的_id
字段
_id
Field in the Output DocumentsThe 默认情况下始终包括_id
field is always included by default. _id
字段。To exclude the 要从_id
field from the output documents of the $project
stage, specify the exclusion of the _id
field by setting it to 0
in the projection document.$project
阶段的输出文档中排除_id
字段,请通过在投影文档中将_id
字段设置为0来指定排除。
Consider a 考虑一个包含以下文档的books
collection with the following document:books
集合:
{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}
The following 以下$project
stage excludes the _id
field but includes the title
, and the author
fields in its output documents:$project
阶段不包括_id
字段,但在其输出文档中包括title
和author
字段:
db.books.aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )
The operation results in the following document:操作结果如下:
{ "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
Exclude Fields from Output Documents从输出文档中排除字段
Consider a 考虑一个包含以下文档的books
collection with the following document:books
集合:
{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}
The following 以下$project
stage excludes the lastModified
field from the output:$project
阶段将lastModified
字段从输出中排除:
db.books.aggregate( [ { $project : { "lastModified": 0 } } ] )
See also the 另请参阅$unset
stage to exclude fields.$unset
阶段以排除字段。
Exclude Fields from Embedded Documents从嵌入文档中排除字段
Consider a 考虑一个包含以下文档的books
collection with the following document:books
集合:
{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}
The following 以下$project
stage excludes the author.first
and lastModified
fields from the output:$project
阶段将authorfirst
和lastModified
字段从输出中排除:
db.books.aggregate( [ { $project : { "author.first" : 0, "lastModified" : 0 } } ] )
Alternatively, you can nest the exclusion specification in a document:或者,您可以在文档中嵌套排除规范:
db.bookmarks.aggregate( [ { $project: { "author": { "first": 0}, "lastModified" : 0 } } ] )
Both specifications result in the same output:两种规格产生相同的输出:
{
"_id" : 1,
"title" : "abc123",
"isbn" : "0001122223334",
"author" : {
"last" : "zzz"
},
"copies" : 5,
}
See also the 另请参阅$unset
stage to exclude fields.$unset
阶段以排除字段。
Conditionally Exclude Fields有条件地排除字段
You can use the variable 可以在聚合表达式中使用变量REMOVE
in aggregation expressions to conditionally suppress a field.REMOVE
来有条件地抑制字段。
Consider a 考虑一个包含以下文档的books
collection with the following document:books
集合:
{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}
{
"_id" : 2,
title: "Baked Goods",
isbn: "9999999999999",
author: { last: "xyz", first: "abc", middle: "" },
copies: 2,
lastModified: "2017-07-21"
}
{
"_id" : 3,
title: "Ice Cream Cakes",
isbn: "8888888888888",
author: { last: "xyz", first: "abc", middle: "mmm" },
copies: 5,
lastModified: "2017-07-22"
}
The following 以下$project
stage uses the REMOVE
variable to excludes the author.middle
field only if it equals ""
:REMOVE
阶段使用REMOVE
变量来排除author.middle
字段,仅当它等于""
时:
db.books.aggregate( [
{
$project: {
title: 1,
"author.first": 1,
"author.last" : 1,
"author.middle": {
$cond: {
if: { $eq: [ "", "$author.middle" ] },
then: "$$REMOVE",
else: "$author.middle"
}
}
}
}
] )
The aggregation operation results in the following output:聚合操作会产生以下输出:
{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
{ "_id" : 2, "title" : "Baked Goods", "author" : { "last" : "xyz", "first" : "abc" } }
{ "_id" : 3, "title" : "Ice Cream Cakes", "author" : { "last" : "xyz", "first" : "abc", "middle" : "mmm" } }
Include Specific Fields from Embedded Documents包括嵌入文档中的特定字段
Consider a 考虑一个包含以下文档的bookmarks
collection with the following documents:bookmarks
集合:
{ _id: 1, user: "1234", stop: { title: "book1", author: "xyz", page: 32 } }
{ _id: 2, user: "7890", stop: [ { title: "book2", author: "abc", page: 5 }, { title: "book3", author: "ijk", page: 100 } ] }
To include only the 要在title
field in the embedded document in the stop
field, you can use the dot notation:stop
字段中仅包括嵌入文档中的title
字段,可以使用点表示法:
db.bookmarks.aggregate( [ { $project: { "stop.title": 1 } } ] )
Or, you can nest the inclusion specification in a document:或者,您可以在文档中嵌套包含规范:
db.bookmarks.aggregate( [ { $project: { stop: { title: 1 } } } ] )
Both specifications result in the following documents:两个规范都产生了以下文件:
{ "_id" : 1, "stop" : { "title" : "book1" } }
{ "_id" : 2, "stop" : [ { "title" : "book2" }, { "title" : "book3" } ] }
Include Computed Fields包括计算字段
Consider a 考虑一个包含以下文档的books
collection with the following document:books
集合:
{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}
The following 以下$project
stage adds the new fields isbn
, lastName
, and copiesSold
:$project
阶段添加了新字段isbn
、lastName
和copiesSold
:
db.books.aggregate(
[
{
$project: {
title: 1,
isbn: {
prefix: { $substr: [ "$isbn", 0, 3 ] },
group: { $substr: [ "$isbn", 3, 2 ] },
publisher: { $substr: [ "$isbn", 5, 4 ] },
title: { $substr: [ "$isbn", 9, 3 ] },
checkDigit: { $substr: [ "$isbn", 12, 1] }
},
lastName: "$author.last",
copiesSold: "$copies"
}
}
]
)
The operation results in the following document:操作结果如下:
{
"_id" : 1,
"title" : "abc123",
"isbn" : {
"prefix" : "000",
"group" : "11",
"publisher" : "2222",
"title" : "333",
"checkDigit" : "4"
},
"lastName" : "zzz",
"copiesSold" : 5
}
Project New Array Fields投影新数组字段
For example, if a collection includes the following document:例如,如果集合包含以下文档:
{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "x" : 1, "y" : 1 }
The following operation projects the fields 以下操作将字段x
and y
as elements in a new field myArray
:x
和y
投影为新字段myArray
中的元素:
db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y" ] } } ] )
The operation returns the following document:该操作返回以下文档:
{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1 ] }
If array specification includes fields that are non-existent in a document, the operation substitutes 如果数组规范包含文档中不存在的字段,则操作会将null
as the value for that field.null
替换为该字段的值。
For example, given the same document as above, the following operation projects the fields 例如,给定与上面相同的文档,以下操作将字段x
, y
, and a non-existing field $someField
as elements in a new field myArray
:x
、y
和不存在的字段$someField
投影为新字段myArray
中的元素:
db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y", "$someField" ] } } ] )
The operation returns the following document:该操作返回以下文档:
{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1, null ] }
Array Indexes are Unsupported不支持数组索引
You cannot use an array index with the 不能将数组索引与$project
stage. This section shows an example.$project
阶段一起使用。本节显示了一个示例。
Create the following 创建以下pizzas
collection:pizzas
集合:
db.pizzas.insert( [
{ _id: 0, name: [ 'Pepperoni' ] },
] )
The following example returns the pizza:以下示例返回pizza:
db.pizzas.aggregate( [
{ $project: { x: '$name', _id: 0 } },
] )
The pizza is returned in the example output:披萨在示例输出中返回:
[ { x: [ 'Pepperoni' ] } ]
The following example uses an array index (以下示例使用数组索引($name.0
) to attempt to return the pizza:$name.0
)来尝试返回pizza:
db.pizzas.aggregate( [
{ $project: { x: '$name.0', _id: 0 } },
] )
The pizza is not returned in the example output:示例输出中不会返回pizza:
[ { x: [] } ]