翻译或纠错本页面

查询文档

查询方法

MongoDB 提供了 db.collection.find() 方法从集合中读取文档。db.collection.find() 方法返回指向匹配文档的:doc:cursor </tutorial/iterate-a-cursor>

db.collection.find( <query filter>, <projection> )

对于 cursor 方法,你可以指定下列可选字段:

  • 一个 query filter 指明返回哪些文档。

  • 一个查询映射来指明返回匹配文档的哪些字段。映射限制了MongoDB通过网络返回给客户端的数据量。

你可以随意增加一个游标修饰符来进行限制、跳过以及排序。除非你声明一个方法 sort() ,否则不会定义查询返回的文档顺序。

示例集合

本页的示例在 mongo shell 中使用了 db.collection.find() 方法。在 mongo shell中,如果返回的游标没有使用 var 关键词赋值给一个变量,游标就会自动迭代20次 [2] ,打印出结果中的前20篇文档。

为填充示例中提到的 user 集合,在 mongo shell 中运行下列命令:

注解

如果 user 集合已经包含了相同 _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 }
       ]
     }
  ]
)

选择集合中的所有文档

一个空的 query filter 文档({}) 选择集合中的所有文档:

db.users.find( {} )

省略 db.collection.find() 中的查询过滤文档等价于指定一个空的查询文档。因此,下面的操作等价于之前的操作:

db.users.find()

指定查询过滤条件

指定等于条件

一个 query filter document 可以使用 <field>:<value> 表达式指定等于条件以选择所有包含 <field> 字段并且等于特定 <value> 的所有文档:

{ <field1>: <value1>, ... }

下面的示例从 user 集合中检索 status 字段值为 "A" 的所有文档:

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

使用查询操作符指定条件

A query filter document can use the query operators to specify conditions in the following form:

{ <field1>: { <operator1>: <value1> }, ... }

下面的示例从 user 集合中检索 status 字段值为 "P" 或者 "D" 的所有文档:

db.users.find( { status: { $in: [ "P", "D" ] } } )

尽管你也可以使用 $or 操作符表示这个查询,但是在相同字段执行等于检查时,建议使用 $in 而不是 $or

查阅 Query and Projection Operators 文档了解查询操作符的完整列表。

指定 AND 条件

复合查询可以在集合文档的多个字段上指定条件。隐含地,一个逻辑的 AND 连接词会连接复合查询的子句,使得查询选出集合中匹配所有条件的文档。

下面的示例在 users 集合中检索 status 等于 "A"``**并且** ``age 小于 ($lt) 30 是所有文档:

db.users.find( { status: "A", age: { $lt: 30 } } )

查阅 comparison operators 了解其它比较操作符。

指定 OR 条件

通过使用 $or 操作符,你可以指定一个使用逻辑 OR 连接词连接各子句的复合查询选择集合中匹配至少一个条件的文档。

下面的示例在 users 集合中检索 status 等于 "A"``**或者** ``age 小于 ($lt) 30 是所有文档:

db.users.find(
   {
     $or: [ { status: "A" }, { age: { $lt: 30 } } ]
   }
)

注解

使用 comparison operators 的查询服从 Type Bracketing

指定 ANDOR 条件

通过使用附加的子句,你可以指定匹配文档的精确条件。

“在下面的示例中,复合查询文档选择集合中`status`` 等于 "A" 并且 要么 age 小于 ($lt) 30 要么 type 等于 1 的所有文档:

db.users.find(
   {
     status: "A",
     $or: [ { age: { $lt: 30 } }, { type: 1 } ]
   }
)

嵌入文档上的查询

当字段中包含嵌入文档时,查询可以指定嵌入文档中的精确匹配或者使用 “dot notation 对嵌入文档中的单个字段指定匹配。

嵌入文档上的精确匹配

使用``{ <field>: <value> }``并且 “<value>” 为要匹配文档的查询文档,来指定匹配整个内嵌文档的完全相等条件.(要使)相等条件匹配上内嵌文档需要指定 <value> 包括字段顺序的 精确 匹配。

在下面的例子中,查询匹配所有 favorites 字段是以该种顺序只包含 等于 "Picasso"``的 ``artist 和等于 "pizza"food 字段的内嵌文档:

db.users.find( { favorites: { artist: "Picasso", food: "pizza" } } )

嵌入文档中字段上的等于匹配

使用 dot notation 匹配内嵌文档中的特定的字段。内嵌文档中特定字段的相等匹配将筛选出集合中内嵌文档包含该指定字段并等于指定的值的文档。内嵌文档可以包含其他的字段。

在下面的例子中,查询使用 dot notation 匹配所有 favorites 字段是包含等于 "Picasso" 的字段 ``artist``(可能还包含其他字段) 的内嵌文档:

db.users.find( { "favorites.artist": "Picasso" } )

数组上的查询

当字段包含数组,你可查询精确的匹配数组或数组中特定的值。如果数组包含嵌入文档,你可以使用 dot notation 查询内嵌文档中特定的字段。

如果你使用 $elemMatch 操作符指定多个查询条件,数组必须包含至少一个元素满足所有条件。参见 单个元素满足查询条件

如果指定多个查询条件时没有使用 $elemMatch 操作符,那么数组元素的组合(不一定是单一元素)必须满足所有条件;例如,数组中的不同元素可以满足条件的不同部门。查阅 元素组合满足查询条件 了解更多信息。

数组上的精确匹配

要指定数组相等匹配,使用查询文档 { <field>: <value> } 其中 <value> 是匹配的数组。数组的相等匹配要求数组字段与指定的匹配数组 <value> 完全 相符,包括数组元素的顺序。

下面的例子查询所有字段 badges 是一个正好有两个元素: "blue""black" (以这种顺序)的数组的文档:

db.users.find( { badges: [ "blue", "black" ] } )

查询匹配下面的文档:

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

匹配一个数组元素

等于匹配可以指定匹配数组中的单一元素。如果数组中至少 一个 元素包含特定的值,就可以匹配这些声明。

下面的示例查询 badges 是一个数组字段并且包含 ``“black”``作为其数组元素的所有文档。

db.users.find( { badges: "black" } )

查询匹配下列文档:

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

匹配数组中的指定元素

等于匹配可以指定匹配数组某一特定所有或位置的元素,使用 dot notation

在下面的例子中,查询使用 the dot notation 匹配所有 dadges 数组的第一个元素为``”black”`` 的文档:

db.users.find( { "badges.0": "black" } )

该操作返回下列文档:

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

指定数组元素的多个查询条件

单个元素满足查询条件

使用 $elemMatch 操作符为数组元素指定复合条件,以查询数组中至少一个元素满足所有指定条件的文档。

下面的例子查询 finished 数组至少包含一个大于 ($gt) 15 并且小于 ($lt) 20 的元素的文档:

db.users.find( { finished: { $elemMatch: { $gt: 15, $lt: 20 } } } )

操作返回下列文档,文档的 finished 数组包含至少一个满足查询条件的元素。

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

元素组合满足查询条件

下面的例子查询 finished 数组包含以某种组合满足查询条件的元素的文档;例如,一个元素满足大于 15 的条件并且有另一个元素满足小于 20 的条件,或者有一个元素满足了这两个条件:

db.users.find( { finished: { $gt: 15, $lt: 20 } } )

操作返回下面的文档:

{
   "_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, 20 ],
   "badges" : [ "green" ],
   "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ]
}
{
   "_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 } ]
}

嵌入文档数组

使用数组索引匹配嵌入文档中的字段

在下面的例子中,查询使用 the dot notation 匹配所有 dadges 是第一个元素为``”black”`` 的数组的文档:

如果你知道内嵌文档的数组索引,你可以使用 dot notation 及内嵌文档的位置指定文档。

db.users.find( { 'points.0.points': { $lte: 55 } } )

操作返回下面的文档:

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

不指定数组索引匹配字段

如果你不知道文档在数组中的索引位置,用点号 (.) 将包含数组的字段的名字和内嵌文档的字段的名字连起来。

下面的例子选择出所有 points``数组中至少有一个嵌入文档包含值小于或等于 ``55 的字段 points 的文档:

db.users.find( { 'points.points': { $lte: 55 } } )

操作返回下面的文档:

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

指定数组文档的多个查询条件

单个元素满足查询条件

使用 $elemMatch 操作符为数组元素指定复合条件,以查询数组中至少一个元素满足所有指定条件的文档。

下面的例子查询 points 数组有至少一个包含 points 小于等于 70 并且字段 bonus 等于 20 的内嵌文档的文档:

db.users.find( { points: { $elemMatch: { points: { $lte: 70 }, bonus: 20 } } } )

该操作返回下列文档:

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

元素组合满足查询条件

下面的例子查询了 points 数组包含了以某种组合满足查询条件的元素的文档;例如,一个元素满足 points 小于等于 70 的条件并且有另一个元素满足 bonus 等于 20 的条件,或者一个元素同时满足两个条件:

db.users.find( { "points.points": { $lte: 70 }, "points.bonus": 20 } )

查询返回下列文档:

{
   "_id" : 2,
   "name" : "bob",
   "age" : 42,
   "type" : 1,
   "status" : "A",
   "favorites" : { "artist" : "Miro", "food" : "meringue" },
   "finished" : [ 11, 20 ],
   "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 } ]
}

其他方法

下面的方法也可以从集合中读取文档:

[1]The db.collection.findOne() method also performs a read operation to return a single document. Internally, the db.collection.findOne() method is the db.collection.find() method with a limit of 1.

读隔离

3.2 新版功能.

对于 replica sets 和复制集 shards 的读取,安全读级别允许客户端选择他们读取的隔离等级.

更多信息,参见 Read Concern.

[2]

你可以使用 DBQuery.shellBatchSize 修改默认的迭代次数(20)。查阅 ref:mongo-shell-executing-queries 了解更多信息。