我在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
中添加任意秒数的正确方法是什么?
感谢。
答案 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日期处理的支持。您可以查看该票证以获取更多详细信息,例如减去两个日期的预期结果,或添加日期和数字。