我有一个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
)
));
问题是$project
中的$add
聚合函数不起作用。
exception: the $year operator does not accept an object as an operand
向日期/时间字段$executed
添加任意秒数的正确方法是什么?
谢谢。
你看到的问题是MongoDB中的一个错误,我已经在SERVER-9289中报告过。解决此问题的方法是将参数包装为数组中的日期运算符,如以下 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
时确实存在错误。根据$project文档,您可以按名称(或对象/数组中字段的虚线路径)引用 BSON 文档中的字段,但不支持在这些字段上调用 JavaScript 方法。按照这些思路,聚合管道在原始 BSON 文档上运行,因此这些类型在管道过程中永远不会转换为它们的 JavaScript 表示(例如,BSON 日期永远不会成为 ISODate)。
值得庆幸的是,在MongoDB 2.4中甚至不需要调用$executed.getTime()
。SERVER-6239 改进了对 $add
和 $subtract
中 BSON 日期处理的支持。您可以查看该票证以获取更多详细信息,例如减去两个日期或添加日期和数字的预期结果。