MongoDB 3.6基于hour字段过滤hourly嵌套子文档的聚合查询需求
解决方案:MongoDB 3.6聚合过滤嵌套对象
我之前刚处理过类似的需求,MongoDB 3.6提供的聚合操作符组合刚好能完美解决这个问题。核心思路是把嵌套对象转成数组进行精准过滤,再转回对象格式,具体实现如下:
示例输入文档
{ "_id" : "08062017/cpu", "hour": 1, "hourly" : { "0" : "0", "1" : "1", "2" : "2" } } { "_id" : "08062017/cpu2", "hour": 2, "hourly" : { "0" : "0", "1" : "1", "2" : "2" } }
聚合查询语句
db.collection.aggregate([ { $addFields: { hourly: { $arrayToObject: { $filter: { input: { $objectToArray: "$hourly" }, cond: { $eq: ["$$this.k", { $toString: "$hour" }] } } } } } } ])
各阶段详细解释
- $objectToArray: 将
hourly对象转换为键值对数组(格式如[{k: "0", v: "0"}, {k: "1", v: "1"}, ...]),这样我们就能用数组操作符对目标内容进行过滤。 - $filter: 遍历转换后的数组,只保留
k(原对象的键)与hour字段值转换为字符串后相等的元素。这里必须用$toString做类型转换,因为hour是数字类型,而hourly的键是字符串类型,类型不匹配会直接导致过滤失效。 - $arrayToObject: 将过滤后的键值对数组重新转换为对象格式,得到仅包含目标hour对应键值对的
hourly对象。 - $addFields: 用处理后的新
hourly字段替换原字段,同时保留文档中的其他所有字段(比如_id和hour)。
运行结果
执行上述聚合后,会完全匹配你期望的输出:
{ "_id" : "08062017/cpu", "hour": 1, "hourly" : { "1" : "1" } } { "_id" : "08062017/cpu2", "hour": 2, "hourly" : { "2" : "2" } }
内容的提问来源于stack exchange,提问作者David Ramsaran
相关产品推荐
相关产品推荐

