Hri*_*shi 31 timezone mongodb mongoid aggregation-framework
我有一个mongodb集合,其中每个文档都有一些属性和一个utc时间戳.我需要从集合中提取数据并使用聚合框架,因为我使用集合中的数据在用户界面上显示一些图表.但是,我需要根据用户的时区进行聚合.假设我知道用户的时区(通过浏览器或其他方式传递请求),有没有办法使用聚合框架根据[客户端]时区进行聚合?
Ast*_*ral 37
除了Matt Johnson提到的SERVER-6310之外,另一个解决方法是使用$project运算符在UTC时区中添加或减去"将时间"转移到正确的本地区域.事实证明,您可以以毫秒为单位添加或减去时间.
例如,假设我有一个名为Date的字段orderTime.我想查询EDT.那是距UTC的-4小时.那是4*60*60*1000毫秒.
所以我会写下面的投影来获取day_ordered我所有记录的当地时间:
db.table.aggregate(
{ $project : { orderTimeLocal : { $subtract : [ "$orderTime", 14400000] } } },
{ $project : { day_ordered : { $dayOfYear : "$orderTimeLocal" } } })
Run Code Online (Sandbox Code Playgroud)
Seb*_*ian 16
上面建议的每种方法都可以很好地工作,但是由于有一个新版本的mongodb,你可以$let在聚合框架中使用2.6,这样你就可以动态创建变量,从而避免$project在分组之前的需要.现在,您可以创建一个包含$let本地化时间的变量,并在$group运算符中使用它.
就像是:
db.test.aggregate([
{$group: {
_id: {
$let: {
vars: {
local_time: { $subtract: ["$date", 10800000]}
},
in: {
$concat: [{$substr: [{$year: "$$local_time"}, 0, 4]},
"-",
{$substr: [{$month: "$$local_time"}, 0, 2]},
"-",
{$substr: [{$dayOfMonth: "$$local_time"}, 0, 2]}]
}
}
},
count: {$sum: 1}
}
}])
Run Code Online (Sandbox Code Playgroud)
请注意,您使用$let块/变量的内部定义,并且该块/变量的值是子表达式的返回值"in",其中使用了上面定义的变量.
Mat*_*int 11
您目前正在MongoDB问题SERVER-6310中讨论您所要求的内容.
我在一个讨论主题的链接中找到了这个.
对于按日期进行的任何分组,这个问题很常见,包括SQL数据库和NoSQL数据库.事实上,我最近在RavenDB中解决了这个问题.有问题,一个解决方案RavenDB一个很好的说明这里.
MongoDB问题讨论了一种解决方法,类似于我在上面的评论中所描述的.您可以预先计算您感兴趣的当地时间,然后按这些时间进行分组.
用这两种方法很难覆盖世界上的每个时区.您应该决定对您的用户群有意义的少数目标区域,例如我在RavenDB文章中描述的每个办公室方法.
更新:此问题已于2017年7月在MongoDB中解决(版本3.5.11). 解决方案在上面的第一个链接中描述,但简而言之,它们为聚合表达式中的日期引入了一种新的对象格式:{ date: <dateExpression>, timezone: <tzExpression> }允许您指定聚合时使用的时区.请参阅此处以获取Mongo文档中的另一个示例.
| 归档时间: |
|
| 查看次数: |
48663 次 |
| 最近记录: |