2013-02-20 65 views
16

对于我的一个集合,它必须保持unix时间戳而不是isodate,我通常用新日期(unix_timestamp)转换时间戳。

现在我需要new Date(ts)在一个聚合。 (例子是在PHP)

'$项目'=>阵列( '天'=> '$新的日期(TS)',...

'$组'=>阵列( “_id”=> array('day'=>'$ day)',...),...

未到达结果中结果字段“day”完全缺失

如何在汇总内获得此转换?

回答

3

对于广告ditional计算领域的投影需要使用$添加运营商,像这样: (控制台例子)

db.so.aggregate([{$project: {date: {$add: Date() }}}]) 

但它是错误的,我们得到了一个错误信息:

exception: $add does not support strings (or dates) 

但是我发现一个简单的砍=)

db.so.aggregate([{$project: {date: {$substr: [Date(), 0, -1] }}}]) 

在这种情况下,我们将有日期 也有望因此,在PHP中输出,您可以看到错误是这样的:

exception: disallowed field type Date in object expression (at 'date') 

而现在,解决方案(PHP 5.4语法):

$so->aggregate([ 
    ['$project' => ["date" => ['$substr' => [new MongoDate(), 0, -1]] ] ] 
]); 
+2

这不会将字段ts的值转换为一个mongo日期。它只接受php字符串或数字作为输入,而不是来自集合本身的值:/ – ledy 2013-02-20 21:24:01

+0

Ops,抱歉)可能应该使用map-reduce而不是聚合来处理这种情况? – 2013-02-20 21:58:06

+0

@KirillZorin,这太棒了! substr是完美的投影日期,减少时间部分。这非常有帮助! – 2013-05-06 18:15:14

21

能够从文档中添加时间戳字段,你可以这样做,因为:

{"ts": 1400512120100} 

作为日期汇总:

db.foo.aggregate({ 
    $project: { 
     date: { $add: [new Date(0), "$ts"] } 
    } 
}) 
+1

这对我帮助很大!我的时间戳都是UTC,我想转换为当地时间。我能用这种方法做到这一点。 {$ project:{dd:{$ add:[new Date(0),{$ subtract:[{$ multiply:[“$ items.ordered”,1000]},tzoffset]}]},... – 2014-06-13 17:09:16

+1

我看到这个作品,但是这里发生了什么?在'ISODate(“2014-05-19T15:08:40.100Z”)''中,''新日期(1400512120100)'的结果正确。但是,如果您尝试在不带'$ add'的'$ project'中使用'new Date()',则会在对象表达式中获得'不允许的字段类型Date'。根据这个例子,很明显可以返回日期。如果你在'$ project'中尝试'$ add:[new Date(“$ ts”)]',你会得到一个很大的负值('ISODate(“ - 292275055-05-16T16:47:03.192Z”)' )。 '$ add'如何正确处理数据类型并返回一个'ISODate'没有错误? – duozmo 2016-02-09 21:41:15

+0

@duozmo:我认为'new Date()'不起作用的原因是'new Date()'只在管道启动之前执行一次。只有特殊的MongoDB“聚合运算符”(比如'$ add','$ trunc'等)才会为每个值运行。因此,如果您想在汇总期间创建日期,则必须使用这些运算符中的一个。由于MongoDB中没有运算符'millisecondsToDate',所以您必须(ab)使用'$ add'。 – sleske 2016-08-09 10:22:32