You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB嵌入式文档查询:基于官方数组文档示例的技术问询

嘿,针对你提到的inventory集合里的嵌入式文档数组查询,我整理了几种常用的方法,直接用你插入的测试数据来举例说明,每种场景都配了具体的查询命令和效果解释:

1. 精确匹配整个嵌入式文档

如果你要找数组中完全包含某个特定子文档的文档(子文档的字段顺序、内容必须完全一致),可以直接用子文档作为查询条件:

db.inventory.find( { instock: { warehouse: "C", qty: 5 } } )

这个查询会返回item: "notebook"的文档,因为它的instock数组里正好有一个和查询条件完全匹配的子文档。

2. 匹配嵌入式文档的单个字段

如果只需要匹配子文档中的某一个字段,用点符号访问嵌套字段即可:

db.inventory.find( { "instock.warehouse": "A" } )

这个查询会返回所有在仓库"A"有库存的商品,也就是journal、paper、planner这三个文档。

3. 匹配同一嵌入式文档的多个字段(逻辑与)

这里要区分两种情况:

  • 情况一:数组中任意子文档分别满足不同条件(比如一个子文档满足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的条件。

4. 匹配数组中至少一个子文档的范围条件

如果要找数组中存在至少一个子文档满足范围条件(比如数量大于10),直接用点符号加范围操作符:

db.inventory.find( { "instock.qty": { $gt: 10 } } )

这个查询会返回journal(有qty=15)、paper(有qty=60和15)、planner(有qty=40)这三个文档,notebook的qty=5不满足,所以不会被返回。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:51:09