MongoDB聚合框架 - 按年分组

8

我一直在尝试使用聚合函数按年份对日期字段进行分组:

db.identities.aggregate([
{
    $group : {
        _id : { year : {$year : "$birth_date"}},
        total : {$sum : 1}
        }
    }   
])

然而,我的一些日期早于1970年,在使用Windows的用户中会出现有关gmtime的错误:

{
    "errmsg" : "exception: gmtime failed - your system doesn't support dates before 1970",
    "code" : 16422,
    "ok" : 0
}

我知道现在显而易见的答案是让我运行一个虚拟机或者其他什么东西,但是我只是好奇是否有任何突破口可以解决Windows(我使用的是Windows 7)的问题。如果解决不了这个问题,那么将日期存储为嵌套对象会对性能造成多大影响,比如:

birth_date : {
  year : 1980,
  month : 12,
  day : 9
}

我不太确定涉及索引等技术会有多繁忙。

欢迎任何建议!


你正在使用哪个版本的Mongo? - Alex
2个回答

1

一些Windows版本已知可以工作。你是否使用32位操作系统?相关代码在这里,并依赖于gmtime_s()实现。

如果此集合仅用于聚合查询,则可以通过将日期组件存储在对象中来完成。我建议缩写字段名称(例如ymd)以节省存储空间,因为每个存储的文档中都存在字段字符串。这里的权衡是无法使用任何聚合日期运算符。如果需要,您可能希望将时间戳存储为有符号整数(例如ts),以便可以轻松进行范围查询。


抱歉回复晚了,刚刚重新查看了这个问题。感谢您的答案! - backdesk
这有点恶魔般,因为它确实瘫痪了该平台上的“日期类型”实现。这也会在64位构建中发生:http://stackoverflow.com/q/21869602/2313887 - Neil Lunn
@NeilLunn:我注意到了你在另一个问题中的评论,并打开了[SERVER-12816](https://jira.mongodb.org/browse/SERVER-12816)来跟踪此问题。 - jmikola
我觉得这很令人沮丧,这个问题已经存在了3年,而且它只被认为是一个增强功能。在Windows Server 2012 R2上的v3.0.3中,它仍然无法正常工作。 - joe.feser

0

这个问题是由于聚合时最小日期没有被很好地处理造成的。

一个快速的解决方法(如果可能的话)是通过以下方式过滤日期:

  • 删除具有最小日期的行(通过匹配/筛选)
  • 通过某个日期进行筛选(大于x日期)

然后再进行聚合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接