Brian L. Clark
Brian L. Clark

Reputation: 628

MongoDB Group By _id's Timestamp

I'm looking to group a bunch of documents by creation date.

Using the MongoDB Aggregation Framework, is it possible to group documents by the _id's timestamp?

Something of the like

db.sessions.aggregate(
    { $group : 
        {_id: { $dayOfYear: "$_id.getTimestamp()"},
        count: { $sum: 1 }
    }
})

Thanks

Upvotes: 2

Views: 1546

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151072

The function you are referring to here is a JavaScript method implemented as a shell helper for the ObjectId wrapper. Other driver implementations for various languages contain a similar method whose basic function can be seen from the mongo shell as this:

function (){
    return new Date(parseInt(this.valueOf().slice(0,8), 16)*1000);
}

But this at least in the shell context is JavaScript and you cannot use JavaScript methods within the aggregation framework, only the implemented operators are allowed. There is presently no "helper" in the aggregation framework methods to extract a "timestamp" from an ObjectId.

As well, the required functions as shown in example above to implement this are lacking at present from the aggregation framework. You cannot possibly "cast" an ObjectId as a string, let alone cast strings as integers or convert from a base type.

For the aggregation framework, the best design approach is to include the required date value in your documents and update accordingly.

If you really wish not to do this and must extract a date from the ObjectId value, then you need to use JavaScript evaluation with mapReduce, or otherwise transfer to client side code:

db.collection.mapReduce(
    function() {
        // Get time group per day
        var id = this._id.getTimestamp()
           - ( this._id.getTimestamp() % ( 1000 * 60 * 60 * 24 )  );
        delete this._id;
        emit( id, this );
    },
    function(key,values) {
        // some reduce operation
    },
    { "out": { "inline": 1 } }
)

Upvotes: 2

Related Questions