mongodb - 为多个日期范围聚合 $group

标签 mongodb mongodb-query aggregation-framework date-range

在我的汇总中,流中的每个文档都会有一个日期。

我需要对日期范围内的一些值求和..

我的文档如下所示:

{ value: 3,  date: [SoME TIME STAMP] },
{ value: 4,  date: [SoME TIME STAMP] },
{ value: 1,  date: [SoME TIME STAMP] },
{ value: -6, date: [SoME TIME STAMP] }

我希望能够根据日期范围对这些文档进行分组。即:1-7 天前8-15 天前15-30 天前

我可能会在日期上应用 3 个不同的聚合查询和 3 个不同的 $match。

但是是否有可能一次性完成所有的 $group 和“value”字段的总和?

最佳答案

您需要根据当前日期在范围之间的位置有条件地确定分组键。这基本上是通过 $cond 来实现的。带有嵌套条件和 $lt 的逻辑变体:

// work out dates somehow
var today = new Date(),
    oneDay = ( 1000 * 60 * 60 * 24 ),
    thirtyDays = new Date( today.valueOf() - ( 30 * oneDay ) ),
    fifteenDays = new Date( today.valueOf() - ( 15 * oneDay ) ),
    sevenDays = new Date( today.valueOf() - ( 7 * oneDay ) );

db.collection.aggregate([
    { "$match": {
        "date": { "$gte": thirtyDays }
    }},
    { "$group": {
        "_id": {
            "$cond": [
                { "$lt": [ "$date", fifteenDays ] },
                "16-30",
                { "$cond": [
                    { "$lt": [ "$date", sevenDays ] },
                    "08-15",
                    "01-07"
                ]}
            ]
        },
        "count": { "$sum": 1 },
        "totalValue": { "$sum": "$value" }
    }}
])

由于 $cond 是一个三元运算符,因此会评估第一个条件以查看条件是否为真,如果为真,则返回第二个参数,否则在为假时返回第三个参数。因此,通过在 false 情况下嵌套另一个 $cond 您可以获得关于日期所在位置的逻辑测试,或者“小于 15 天日期”,这意味着它在最旧的范围内,或者“小于 7 days"表示中间范围,或者当然是最新的范围。

我只是在小于 10 的数字前加上 0 以便您可以根据需要进行排序,因为 $group< 中的“keys”输出 本身没有顺序。

但这就是您在单个查询中执行此操作的方式。您只需根据日期所在的位置计算出分组键应该是什么,并为每个键累积。

关于mongodb - 为多个日期范围聚合 $group,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33657242/

相关文章:

node.js - 将 $lookup 与条件连接一起使用

MongoDB 嵌套数组交集查询

mongodb - 如何更新 MongoDB 中限制集合中的单个字段?

java - 如何在mongoquery中展开两个数组

Javascript/Typescript .bind() 获取绑定(bind)函数中的变量

mongodb - 获取每个 "loglevel"的 "name"计数

mongodb - 选择 2 个字段并返回具有不同值的排序数组

mongodb - 按 Mongodb 中字段的平均值计算文档

node.js - MongoDB:如果字段值小于10,则将字段值设置为10,否则加1

javascript - 使用 Mongoose 和 Node/ express 保存新帖子时遇到问题