MongoDB 内嵌文档数组查询
文章目录
- [MongoDB 内嵌文档数组查询](#MongoDB 内嵌文档数组查询)
-
- 查询数组内嵌文档
- 为文档数组中的字段指定查询条件
- 为文档数组指定多个条件
- [使用 MongoDB Atlas 查询文档数组](#使用 MongoDB Atlas 查询文档数组)
可以使用下面几种方法查询MongoDB中的嵌入文档:
- 编程语言的驱动程序,比如:Java、Python灯。
- MongoDB Atlas UI。
- MongoDB Compass。
- 其他第三方工具。
下面的示例使用mongosh的db.collection.find()方法对内嵌/嵌套文档进行查询,如果使用其他编程语言或驱动,写法会有不同。
首先,使用下面的语句创建inventory
数据集:
js
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 } ] }
]);
查询数组内嵌文档
下面的示例查询instock
数组中元素与指定文档匹配的文档:
js
db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )
整个内嵌文档的等价匹配要求与指定文档完全匹配,包括字段顺序。例如,下面的查询与集合中所有文档都不匹配:
js
db.inventory.find( { "instock": { qty: 5, warehouse: "A" } } )
为文档数组中的字段指定查询条件
指定文档数组内嵌文档字段的查询条件
如果不知道数组中内嵌文档的索引位置,可将数组字段名称与点(.)和内嵌文档中的字段名称连接起来。
下面的示例查询instock
数组中至少有一个内嵌文档包含qty
字段(其值小于或等于20
)的文档:
js
db.inventory.find( { 'instock.qty': { $lte: 20 } } )
使用数组索引查询内嵌文档的字段
可以使用点号表示法,指定文档中数组指定索引位置的字段的查询条件,数组的索引从零开始,使用点表示法查询时,字段和索引必须位于引号内。
js
db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )
为文档数组指定多个条件
对内嵌文档数组的多个字段指定条件时,可以指定单个、多个或全部文档满足条件。
单个内嵌文档满足内嵌字段的多个查询条件
使用$elemMatch
操作符可以在内嵌文档数组上指定多个条件,这样至少有一个内嵌文档满足条件。
下面的例子查询instock
数组中至少有一个内嵌文档同时包含qty
字段等于5
和warehouse
字段等于A
的文档:
js
db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )
下面的列子查询instock
数组中至少有一个内嵌文档包含qty
大于10
且小于或等于20
的文档:
js
db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )
符合标准的元素组合
如果数组字段上的复合查询条件不使用 $elemMatch 运算符,则查询将选择其数组包含满足条件的任意元素组合的文档。
例如,以下查询匹配 instock 数组中嵌套的任何文档的 qty 字段大于 10 且数组中的任何文档(但不一定是相同的嵌入文档)的 qty 字段小于或等于 20 的文档:
js
db.inventory.find( { "instock.qty": { $gt: 10, $lte: 20 } } )
以下示例查询 instock 数组中至少有一个包含等于 5 的字段 qty 的嵌入文档和至少一个包含等于 A 的字段仓库的嵌入文档(但不一定是相同的嵌入文档)的文档:
js
db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )