翻译或纠错本页面

返回查询的映射字段

默认地,MongoDB中的查询返回匹配文档中的所有字段。为了限制MongoDB发送给应用的数据量,您可以在查询操作中包括一个 projection 文档。

映射文档

映射文档限制了返回所有匹配文档的字段。映射文档可以指明包括哪些字段或者排除哪些字段,有以下形式:

{ field1: <value>, field2: <value> ... }

The <value> can be any of the following:

  • 1true 在返回的文档中包含字段。

  • 0 或者 false 排除该字段。

  • 使用 Projection Operators 的表达式。

注解

对于 _id 字段,您不用显式指明 _id: 1 以返回 _id 字段。 db.collection.find() 方法返回 _id 字段,除非您指明 _id: 0 排除该字段。

一个 projection 不能 同时 指定包括和排除字段,除了排除 _id 字段。 在 显式包括 字段的映射中,_id 字段是唯一一个您可以 显式排除 的。

示例集合

本页面的示例在 mongo shell 中使用 db.collection.find() 。在 mongo shell 中,如果返回的游标没有赋值给 var 关键词的变量,该游标将会自动迭代最多20次 [1] 以打印出结果中的前20篇文档。

为了创建示例中提及的 users 集合,在 mongo shell 中运行下列命令:

注解

如果 users 集合已经包含了相同 _id 值的文档,您需要在插入示例文档之前 drop 集合 (db.users.drop()) 。

db.users.insertMany(
  [
     {
       _id: 1,
       name: "sue",
       age: 19,
       type: 1,
       status: "P",
       favorites: { artist: "Picasso", food: "pizza" },
       finished: [ 17, 3 ],
       badges: [ "blue", "black" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 85, bonus: 10 }
       ]
     },
     {
       _id: 2,
       name: "bob",
       age: 42,
       type: 1,
       status: "A",
       favorites: { artist: "Miro", food: "meringue" },
       finished: [ 11, 25 ],
       badges: [ "green" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 64, bonus: 12 }
       ]
     },
     {
       _id: 3,
       name: "ahn",
       age: 22,
       type: 2,
       status: "A",
       favorites: { artist: "Cassatt", food: "cake" },
       finished: [ 6 ],
       badges: [ "blue", "red" ],
       points: [
          { points: 81, bonus: 8 },
          { points: 55, bonus: 20 }
       ]
     },
     {
       _id: 4,
       name: "xi",
       age: 34,
       type: 2,
       status: "D",
       favorites: { artist: "Chagall", food: "chocolate" },
       finished: [ 5, 11 ],
       badges: [ "red", "black" ],
       points: [
          { points: 53, bonus: 15 },
          { points: 51, bonus: 15 }
       ]
     },
     {
       _id: 5,
       name: "xyz",
       age: 23,
       type: 2,
       status: "D",
       favorites: { artist: "Noguchi", food: "nougat" },
       finished: [ 14, 6 ],
       badges: [ "orange" ],
       points: [
          { points: 71, bonus: 20 }
       ]
     },
     {
       _id: 6,
       name: "abc",
       age: 43,
       type: 1,
       status: "A",
       favorites: { food: "pizza", artist: "Picasso" },
       finished: [ 18, 12 ],
       badges: [ "black", "blue" ],
       points: [
          { points: 78, bonus: 8 },
          { points: 57, bonus: 7 }
       ]
     }
  ]
)

返回匹配文档的所有字段

如果您没有指定映射, db.collection.find() 方法将会返回满足查询的所有文档的所有字段。

下面的案例从 users 集合中检索 status"A" 的所有文档。

db.users.find( { status: "A" } )

匹配文档包含所有字段:

{
   "_id" : 2,
   "name" : "bob",
   "age" : 42,
   "type" : 1,
   "status" : "A",
   "favorites" : { "artist" : "Miro", "food" : "meringue" },
   "finished" : [ 11, 25 ],
   "badges" : [ "green" ],
   "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ]
}
{
   "_id" : 3,
   "name" : "ahn",
   "age" : 22,
   "type" : 2,
   "status" : "A",
   "favorites" : { "artist" : "Cassatt", "food" : "cake" },
   "finished" : [ 6 ],
   "badges" : [ "blue", "red" ],
   "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ]
}
{
   "_id" : 6,
   "name" : "abc",
   "age" : 43,
   "type" : 1,
   "status" : "A",
   "favorites" : { "food" : "pizza", "artist" : "Picasso" },
   "finished" : [ 18, 12 ],
   "badges" : [ "black", "blue" ],
   "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ]
}

只返回指定的字段及 _id 字段

一个映射可以显式地包含几个字段,在下面的操作中, db.collection.find() 方法返回满足查询的所有文档。在结果集中,只返回了匹配文档的 namestatus 以及默认的 _id 字段。

db.users.find( { status: "A" }, { name: 1, status: 1 } )

上面的操作返回下列结果:

{ "_id" : 2, "name" : "bob", "status" : "A" }
{ "_id" : 3, "name" : "ahn", "status" : "A" }
{ "_id" : 6, "name" : "abc", "status" : "A" }

只返回指定的字段

您可以通过在映射中指定排除的字段删除结果中的 _id 字段,如下面的案例所示:

db.users.find( { status: "A" }, { name: 1, status: 1, _id: 0 } )

在结果集中, 返回匹配文档中的 namestatus 字段。

{ "name" : "bob", "status" : "A" }
{ "name" : "ahn", "status" : "A" }
{ "name" : "abc", "status" : "A" }

返回除了排除字段之外的所有字段

为了排除一个或多个字段,而不是列出在匹配文档中列出的字段,您可以像下列示例中一样,使用一个映射来排除特定的字段:

db.users.find( { status: "A" }, { favorites: 0, points: 0 } )

在结果集中, favoritespoints 字段不在匹配文档中返回。

{
   "_id" : 2,
   "name" : "bob",
   "age" : 42,
   "type" : 1,
   "status" : "A",
   "finished" : [ 11, 25 ],
   "badges" : [ "green" ]
}
{
   "_id" : 3,
   "name" : "ahn",
   "age" : 22,
   "type" : 2,
   "status" : "A",
   "finished" : [ 6 ],
   "badges" : [ "blue", "red" ]
}
{
   "_id" : 6,
   "name" : "abc",
   "age" : 43,
   "type" : 1,
   "status" : "A",
   "finished" : [ 18, 12 ],
   "badges" : [ "black", "blue" ]
}

除了 _id 字段,您不能在映射文档中组合 包含和排除 语句。

返回嵌入文档中的指定字段

使用 dot notation 返回嵌入文档中的特定字段

下面的示例指定了一个映射,返回 _id 字段、name 字段、 status 字段以及 favorites 文档中的 food 字段, food 仍然保持嵌入在 favorites 文档中。

db.users.find(
   { status: "A" },
   { name: 1, status: 1, "favorites.food": 1 }
)

上面的操作返回下列结果:

{ "_id" : 2, "name" : "bob", "status" : "A", "favorites" : { "food" : "meringue" } }
{ "_id" : 3, "name" : "ahn", "status" : "A", "favorites" : { "food" : "cake" } }
{ "_id" : 6, "name" : "abc", "status" : "A", "favorites" : { "food" : "pizza" } }

排除嵌入文档中的特定字段

Use dot notation to suppress specific fields of an embedded document using a 0 instead of 1.

下面的示例指明了排除 favorites 文档中 food 字段的映射。所有其他字段都会在匹配的文档中返回:

db.users.find(
   { status: "A" },
   { "favorites.food": 0 }
)

操作返回下列文档:

{
   "_id" : 2,
   "name" : "bob",
   "age" : 42,
   "type" : 1,
   "status" : "A",
   "favorites" : { "artist" : "Miro" },
   "finished" : [ 11, 25 ],
   "badges" : [ "green" ],
   "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ]
}
{
   "_id" : 3,
   "name" : "ahn",
   "age" : 22,
   "type" : 2,
   "status" : "A",
   "favorites" : { "artist" : "Cassatt" },
   "finished" : [ 6 ],
   "badges" : [ "blue", "red" ],
   "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ]
}
{
   "_id" : 6,
   "name" : "abc",
   "age" : 43,
   "type" : 1,
   "status" : "A",
   "favorites" : { "artist" : "Picasso" },
   "finished" : [ 18, 12 ],
   "badges" : [ "black", "blue" ],
   "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ]
}

映射数组中的嵌入文档

使用 dot notation 映射嵌入在数组中文档的特定字段。

下面的示例指明映射返回 name 字段、 status 字段,以及 points 数组的文档中包含 bonus 字段的文档。 默认返回 _id

db.users.find( { status: "A" }, { name: 1, status: 1, "points.bonus": 1 } )

上面的操作返回下列结果:

{ "_id" : 2, "name" : "bob", "status" : "A", "points" : [ { "bonus" : 20 }, { "bonus" : 12 } ] }
{ "_id" : 3, "name" : "ahn", "status" : "A", "points" : [ { "bonus" : 8 }, { "bonus" : 20 } ] }
{ "_id" : 6, "name" : "abc", "status" : "A", "points" : [ { "bonus" : 8 }, { "bonus" : 7 } ] }

映射返回数组中特定的数组元素

对于包含数组的字段,MongoDB提供了下面的映射操作符: $elemMatch, $slice, 以及 $

下面的示例使用 $slice 映射操作符来返回 scores 数组中最后的元素。

db.users.find( { status: "A" }, { name: 1, status: 1, points: { $slice: -1 } } )

上面的操作返回下列结果:

{ "_id" : 2, "name" : "bob", "status" : "A", "points" : [ { "points" : 64, "bonus" : 12 } ] }
{ "_id" : 3, "name" : "ahn", "status" : "A", "points" : [ { "points" : 55, "bonus" : 20 } ] }
{ "_id" : 6, "name" : "abc", "status" : "A", "points" : [ { "points" : 57, "bonus" : 7 } ] }

$elemMatch$slice ,以及 $ 是用来指定返回数组中包含映射元素的 唯一 方式。例如,您 不能 使用数组索引来指定映射的特定数组元素;例如 { "ratings.0": 1 } 映射 不会 映射到数组的第一个元素。

参见

查询文档

[1]

您可以使用 DBQuery.shellBatchSize 修改迭代的数目默认值 20 。 查看 使用``mongo`` Shell 了解更多信息。