如何在未知嵌套键名的MongoDB文档中提取数组元素78
如何从MongoDB未知键的嵌套对象中提取指定值78
没问题,我来帮你解决这个查询问题——当你不知道obj对象内部的键名,但需要提取值78的时候,我们可以利用MongoDB的聚合管道来处理,下面是几种实用的方法:
方法1:提取所有包含78的条目(带对应键名)
这个方法会把所有包含78的键和值都找出来,适合你想知道哪些键下有78的场景:
db.collection.aggregate([ // 第一步:把obj对象转换成[{k: "键名", v: 数值数组}, ...]的格式 { $addFields: { objArray: { $objectToArray: "$obj" } } }, // 第二步:展开objArray,让每个键值对单独成为一条文档 { $unwind: "$objArray" }, // 第三步:展开每个键对应的数值数组,让每个数值单独成文档 { $unwind: "$objArray.v" }, // 第四步:筛选出值等于78的文档 { $match: { "objArray.v": 78 } }, // 第五步:只保留我们需要的键和值,去掉多余字段 { $project: { _id: 0, 匹配值: "$objArray.v", 对应键名: "$objArray.k" } } ])
执行后会得到这样的结果:
{ "匹配值" : 78, "对应键名" : "key..." } { "匹配值" : 78, "对应键名" : "key...." } { "匹配值" : 78, "对应键名" : "key..." }
方法2:获取去重后的78值
如果你只需要确认78存在,或者只想得到唯一的78值,可以在聚合最后加上分组操作:
db.collection.aggregate([ { $addFields: { objArray: { $objectToArray: "$obj" } } }, { $unwind: "$objArray" }, { $unwind: "$objArray.v" }, { $match: { "objArray.v": 78 } }, // 按值分组,去重 { $group: { _id: "$objArray.v" } }, { $project: { _id: 0, 目标值: "$_id" } } ])
结果会是:
{ "目标值" : 78 }
方法3:MongoDB 4.4+简化版(更高效)
如果你用的是MongoDB 4.4及以上版本,可以用$reduce和$filter组合来减少展开操作,效率更高:
db.collection.aggregate([ { $project: { 匹配结果: { $reduce: { input: { $objectToArray: "$obj" }, initialValue: [], in: { // 把每个键数组里筛选出的78拼接成一个数组 $concatArrays: [ "$$value", { $filter: { input: "$$this.v", cond: { $eq: ["$$this", 78] } } } ] } } } } }, { $unwind: "$匹配结果" }, { $project: { _id: 0, 目标值: "$匹配结果" } } ])
这个方法不需要多次$unwind,直接在数组层面完成筛选,性能更好。
内容的提问来源于stack exchange,提问作者Lucifar
相关产品推荐
相关产品推荐

