如何在MongoDB数组中搜索不同对象的任意值?
解决方案:搜索MongoDB数组中任意对象的任意值
针对你需要匹配language数组内任意对象的任意值的需求,这里提供两种可行的查询方式,适配不同版本的MongoDB:
方法一:使用$reduce + $objectToArray(MongoDB 3.4+)
该方法通过遍历数组,将每个对象转为键值对数组后提取值,再检查目标值是否存在:
db.collection.find({ $expr: { $reduce: { input: "$language", initialValue: false, in: { $or: [ "$$value", { $in: [ "hello", // 替换成你要搜索的目标值 { $map: { input: { $objectToArray: "$$this" }, as: "item", in: "$$item.v" } } ] } ] } } } })
逻辑说明:
$objectToArray:将language中的每个子对象(如{"English":"hello"})转换为[{"k":"English", "v":"hello"}]格式的键值对数组$map:提取每个键值对的v(值)部分,得到仅包含值的数组$in:检查目标值是否存在于这个值数组中$reduce:遍历整个language数组,只要有一个子对象匹配目标值,最终结果就为true,对应的文档会被筛选出来
方法二:使用$anyElementTrue + $map(MongoDB 5.0+)
如果你的MongoDB版本是5.0及以上,可以用更简洁的$anyElementTrue来判断是否存在匹配项:
db.collection.find({ $expr: { $anyElementTrue: { $map: { input: "$language", as: "langObj", in: { $in: [ "bonjour", // 替换成你要搜索的目标值 { $map: { input: { $objectToArray: "$$langObj" }, as: "item", in: "$$item.v" } } ] } } } } })
逻辑说明:
- 内层
$map和$objectToArray的作用和方法一一致,生成每个子对象的匹配结果(true/false) $anyElementTrue:只要数组中有一个true,就会返回true,对应文档被选中
优化建议
如果这类查询是高频操作,建议调整数据结构,将language数组改为统一键名的格式:
{ "id": 1, "language": [ {"lang": "English", "value": "hello"}, {"lang": "French", "value": "bonjour"} ] }
之后就可以用更高效的普通查询语句:
db.collection.find({"language.value": "hello"})
内容的提问来源于stack exchange,提问作者water
相关产品推荐
相关产品推荐

