20
votes

For one of my collections, which must remain unix timestamp instead of isodate, I usually convert the timestamp with new Date(unix_timestamp).

Now I need the new Date(ts) in an aggregation. (the example is in PHP)

'$project' => array ( 'day' => '$new Date(ts)', ...

'$group' => array ( "_id" => array('day' => '$day)', ...),...

does not arrive in the results. The field "day" in the result is missing entirely.

How to get this converted within the aggregation?

3

3 Answers

26
votes

to be able to add a timestamp field from the document, you can do this, given:

{"ts": 1400512120100}

to aggregate as a date:

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

For additional calculated fields in projection you need to use $add operator, like this: (console example)

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

but it's wrong and we get a error message:

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

But I found a simple hack =)

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

In this case we'll have expected result with dates Also, in PHP output you can see error like this:

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

And now, solution(php 5.4 syntax):

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

Starting Mongo 4.0, this can be achieved with the $toDate aggregation operator:

// { "ts": 1400512120100 }
db.collection.aggregate({ $project: { date: { $toDate: "$ts" } } })
// { "date": ISODate("2014-05-19T15:08:40.100Z") }