如何通过MongoDB查询将voice集合按日期分组转换为dailyvoice集合
问题原因
你写的聚合语句存在两个核心错误:
originaltimestamp是yyyyMMddHHmmss格式的字符串,并非MongoDB原生Date类型,无法直接被$dateToString、日期运算类操作符识别处理- 分组后需要将日期键转换为你要求的
ddMMyyyy格式,再作为数组的顶层键
正确实现方案
直接通过字符串截取操作即可完成分组和键格式转换,无需额外转Date类型,性能更好:
db.getCollection('voice').aggregate([ // 提取日期分组键:取originaltimestamp前8位得到yyyyMMdd格式的日期标识 { $addFields: { dateGroupKey: { $substr: ["$originaltimestamp", 0, 8] } } }, // 按日期分组,同天数据存入数组 { $group: { _id: "$dateGroupKey", dailyRecords: { $push: "$$ROOT" } } }, // 转换为目标结构:将yyyyMMdd转成ddMMyyyy作为键 { $replaceRoot: { newRoot: { $arrayToObject: [ { k: { $concat: [ { $substr: ["$_id", 6, 2] }, // 日 { $substr: ["$_id", 4, 2] }, // 月 { $substr: ["$_id", 0, 4] } // 年 ] }, v: "$dailyRecords" } ] } } }, // 结果写入dailyvoice集合 { $out: "dailyvoice" } ])
说明
- 该实现兼容MongoDB 3.4及以上版本,生成的
dailyvoice集合结构和你给出的预期结构完全一致 - 如果需要保留单日交易计数,可以在
$group阶段添加count: { $sum: 1 },再在$replaceRoot阶段把计数字段加入返回结构即可
内容的提问来源于stack exchange,提问作者cauchuyennhocuatoi
相关产品推荐
相关产品推荐

