MongoDB嵌入式文档查询:基于官方数组文档示例的技术问询
嘿,针对你提到的inventory集合里的嵌入式文档数组查询,我整理了几种常用的方法,直接用你插入的测试数据来举例说明,每种场景都配了具体的查询命令和效果解释:
如果你要找数组中完全包含某个特定子文档的文档(子文档的字段顺序、内容必须完全一致),可以直接用子文档作为查询条件:
db.inventory.find( { instock: { warehouse: "C", qty: 5 } } )
这个查询会返回item: "notebook"的文档,因为它的instock数组里正好有一个和查询条件完全匹配的子文档。
如果只需要匹配子文档中的某一个字段,用点符号访问嵌套字段即可:
db.inventory.find( { "instock.warehouse": "A" } )
这个查询会返回所有在仓库"A"有库存的商品,也就是journal、paper、planner这三个文档。
这里要区分两种情况:
情况一:数组中任意子文档分别满足不同条件(比如一个子文档满足warehouse=A,另一个满足qty<20)
db.inventory.find( { "instock.warehouse": "A", "instock.qty": { $lt: 20 } } )这个查询会返回
journal(有warehouse=A且qty=5<20)、paper(有warehouse=A且另一个子文档qty=15<20)、planner(有warehouse=A且另一个子文档qty=5<20)。情况二:同一个子文档同时满足多个条件
这种情况必须用$elemMatch操作符,确保是同一个子文档符合所有条件:db.inventory.find( { instock: { $elemMatch: { warehouse: "A", qty: { $lt: 20 } } } } )这个查询只会返回
journal,因为只有它的instock数组里存在一个同时满足warehouse="A"和qty<20的子文档(qty=5),而paper和planner中warehouse=A的子文档qty分别是60和40,都不满足<20的条件。
如果要找数组中存在至少一个子文档满足范围条件(比如数量大于10),直接用点符号加范围操作符:
db.inventory.find( { "instock.qty": { $gt: 10 } } )
这个查询会返回journal(有qty=15)、paper(有qty=60和15)、planner(有qty=40)这三个文档,notebook的qty=5不满足,所以不会被返回。
如果要找数组里每一个子文档都符合某个条件(比如所有库存数量都大于5),可以用$not结合$elemMatch来排除不符合的文档:
db.inventory.find( { $not: { instock: { $elemMatch: { qty: { $lte: 5 } } } } } )
这个查询会返回paper,因为它的两个子文档qty分别是60和15,都大于5;而journal、notebook、planner都存在qty<=5的子文档,会被排除。
或者用更直观的$expr表达式来实现:
db.inventory.find( { $expr: { $allElementsTrue: { $map: { input: "$instock", as: "stockItem", in: { $gt: [ "$$stockItem.qty", 5 ] } } } } } )
这个命令会遍历每个文档的instock数组,检查每一个子文档的qty是否都大于5,返回符合要求的文档。
内容的提问来源于stack exchange,提问作者Nelson La Rocca

