如何在MongoDB文档中不枚举字段计算多个月份字段的平均值
MongoDB动态计算月份字段平均值解决方案
错误原因
你原有聚合返回null的核心问题是语法使用不符合MongoDB规范:MongoDB不存在$all这种指代文档所有字段的语法,$isNumber、$push的用法也和需求不匹配,无法实现动态提取月份字段的效果。
正确聚合查询
[ { $match: { "WELL": "199-H4-15A" } }, { $project: { monthFields: { $filter: { input: { $objectToArray: "$$ROOT" }, as: "field", cond: { $and: [ // 匹配月份字段格式:三个字母+横杠+两位数字 { $regexMatch: { input: "$$field.k", regex: /^[A-Za-z]{3}-\d{2}$/ } }, // 确保字段值是数字,避免异常值影响计算 { $isNumber: "$$field.v" } ] } } } } }, { $unwind: "$monthFields" }, { $group: { _id: null, average: { $avg: "$monthFields.v" } } } ]
逻辑说明
$match阶段:过滤出指定井号的目标文档,和你原有逻辑一致$project阶段:通过$$ROOT获取当前完整文档,用$objectToArray将所有字段转为{k: 字段名, v: 字段值}格式的数组,再用$filter筛选出符合月份命名规则的字段$unwind阶段:将筛选后的月份数组成员拆分为独立文档$group阶段:对所有月份字段的值计算平均值
简化版本(MongoDB >= 5.0支持)
更高版本的MongoDB支持直接对数组元素计算平均值,无需拆分数组:
[ { $match: { "WELL": "199-H4-15A" } }, { $project: { average: { $avg: { $map: { input: { $filter: { input: { $objectToArray: "$$ROOT" }, as: "field", cond: { $and: [ { $regexMatch: { input: "$$field.k", regex: /^[A-Za-z]{3}-\d{2}$/ } }, { $isNumber: "$$field.v" } ] } } }, in: "$$this.v" } } } } } ]
内容的提问来源于stack exchange,提问作者mountainscaler
相关产品推荐
相关产品推荐

