MongoDB中无外层键时查询嵌套对象的方法
MongoDB动态外层键下的嵌套查询解决方案
针对你遇到的这种不知道动态外层键的查询需求,有两种实用的解决方案,均基于MongoDB的$objectToArray操作符(需MongoDB 3.4及以上版本支持):
方法一:直接使用find配合$expr查询
通过将顶层文档转换为键值对数组,遍历检查每个非_id字段的嵌套内容:
db.collection.find({ $expr: { $anyElementTrue: { $map: { input: { $objectToArray: "$$ROOT" }, as: "item", in: { $and: [ { $ne: ["$$item.k", "_id"] }, // 排除默认的_id字段 { $eq: ["$$item.v.details.hardware.id", 5] } // 检查嵌套的硬件id ] } } } } })
原理:
$objectToArray: "$$ROOT"把整个文档转为[{k: 键名, v: 对应值}]的数组$map遍历每个键值对,排除_id后检查嵌套的details.hardware.id是否等于5$anyElementTrue只要有一个键值对满足条件,就返回该文档
方法二:使用聚合管道实现查询(更灵活)
如果需要后续对结果做进一步处理,聚合管道的方式更合适:
db.collection.aggregate([ // 第一步:将顶层文档转为键值对数组,新增临时字段存储 { $addFields: { topLevelPairs: { $objectToArray: "$$ROOT" } } }, // 第二步:匹配符合条件的文档 { $match: { "topLevelPairs.v.details.hardware.id": 5, "topLevelPairs.k": { $ne: "_id" } } }, // 可选:移除临时字段,还原文档结构 { $project: { topLevelPairs: 0 } } ])
额外优化
如果你的外层键有固定格式(比如都是数字字符串),可以在条件里加正则过滤,避免匹配无关字段:
比如在$map的$and里新增:
{ $regexMatch: { input: "$$item.k", regex: /^\d+$/ } }
内容的提问来源于stack exchange,提问作者wwwwwwww
相关产品推荐
相关产品推荐

