$project (aggregation)

在本页面

Definition

$project阶段具有以下原型形式:

{ $project: { <specification(s)> } }

$project可以使用一个文档,该文档可以指定字段的包含,_id字段的禁止显示,新字段的添加以及现有字段的值的重置。或者,您可以指定字段的“排除”。

$project规范具有以下形式:

Form Description
<field>: <1 or true> 指定包含一个字段。
_id: <0 or false> 指定对_id字段的抑制。


要有条件地排除字段,请改用REMOVE变量。有关详细信息,请参见有条件地排除字段
| <field>: <expression> |添加新字段或重置现有字段的值。
在版本 3.6 中进行了更改:MongoDB 3.6 添加了变量REMOVE。如果表达式的计算结果为$$REMOVE,则该字段将排除在输出中。有关详细信息,请参见有条件地排除字段
| <field>:<0 or false> |版本 3.4 中的新功能。
指定排除字段。
要有条件地排除字段,请改用REMOVE变量。有关详细信息,请参见有条件地排除字段
如果您指定了_id以外的其他字段,则您不能**使用其他任何$project规格表。此限制不适用于使用REMOVE变量有条件地排除字段。

Considerations

包含现有字段

禁止_id 字段

默认情况下,_id字段包含在输出文档中。要从输出文档中排除_id字段,必须在$project中显式指定对_id字段的禁止。

Exclude Fields

3.4 版的新功能。

如果指定一个或多个字段排除,则所有其他字段将在输出文档中返回。

如果您指定排除_id以外的其他字段,则不能使用任何其他$project规格形式:即,如果您排除字段,则也不能指定包含字段,重置现有字段的值或添加新字段。此限制不适用于使用REMOVE变量有条件地排除字段。

有条件排除字段

3.6 版的新功能。

从 MongoDB 3.6 开始,您可以在聚合表达式中使用变量REMOVE来有条件地禁止显示字段。有关示例,请参见有条件地排除字段

添加新字段或重置现有字段

Note

MongoDB 还提供$addFields将新字段添加到文档中。

要添加新字段或重置现有字段的值,请指定字段名称并将其值设置为某些表达式。有关表达式的更多信息,请参见Expressions

Literal Values

要将字段值直接设置为数字或布尔 Literals,而不是将字段设置为可解析为 Literals 的表达式,请使用$literal运算符。否则,$project将数字或布尔 Literals 视为包含或排除该字段的标志。

Field Rename

通过指定新字段并将其值设置为现有字段的字段路径,可以有效地重命名字段。

新数组字段

从 MongoDB 3.2 开始,$project阶段支持使用方括号[]直接创建新的数组字段。如果数组规范包含文档中不存在的字段,则该操作将null替换为该字段的值。有关示例,请参见投影新的数组字段

嵌入式文档字段

在嵌入式文档中投影或添加/重置字段时,可以使用dot notation,如

"contact.address.country": <1 or 0 or expression>

或者,您可以嵌套字段:

contact: { address: { country: <1 or 0 or expression> } }

嵌套字段时,不能在嵌入式文档中使用点符号来指定字段,例如contact: { "address.country": <1 or 0 or expression> }无效

Restrictions

在版本 3.4 中更改。

如果$project规范为空文档,则 MongoDB 3.4 及更高版本会产生错误。

Examples

在输出文档中包括特定字段

考虑包含以下文档的books集合:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}

以下$project阶段在其输出文档中仅包含_idtitleauthor字段:

db.books.aggregate( [ { $project : { title : 1 , author : 1 } } ] )

该操作产生以下文档:

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

禁止输出文档中的_id 字段

默认情况下始终包含_id字段。要从$project阶段的输出文档中排除_id字段,请通过在投影文档中将_id字段设置为0来指定排除。

考虑包含以下文档的books集合:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}

以下$project阶段在其输出文档中不包括_id字段,但包括titleauthor字段:

db.books.aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )

该操作产生以下文档:

{ "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

从输出文档中排除字段

3.4 版的新功能。

考虑包含以下文档的books集合:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5,
  lastModified: "2016-07-28"
}

以下$project阶段从输出中排除lastModified字段:

db.books.aggregate( [ { $project : { "lastModified": 0 } } ] )

从嵌入式文档中排除字段

3.4 版的新功能。

考虑包含以下文档的books集合:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5,
  lastModified: "2016-07-28"
}

以下$project阶段从输出中排除author.firstlastModified字段:

db.books.aggregate( [ { $project : { "author.first" : 0, "lastModified" : 0 } } ] )

或者,您可以将排除规范嵌套在文档中:

db.bookmarks.aggregate( [ { $project: { "author": { "first": 0}, "lastModified" : 0 } } ] )

两种规格的结果相同:

{
   "_id" : 1,
   "title" : "abc123",
   "isbn" : "0001122223334",
   "author" : {
      "last" : "zzz"
   },
   "copies" : 5,
}

有条件排除字段

3.6 版的新功能。

从 MongoDB 3.6 开始,您可以在聚合表达式中使用变量REMOVE来有条件地禁止显示字段。

考虑包含以下文档的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"
}

以下$project阶段仅在author.middle等于""时使用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"
            }
         }
      }
   }
] )

聚合操作将产生以下输出:

{ "_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" } }

包括嵌入式文档中的特定字段

考虑包含以下文档的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 } ] }

要在stop字段的嵌入文档中仅包含title字段,可以使用dot notation

db.bookmarks.aggregate( [ { $project: { "stop.title": 1 } } ] )

或者,您可以将包含规范嵌套在文档中:

db.bookmarks.aggregate( [ { $project: { stop: { title: 1 } } } ] )

两种规格均产生以下文件:

{ "_id" : 1, "stop" : { "title" : "book1" } }
{ "_id" : 2, "stop" : [ { "title" : "book2" }, { "title" : "book3" } ] }

包含计算字段

考虑包含以下文档的books集合:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}

以下$project阶段添加了新字段isbnlastNamecopiesSold

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

该操作产生以下文档:

{
   "_id" : 1,
   "title" : "abc123",
   "isbn" : {
      "prefix" : "000",
      "group" : "11",
      "publisher" : "2222",
      "title" : "333",
      "checkDigit" : "4"
   },
   "lastName" : "zzz",
   "copiesSold" : 5
}

投影新的数组字段

例如,如果一个集合包含以下文档:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "x" : 1, "y" : 1 }

以下操作将字段xy投影为新字段myArray中的元素:

db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y" ] } } ] )

该操作返回以下文档:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1 ] }

如果数组规范包含文档中不存在的字段,则该操作将null替换为该字段的值。

例如,给定与上述相同的文档,以下操作将字段xy和不存在的字段$someField投影为新字段myArray中的元素:

db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y", "$someField" ] } } ] )

该操作返回以下文档:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1, null ] }
首页