Query Documents
此页提供了使用 mongo shell 中的 db.collection.find() 方法进行查询操作的示例。
此页上的示例使用库存集合。若要填充清单集合, 请运行以下命令:
db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
查询所有
db.inventory.find( {} )
指定相等的条件
下面的示例从库存集合中选择状态等于 “d” 的所有文档:
db.inventory.find( { status: "D" } )
指定查询条件
查询筛选器文档可以使用查询运算符以以下形式指定条件:
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
注意
尽管可以使用 $or 运算符来表示此查询, 但在对同一字段执行相等性检查时, 请使用 $in
运算符, 而不是 $or 运算符。
指定 & 条件
复合查询可以为集合文档中的多个字段指定条件。
隐式地, 逻辑 and 连词连接复合查询的子句, 以便查询选择集合中与所有条件匹配的文档。
下面的示例检索清单集合中状态等于 “a” 且 qty 小于 ($lt) 30 的所有文档:
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
指定 or 条件
使用 $or 运算符, 可以指定一个复合查询, 该查询用逻辑或连词连接每个子句, 以便查询选择集合中至少匹配一个条件的文档。
下面的示例检索集合中状态等于 “a” 或 qty 小于 ($lt) 30 的所有文档:
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
使用 and/or
在下面的示例中, 复合查询文档选择集合中状态等于 “a” 且数量小于 ($lt) 30 或项目以字符 p 开头的集合中的所有文档:
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )
行为
光标
db.collection.find()
方法将光标返回到匹配的文档。
阅读隔离
3.2 版中的新版本。
对于对副本集和副本集分片的读取, 读取关注允许客户端为其读取选择隔离级别。
有关详细信息, 请参阅阅读关注。
查询嵌套结果
数据初始化
db.inventory.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
匹配嵌入的/嵌套文档
若要在嵌入/嵌套文档的字段上指定相等条件, 请使用查询筛选器文档 {<field>: <value>}
, 其中 <value>
是要匹配的文档。
例如, 下面的查询选择字段大小等于文档 {h:14, w:21, uom: "cm"}
的所有文档:
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )
- 查询结果
{ "_id" : ObjectId("5c1644baf29beabd5b32d1ac"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }
嵌套字段的查询
若要在嵌入嵌套文档中的字段上指定查询条件, 请使用点符号 ("field.nestedfield")
。
注意
使用点表示法查询时, 字段和嵌套字段必须在引号内。
db.inventory.find( { "size.uom": "in" } )
使用查询运算符指定匹配
查询筛选器文档可以使用查询运算符以以下形式指定条件:
db.inventory.find( { "size.h": { $lt: 15 } } )
使用 AND
下面的查询选择嵌套字段 h 小于15、嵌套字段 uom 等于 “in” 和状态字段等于 “d” 的所有文档:
db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )
查询一个数组
数据初始化
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
匹配一个数组
若要指定数组上的相等条件, 请使用查询文档 {<field>: <value>}
, 其中 <value>
是要匹配的确切数组, 包括元素的顺序。
下面的示例按指定的顺序查询字段标记值是一个具有 “红色” 和 “空白” 这两个元素的数组的所有文档:
db.inventory.find( { tags: ["red", "blank"] } )
- 结果
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b2"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
相反, 如果您希望找到一个同时包含元素 “红色” 和 “空白” 的数组, 而不考虑数组中的顺序或其他元素, 请使用 $all
运算符:
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
- 结果
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b1"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b2"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b3"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b4"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }
查询元素的数组
若要查询数组字段是否至少包含一个具有指定值的元素, 请使用筛选器 {<field>: <value>}
, 其中 <value>
是元素值。
下面的示例查询标记是包含字符串 “红色” 作为其元素之一的数组的所有文档:
db.inventory.find( { tags: "red" } )
例如, 对于数组 dim_cm 包含至少一个值大于25的元素的所有文档, 下面的操作将查询。
db.inventory.find( { dim_cm: { $gt: 25 } } )
指定数组元素的多个条件
在数组元素上指定复合条件时, 可以指定查询, 使单个数组元素满足这些条件或数组元素的任意组合满足条件。
在数组元素上查询具有复合筛选条件的阵列
下面的示例查询的文档, 其中 dim_cm 数组包含在某些组合中满足查询条件的元素;
例如, 一个元素可以满足大于15个条件, 另一个元素可以满足小于20个条件, 或者一个元素可以满足这两个条件:
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
- 查询结果
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b1"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b2"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b3"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b5"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }
查询满足多个条件的数组元素
使用 $elemMatch 运算符在数组的元素上指定多个条件, 以便至少有一个数组元素满足所有指定的条件。
下面的示例查询的文档中, dim_cm 数组至少包含一个元素, 该元素既大于 ($gt) 22, 又小于 ($lt) 30:
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )
- 结果
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b4"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }
按数组索引位置查询元素
使用点表示法, 可以在数组的特定索引或位置为元素指定查询条件。
数组使用从零开始的索引。
注意
使用点表示法查询时, 字段和嵌套字段必须在引号内。
下面的示例查询数组 dim_cm 中第二个元素大于25的所有文档:
db.inventory.find( { "dim_cm.1": { $gt: 25 } } )
- 结果
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b4"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }
按数组长度查询数组
使用 $size
运算符按元素数查询数组。
例如, 下面选择数组标记具有3个元素的文档。
db.inventory.find( { "tags": { $size: 3 } } )
- 结果
{ "_id" : ObjectId("5c1645edf29beabd5b32d1b3"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
查询数组中的嵌套元素
初始化
db.inventory.insertMany( [
{ item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
{ item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
{ item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
{ item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
顺序指定查询
- 脚本
db.inventory.find({"instock": {warehouse: "A", qty: 5} });
- 结果
{ "_id" : ObjectId("5c164864f29beabd5b32d1b6"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
注意:上面的查询和属性字段的顺序也是有关联的。
比如下面的查询则没有匹配结果。
db.inventory.find( { "instock": { qty: 5, warehouse: "A" } } )
指定查询条件
在文档数组中嵌入的字段上指定查询条件
如果不知道嵌套在数组中的文档的索引位置, 请在嵌套文档中使用点 (.
) 和字段的名称连接数组字段的名称。
下面的示例选择任何文档, 其中 instock 数组至少有一个嵌入文档, 其中包含值小于或等于20的字段 qty:
db.inventory.find( { 'instock.qty': { $lte: 20 } } )
指定数组下标
使用点表示法, 可以在数组的特定索引或位置为文档中的字段指定查询条件。数组使用从零开始的索引。
注意
使用点表示法查询时, 字段和索引必须在引号内。
下面的示例选择所有文档, 其中 instock 数组的第一个元素是包含字段 qty 的文档, 其值小于或等于 20:
db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )
指定文档数组的多个条件
在文档数组中嵌套的多个字段上指定条件时, 可以指定查询, 使单个文档满足这些条件, 或者数组中的任何文档组合 (包括单个文档) 满足条件。
单个嵌套文档满足嵌套字段上的多个查询条件
使用 $elemMatch
运算符在嵌入文档数组上指定多个条件, 以便至少有一个嵌入文档满足所有指定的条件。
下面的示例查询的文档, 如果 instock 数组至少有一个嵌入文档, 其中包含既包含等于5的字段 qty, 也包含等于 A 的字段仓库:
db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )
- 结果
{ "_id" : ObjectId("5c164864f29beabd5b32d1b6"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
下面的示例查询的文档, 如果 instock 数组至少有一个嵌入文档, 其中包含大于10且小于或等于20的字段 qty:
db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )
- 结果
{ "_id" : ObjectId("5c164864f29beabd5b32d1b6"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("5c164864f29beabd5b32d1b8"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("5c164864f29beabd5b32d1ba"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }
满足标准的元素组合
如果数组字段上的复合查询条件不使用 $elemMatch 运算符, 则查询将选择数组包含满足条件的任何元素组合的文档。
例如, 下面的查询匹配嵌套在 instock 数组中的任何文档的 qty 字段大于 10, 而数组中的任何文档 (但不一定是相同的嵌入文档) 的 qty 字段小于或等于20的文档:
db.inventory.find( { "instock.qty": { $gt: 10, $lte: 20 } } )
- 结果
{ "_id" : ObjectId("5c164864f29beabd5b32d1b6"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("5c164864f29beabd5b32d1b8"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("5c164864f29beabd5b32d1b9"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }
{ "_id" : ObjectId("5c164864f29beabd5b32d1ba"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }
下面的示例查询的文档, 其中 instock 数组至少有一个嵌入文档, 其中包含字段 qty 等于5和至少一个嵌入文档 (但不一定是相同的嵌入文档), 其中包含等于字段仓库的字段仓库答:
db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )
- 结果
{ "_id" : ObjectId("5c164864f29beabd5b32d1b6"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("5c164864f29beabd5b32d1b9"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }
指定查询返回的字段
默认情况下, mongodb 中的查询返回匹配文档中的所有字段。
若要限制 mongodb 发送到应用程序的数据量, 可以包括投影文档, 以指定或限制要返回的字段。
数据初始化
db.inventory.insertMany( [
{ item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] },
{ item: "notebook", status: "A", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] },
{ item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] },
{ item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
返回指定的字段和 _id 字段
至于为什么 item: 1
这种写法,个人感觉是为了符合 json 的格式,感觉为了符合 json 的格式对简洁性做了牺牲。
db.inventory.find({status: "A"}, {item: 1, status: 1})
等同于
SELECT _id, item, status from inventory WHERE status = "A"
返回指定的字段,排除 _id 字段
db.inventory.find({status: "A"}, {item: 1, status: 1, _id: 0})
等同于
SELECT item, status from inventory WHERE status = "A"
返回所有字段,除了排除的字段
db.inventory.find({status: "A"}, {item: 0, status: 0})
注意
除了 _id 字段之外, 不能在投影文档中合并包含语句和排除语句。
返回指定字段的嵌套字段
您可以返回嵌入文档中的特定字段。使用点符号引用嵌入的字段, 并在投影文档中设置为1。
下面的示例返回:
-
_id 字段 (默认返回),
-
项目字段,
-
状态字段,
-
大小文档中的 uom 字段。
-
uom 字段仍嵌入到大小文档中。
db.inventory.find(
{ status: "A" },
{ item: 1, status: 1, "size.uom": 1 }
)
禁止嵌入文档中的特定字段
您可以禁止显示嵌入文档中的特定字段。
使用点符号引用投影文档中的嵌入字段, 并将其设置为0。
下面的示例指定一个 projection, 以排除大小文档中的 uom 字段。所有其他字段都将在匹配的文档中返回:
db.inventory.find(
{ status: "A" },
{ "size.uom": 0 }
)
阵列中嵌入文档的投影
使用点表示法在嵌入到数组中的文档中投影特定字段。
下面的示例指定要返回的投影:
-
_id 字段 (默认返回),
-
项目字段,
-
状态字段,
-
嵌入在存储数组中的文档中的 qty 字段。
db.inventory.find( { status: "A" }, { item: 1, status: 1, "instock.qty": 1 } )
返回数组中的项目特定数组元素
对于包含数组的字段, mongodb 提供了以下用于操作数组的投影运算符: $elemMatch、$slice 和 $。
下面的示例使用 $slice 投影运算符返回存储数组中的最后一个元素:
db.inventory.find( { status: "A" }, { item: 1, status: 1, instock: { $slice: -1 } } )
$elemMatch、$slice 和 $ 是预测要包含在返回数组中的特定元素的唯一方法。
例如, 不能使用数组索引投影特定的数组元素;投影不会使用第一个元素投影数组。
查询 NULL 或者不存在的字段
mongodb 中的不同查询运算符以不同的方式处理空值。
初始化
db.inventory.insertMany([
{ _id: 1, item: null },
{ _id: 2 }
])
相等过滤
{item: null}
查询匹配包含其值为 null 或不包含项字段的项字段的文档。
db.inventory.find( { item: null } )
- 结果
{ "_id" : 1, "item" : null }
{ "_id" : 2 }
类型检查
{item: {$type:10} 查询仅与包含其值为 null 的项字段的文档匹配;
即项字段的值为 bson 类型 null (类型 10):
db.inventory.find( { item : { $type: 10 } } )
- 结果
{ "_id" : 1, "item" : null }
存在检查
{item: {$exists: false} 查询与不包含项字段的文档匹配:
db.inventory.find( { item : { $exists: false } } )
- 结果
{ "_id" : 2 }