MongoDB按年月分组并统计子文档作者出现次数
修正后的MongoDB聚合管道方案
原始管道的问题分析
- 分组逻辑错误:首次分组同时按日期和完整
books对象聚合,无法实现按作者维度的统计 - 年月格式化缺陷:手动拼接
year和month时,无法自动为单个数字月份补零(如4月会变成2022-4而非2022-04) - 结果结构不符合预期:未将统计数据转换为
authors键值对的目标格式
修正后的聚合管道
[ // 拆分books数组,使每条文档对应单本图书 { "$unwind": "$books" }, // 直接生成YYYY-MM格式的年月字符串,仅保留必要字段 { "$project": { "_id": 0, "yearMonth": { "$dateToString": { "format": "%Y-%m", "date": "$date" } }, "author": "$books.author" } }, // 按年月+作者分组,统计每个作者在对应月份的出现次数 { "$group": { "_id": { "yearMonth": "$yearMonth", "author": "$author" }, "count": { "$sum": 1 } } }, // 按年月重新聚合,收集每个作者的统计键值对 { "$group": { "_id": "$_id.yearMonth", "authors": { "$push": { "k": "$_id.author", "v": "$count" } } } }, // 将数组转换为对象格式,并重命名输出字段 { "$project": { "_id": 0, "date": "$_id", "authors": { "$arrayToObject": "$authors" } } } ]
关键步骤说明
- 使用
$dateToString直接生成标准的YYYY-MM日期字符串,避免手动拼接的格式问题 - 两次分组分层处理:先按「年月+作者」统计基础次数,再按「年月」聚合生成最终的作者统计对象
- 通过
$arrayToObject将收集到的键值对数组转换为目标格式的authors对象
输出结果(与预期一致)
[ { "date": "2022-04", "authors": { "Johnson": 2, "Smith": 1 } }, { "date": "2022-05", "authors": { "Johnson": 1, "Smith": 2, "Brooks": 1 } } ]
内容的提问来源于stack exchange,提问作者Jowz
相关产品推荐
相关产品推荐

