node.js - MongoDB 聚合查询返回集合中每年每月的条目总数,按位置值分组
问题描述
我正在尝试编写一个 mongo 聚合查询,该查询返回集合中的条目总数year-month,按location分组。
这是所需输出的示例:
[
{
_id: 'Location 1',
reviews: [
{ total: 12, date: '03-2019' },
{ total: 55, date: '04-2019' },
{ total: 9, date: '05-2019' }
]
},
{
_id: 'Location 2',
reviews: [
{ total: 8, date: '03-2019' },
{ total: 35, date: '04-2019' },
{ total: 12, date: '05-2019' }
]
}
];
这是架构的截断示例:
{
branchId: { type: String, required: true },
orgId: { type: String, required: true },
stars: { type: Number, default: 0 },
reviewUpdatedAt: { type: Date, default: Date.now }
}
我能够以各种方式返回数据,但在获得所需输出时遇到问题。以下是我遇到障碍的一些示例查询。基本上我在尝试对每月的总条目进行分组时遇到问题,然后按 branchId / location 进一步分组。
这是按年月分组的示例。响应包含每个 branchId 的计数,但 _ids 对于每个分支的月-年都有重复项。我需要 _id 作为位置,并有一个包含总计和年月的数组,如上面所需输出的示例所示。
[
{
$match: {
stars: {$exists: true, $gte: 1},
orgId: '100003'
// reviewUpdatedAt: { $gte: new Date(fromDate), $lte: new Date(toDate) }
}
},
{
$group: {
_id: { $dateToString: { format: '%Y-%m', date: '$reviewUpdatedAt' }},
branchId: {$addToSet: '$branchId'},
total: { $sum: 1 }
}
},
{
$unwind: '$branchId'
},
{ $sort: { _id: 1 } }
]
在上面的示例中,我成功地调整了组和$unwind
语句,如下所示:
{
$group: {
_id: '$branchId',
date: { $addToSet: { $dateToString: { format: '%Y-%m', date: '$reviewUpdatedAt' } } },
total: { $sum: 1 }
}
},
{ $unwind: '$date' }
但是,总 $sum 并不准确,并且会针对每个 branchId 条目重复。如何修改上述查询以产生所需的输出?任何帮助将不胜感激。
解决方案
您可以尝试以下查询:
db.collection.aggregate([
{
$group: {
_id: {
date: {
$dateToString: {
format: "%m-%Y",
date: "$reviewUpdatedAt"
}
},
loc: "$branchId"
},
Total: {
$sum: 1
}
}
},
{
$group: {
_id: "$_id.loc",
reviews: {
$push: {
Total: "$Total",
"date": "$_id.date"
}
}
}
}
])
测试: MongoDB-游乐场
推荐阅读
- swift - SwiftUI - 将存储中图像文件的路径移动到 Firebase 上的实时数据库
- c++ - 无法使用可变参数编译 constexpr 函数
- reactjs - 不要直接改变状态。使用 setState() react/no-direct-mutation-state 问题
- dropzone.js - 从 dropzonejs 中删除最后添加的文件的内存
- python - if else 语句如何改进?
- python - 在python中加载一个ttf文件
- javascript - 获取其他日子的预报
- python - 我需要帮助计算使用 python 的错误栏
- docker - docker-compose 和 docker:只需要第一次使用虚拟数据进行初始化。最好的方法是什么
- reactjs - 反应地图为什么单击标记后会出现两个信息窗口