- MongoDB CRUD 操作 >
- MongoDB CRUD 教程 >
- 查询文档
查询文档¶
在MongoDB中,使用 db.collection.find() 方法从集合中检索文档,[1] db.collection.find() 方法将返回一个检索文档的 游标 。
本向指南提供了一系列在 mongo shell中使用 db.collection.find() 方法的读操作示例。在这些示例中,被检索的文档包含了所有字段。若要限制被检索文档的返回字段,请参考 限制查询返回的字段
[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. |
选取集合中的所有文档¶
使用空查询文档 ({}) 选取集合中的所有文档:
db.inventory.find( {} )
如果不为方法 find() 指定查询文档,等同于为其指定一个空查询文档。因此如下的操作和上面的操作等效。
db.inventory.find()
指定等于查询条件¶
要指定相等查询条件,使用查询文档 { <field>: <value> } 查询所有包含 <field> 字段并且值等于 <value> 的集合。
下面的示例从 inventory 集合中检索所有字段 type 值为的文档 snacks:
db.inventory.find( { type: "snacks" } )
使用查询操作符指定查询条件¶
在MongoDB查询中,查询文档可使用 query operators 指定查询条件。
下面的示例筛选 inventory 集合中 type 字段值为 'food' 或 'snacks' 的所有文档:
db.inventory.find( { type: { $in: [ 'food', 'snacks' ] } } )
虽然你也可以使用 $or 操作符实现这个查询,但在同字段上使用相等条件查询时更宁愿使用 $in 查询操作符。
完整查询操作符列表请参看 Operators 文档。
指定 与 查询条件¶
复合查询可指定文档中多个字段作为查询条件。使用 AND 逻辑连接复合查询的条件子句,以筛选出集合中所有符合查询条件的文档。
在下面示例中,查询文档分别在字段 type 和 price 上指定了等于与小于 ($lt) 条件:
db.inventory.find( { type: 'food', price: { $lt: 9.95 } } )
查询选取所有 type 字段等于 'food' 并且 price 字段值小于 9.95 的文档。其他比较操作符请参看 comparison operators 。
指定 或 查询条件¶
使用 $or 操作符,可通过 OR 逻辑连接每个子句以指定一个复合查询,查询将筛选集合中至少匹配一个查询条件的文档。
下面示例中,查询文档筛选出集合中 qty 字段值大于 ($gt) 100 或 price 字段小于 ($lt) 9.95 的所有文档:
db.inventory.find(
{
$or: [ { qty: { $gt: 100 } }, { price: { $lt: 9.95 } } ]
}
)
同时指定 与 和 或 查询条件¶
使用更多条件子句,你可以更精确的指定文档匹配条件。
在下面示例中,复合查询文档筛选出集合中 type 字段值为 'food' 并且 qty 字段的值大于 ($gt) 100 或 price 的值小于 ($lt) ``9.95``的所有文档:
db.inventory.find(
{
type: 'food',
$or: [ { qty: { $gt: 100 } }, { price: { $lt: 9.95 } } ]
}
)
内嵌文档¶
当字段包含内嵌文档,查询可为整个内嵌文档指定精确匹配条件,同时也可使用 :term:`dot notation`对内嵌文档中的某个单独字段指定匹配条件。
内嵌文档的精确匹配¶
要在整个内嵌文档上指定相等匹配条件,使用查询文档 { <field>: <value> },其中 <value> 是用于匹配的文档。相等匹配要求 <value> 文档与内嵌文档 完全 匹配,包括字段顺序。
在如下示例中,查询将匹配 producer 字段为内嵌文档,并 仅 包含 company 和 address 字段(字段顺序相同),且值分别为 'ABC123' 与 '123 Street' 的所有文档:
db.inventory.find(
{
producer:
{
company: 'ABC123',
address: '123 Street'
}
}
)
内嵌文档中的字段相等匹配¶
使用 dot notation 匹配内嵌文档中的特定的字段。内嵌文档中特定字段的相等匹配将筛选出集合中内嵌文档包含该指定字段并等于指定的值的文档。内嵌文档可以包含其他的字段。
下面示例中,查询使用 dot notation 匹配 producer 字段为内嵌文档,该内嵌文档中包含 company 字段(可包含其他字段)且值为 'ABC123' 的所有文档:
db.inventory.find( { 'producer.company': 'ABC123' } )
数组¶
当字段包含数组,你可查询精确的匹配数组或数组中特定的值。如果数组包含嵌入文档,你可以使用 dot notation 查询内嵌文档中特定的字段。
如果你使用 $elemMatch 操作符指定多个查询条件,数组必须包含至少一个元素满足所有条件。参见 单元素满足条件。
如果你不使用 $elemMatch 操作符指定多查询条件,
考虑集合 inventory 包含如下文档:
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] }
数组精确匹配¶
要指定数组相等匹配,使用查询文档 { <field>: <value> } 其中 <value> 是匹配的数组。数组的相等匹配要求数组字段与指定的匹配数组 <value> 完全 相符,包括数组元素的顺序。
下面示例将筛选出 ratings 字段为数组,包含 5, 8, 9 三个元素并且元素顺序符合该顺序的所有文档:
db.inventory.find( { ratings: [ 5, 8, 9 ] } )
此操作将返回如下文档:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
匹配数组元素¶
相等匹配可以指定数组中单一元素进行匹配。这些相等匹配将匹配包含至少一个元素等于指定值的数组。
下面示例查询数组字段 ratings 中元素之一为 5 的所有文档。
db.inventory.find( { ratings: 5 } )
操作将返回如下文档:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
{ "_id" : 7, "type" : "food", "item" : "ccc", "ratings" : [ 9, 5, 8 ] }
匹配数组中特定元素¶
使用 dot notation 可以在数组特定的索引或位置指定相等匹配的元素。
在下面示例中,查询使用 dot notation 匹配数组字段 ratings 的第一个元素为 5 的所有文档:
db.inventory.find( { 'ratings.0': 5 } )
操作将返回如下文档:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
为数组元素指定复合条件¶
单元素满足条件¶
使用 $elemMatch 操作符为数组元素指定复合条件,以查询数组中至少一个元素满足所有指定条件的文档。
下面示例查询 ratings 数组中至少一个元素大于 ($gt) 5 且小于 ($lt) 9 的文档:
db.inventory.find( { ratings: { $elemMatch: { $gt: 5, $lt: 9 } } } )
操作返回如下文档,这些文档的 ratings 中包含元素 8,满足条件:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 7, "type" : "food", "item" : "ccc", "ratings" : [ 9, 5, 8 ] }
满足条件的元素组合¶
下面示例将查询 ratings 中包含某些元素组合满足查询条件的文档;比如,一个元素满足大于 5 的条件,另外元素满足小于 9 的条件,或一个元素同时满足两个条件;
db.inventory.find( { ratings: { $gt: 5, $lt: 9 } } )
操作将返回如下文档:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
{ "_id" : 7, "type" : "food", "item" : "ccc", "ratings" : [ 9, 5, 8 ] }
The document with the "ratings" : [ 5, 9 ] matches the query since the element 9 is greater than 5 (the first condition) and the element 5 is less than 9 (the second condition).
内嵌文档数组¶
考虑 inventory 集合包含如下文档:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
{
_id: 101,
type: "fruit",
item: "jkl",
qty: 10,
price: 4.25,
ratings: [ 5, 9 ],
memos: [ { memo: "on time", by: "payment" }, { memo: "delayed", by: "shipping" } ]
}
使用数组索引匹配内嵌文档的字段¶
如果你知道内嵌文档所在数组的索引,就可以指定使用 dot notation 通过子文档的位置指定文档。
下面示例筛选了 memos 字段包含数组且该数组第一个元素(即索引为 0)是一个文档,并且该文档包含字段 by``且值为 ``'shipping' 的所有文档:
db.inventory.find( { 'memos.0.by': 'shipping' } )
此操作将返回如下文档:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
不使用指定数组索引匹配字段¶
如果你并不知道文档在数组中的索引位置,使用逗号 (.) 连接包含数组的字段名与子文档中的字段名。
下面示例筛选出 memos 字段包含数组且该数组包含至少一个内嵌文档,并且内嵌文档包含字段 by 且值为 'shipping' 的所有文档:
db.inventory.find( { 'memos.by': 'shipping' } )
操作将返回如下文档:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
{
_id: 101,
type: "fruit",
item: "jkl",
qty: 10,
price: 4.25,
ratings: [ 5, 9 ],
memos: [ { memo: "on time", by: "payment" }, { memo: "delayed", by: "shipping" } ]
}
给文档数组指定复合条件¶
单元素满足条件¶
使用 $elemMatch 操作符为内嵌文档数组指定复合条件,以查询数组中只是一个内嵌文档满足所有指定添加的文档。
下面示例查询 memos 数组中至少有一个内嵌文档同时包含 memo 和 by 字段并且值分别为 'on time' 与 'shipping' 的所有文档:
db.inventory.find(
{
memos:
{
$elemMatch:
{
memo: 'on time',
by: 'shipping'
}
}
}
)
此操作将返回如下文档:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
满足条件的元素组合¶
下面示例查询 memos 数组中包含某些元素组合满足查询条件的文档:例如,其中一个元素满足字段 memo 值等于 'on time' 条件,另外一个元素满足字段 by 值等于 'shipping' ,或一个元素同时满足两个条件:
db.inventory.find(
{
'memos.memo': 'on time',
'memos.by': 'shipping'
}
)
查询返回如下文档:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
{
_id: 101,
type: "fruit",
item: "jkl",
qty: 10,
price: 4.25,
ratings: [ 5, 9 ],
memos: [ { memo: "on time", by: "payment" }, { memo: "delayed", by: "shipping" } ]
}