MongoDB在PHP中聚合,增加了日期/时间的秒数

时间:2013-01-28 19:26:10

标签: php mongodb aggregation-framework

我在MongoDB中的PHP聚合定义为:

$results = $c->aggregate(array(
    array(
      '$project' => array(
          'year' => array('$year' => array('$add' => array('$executed.getTime()', 3600))),
          'month' => array('$month' => array('$add' => array('$executed.getTime()', 3600))),
          'day' => array('$dayOfMonth' => array('$add' => array('$executed.getTime()', 3600)))
      ),
    ),
    array(
      '$group' => array(
          '_id' => array('year' => '$year', 'month' => '$month', 'day' => '$day'),
          'count' => array('$sum' => 1)
      ),
    ),
    array(
      '$sort' => array(
          '_id' => 1
      ),
    ),
    array(
      '$limit' => 30
    )
));

问题是$add中的$project聚合函数无效。

 exception: the $year operator does not accept an object as an operand

在日期/时间字段$executed中添加任意秒数的正确方法是什么?

感谢。

1 个答案:

答案 0 :(得分:0)

您看到的问题是MongoDB中的一个错误,我在SERVER-9289中报告过。解决这个问题需要将参数包装到数组中的date运算符,如下面的shell示例所示:

> db.foo.drop()

> db.foo.insert({x:ISODate()})

> db.foo.aggregate({$project: {x:1, y: {$year: {$add:['$x',1000]}}}})
Error: Printing Stack Trace
    at printStackTrace (src/mongo/shell/utils.js:37:7)
    at DBCollection.aggregate (src/mongo/shell/collection.js:897:1)
    at (shell):1:8
Mon Apr  8 18:15:15.198 JavaScript execution failed: aggregate failed: {
    "errmsg" : "exception: the $year operator does not accept an object as an operand",
    "code" : 16021,
    "ok" : 0
} at src/mongo/shell/collection.js:L898

> db.foo.aggregate({$project: {x:1, y: {$year: [{$add:['$x',1000]}]}}})
{
    "result" : [
        {
            "_id" : ObjectId("516341333512acfb2d33f156"),
            "x" : ISODate("2013-04-08T22:14:11.665Z"),
            "y" : 2013
        }
    ],
    "ok" : 1
}

把它移植到PHP上应该是微不足道的。

话虽如此,您的原始代码在$executed的引用中确实存在错误。根据{{​​3}}文档,您可以按名称引用BSON文档中的字段(或对象/数组中字段的虚线路径),但不支持在这些字段上调用JavaScript方法。沿着这些方向,聚合管道在原始BSON文档上运行,因此这些类型在管道过程中永远不会被转换为它们的JavaScript表示形式(例如,BSON日期永远不会成为ISODate)。

值得庆幸的是,MongoDB 2.4甚至不需要调用$executed.getTime()$project$add$subtract中改进了对BSON日期处理的支持。您可以查看该票证以获取更多详细信息,例如减去两个日期的预期结果,或添加日期和数字。