MongoDB如何查询含动态子键的双层嵌套对象符合条件的文档
问题背景
现有存储结构示例如下:
[ { "name": "parent1", "children": { "child1": { "age": 12, "isSomething": true }, "child2": { "age": 13, "isSomething": false }, "child3": { "age": 12, "isSomething": true } } }, { "name": "parent2", "children": { "child4": { "age": 12, "isSomething": true }, "child5": { "age": 15, "isSomething": false } } } // 更多同结构文档 ]
每个文档的children字段为对象类型,存储对应父级的所有子项数据:子项名称作为键,子项属性组成的对象作为值,所有子项名称全局唯一。
需求
需要基于子项的属性值匹配查询父文档,例如查询所有包含age = 15子项的文档,预期返回name为parent2的文档。
核心疑问:MongoDB是否支持通配符匹配children下的未知键名,实现类似find({"children.*.age":15})的查询效果?
解答
MongoDB 4.2及以上版本原生支持这类动态字段的通配符查询,不需要提前枚举children下的子项键名,完全可以实现预期效果。
原生通配符查询方案
你设想的路径匹配逻辑是成立的,MongoDB中用$**表示任意层级、任意名称的通配符,实际查询语句如下:
db.你的集合名.find({ "children.$**.age": 15 })
执行后会自动遍历children下所有子项,匹配age值等于15的文档,针对示例数据会精准返回parent2对应的文档。
如果这类动态字段查询是高频操作,可以给children字段创建通配符索引,大幅提升查询速度,建索引命令:
db.你的集合名.createIndex({ "children.$**": 1 })
低版本兼容方案(MongoDB < 4.2)
4.2之前的版本没有通配符查询能力,可以通过$where执行JS逻辑遍历判断:
db.你的集合名.find({ $where: function() { return Object.values(this.children).some(child => child.age === 15) } })
注意:$where查询性能远低于原生通配符查询,仅适合小数据量临时查询场景,生产环境优先升级版本使用原生方案。
内容的提问来源于stack exchange,提问作者asma
相关产品推荐
相关产品推荐

