带时区的地图缩小

时间:2018-07-06 07:13:59

标签: mongodb mapreduce

我试图映射减少大量数据以生成每日图表,但发现该应用程序拥有来自世界各地的用户,并且他们希望在自己的时区中获取数据。

我当前使用的地图简化非常简单

var map = function(){
var userLogin = this;

var d = this.StartTime;
var start = d.getFullYear() + '-' + d.getMonth() + 1, + '-' + d.getDate();

var reduceValue = {
    SuccessSession: 0,
    FailSession: 0
}

if(userLogin.ExitReason.Severity <2)
{
    reduceValue.SuccessSession += 1;
} else {
    reduceValue.FailSession += 1;
}

emit({ClientId: this.ClientId, StartDate:start, IsAdmin: this.IsAdmin},
    {SuccessSession: reduceValue.SuccessSession, FailSession: reduceValue.FailSession })
}    

和减少

var reduce = function(key, value) {
var reducedValue = {
    SuccessSession: 0,
    FailSession : 0
};

for(var idx = 0; idx < value.length; idx++)
{
 reducedValue.SuccessSession += value[idx].SuccessSession;
 reducedValue.FailSession += value[idx].FailSession;
}

return reducedValue; 
};

此方法的问题在于它从UTC午夜到UTC进行计算,但是我更希望能够查询Mapreduce,并且仍然能够根据用户所在的时区进行查询。

是否有任何简单的方法来完成能够映射并保持使用时区的功能?

1 个答案:

答案 0 :(得分:0)

没有简单的方法。地图是JavaScript,因此您至少需要IANA TZ数据库。地图功能中提供https://momentjs.com/timezone/之类的东西。

您会考虑使用聚合框架而不是map-reduce吗?它支持时区并且速度更快。管道可以像这样简单:

db.collection.aggregate([
    { $group: {
        _id: {
            ClientId: "$ClientId",
            start: { $dateToString: { 
                format: "%Y-%m-%d", 
                date: "$StartTime",
                timezone: "Europe/Kiev"
            } },
            IsAdmin: "$IsAdmin"
        },
        "SuccessSession": { $sum: { $cond: {
            if: { $lt: [ "$ExitReason.Severity", 2 ] }, 
            then: 1, 
            else: 0 
        } } },
        "FailSession":{ $sum: { $cond: {
            if: { $lt: [ "$ExitReason.Severity", 2 ] }, 
            then: 0, 
            else: 1 
        } } },
    } }
])