我试图映射减少大量数据以生成每日图表,但发现该应用程序拥有来自世界各地的用户,并且他们希望在自己的时区中获取数据。
我当前使用的地图简化非常简单
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,并且仍然能够根据用户所在的时区进行查询。
是否有任何简单的方法来完成能够映射并保持使用时区的功能?
答案 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
} } },
} }
])