繁体   English   中英

带循环的MongoDB聚合管道

[英]MongoDB aggregation pipeline with loop

我下面有这个聚合管道代码,希望在一年中的每一天都运行! 本质上计算一年中每一天的最低,最高和平均温度(“ TEMP”字段)。 目前,我将这段代码调用365次,传递一天的开始日期和结束日期。

显然,这是非常低效的。 有什么方法可以在mongo中循环它,使其更快,并返回365个平均值,365个最小值和365个最大值等数组。 我使用时区库来导出开始日期和结束日期。

collection.aggregate([
    {
    $match:{$and:[
        {"UID"  : uid},
        {"TEMP" :{$exists:true}}
        {"site" : "SITE123"},
        {"updatedAt": {$gte : new Date(START_DATE_ARG), $lte : new Date(END_DATE_ARG)} }
        ]}
    },

    { "$group": {
        "_id": "$UID",
        "avg": { $avg: $TEMP },
        "min": { $min: $TEMP },
        "max": { $max: $TEMP }
        }
    }
], function(err, result){
                if (err){
                     cb(1, err);
                }
                else{
                    cb(0, result);
                }
            });
});

数据集看起来像这样

....
{UID: "123", TEMP: 11, site: "SITE123", updatedAt: ISODate("2014-09-12T21:55:19.326Z")}
{UID: "123", TEMP: 10, site: "SITE123", updatedAt: ISODate("2014-09-12T21:55:20.491Z")}
....

有任何想法吗? 也许我们可以在聚合管道中传递一年中所有日期的所有时间戳?

谢谢!!

当您只需将日期作为分组键的一部分时,为什么还要每天运行一次? 这就是日期聚合运算符的用途,因此您可以按时间段在整个周期内一次聚合,而不会循环:

collection.aggregate([
    { "$match":{
        "UID": uid,
        "TEMP":{ "$exists": true }
        "site" : "SITE123",
        "updatedAt": {
            "$gte": new Date(START_DATE_ARG), 
            "$lte": new Date(END_DATE_ARG)
        }}
    }},

    { "$group": {
        "_id": { 
            "uid": "$UID",
            "year": { "$year": "$updatedAt" },
            "month": { "$month": "$updatedAt" },
            "day": { "$dayOfMonth" }
        },
        "avg": { "$avg": "$TEMP" },
        "min": { "$min": "$TEMP" },
        "max": { "$max": "$TEMP" }
    }}
])

或者可能只是将日期压缩为时间戳值。 有关日期对象的日期数学技巧:

collection.aggregate([
    { "$match":{
        "UID": uid,
        "TEMP":{ "$exists": true }
        "site" : "SITE123",
        "updatedAt": {
            "$gte": new Date(START_DATE_ARG), 
            "$lte": new Date(END_DATE_ARG)
        }}
    }},

    { "$group": {
        "_id": { 
            "uid": "$UID",
            "date": {
                "$subtract": [
                    { "$subtract": [ "$updatedAt", new Date("1970-01-01") ] },
                    { "$mod": [
                        { "$subtract": [ "$updatedAt", new Date("1970-01-01") ] },
                        1000 * 60 * 60 * 24
                    ]}
                ]
            }
        },
        "avg": { "$avg": "$TEMP" },
        "min": { "$min": "$TEMP" },
        "max": { "$max": "$TEMP" }
    }}
])

当然,这里的“日期范围”现在是结果中需要的所有日期,因此,要循环播放的所有内容的开始日期和结束日期。 无论哪种情况,都进行分组以反映“一天” ,但是您当然可以将其更改为想要的任何间隔。

另请注意,您不必在此处使用$and 默认情况下,MongoDB中的查询“和”条件。 您唯一需要该运算符的是针对同一字段上的多个条件,这些条件否则将不是有效的JSON / BSON。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM