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 }
参考资料
目录
版权声明
本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。


