mikemaccana
mikemaccana

Reputation: 123490

How can I add a computed field using an arbitrary function with Mongo aggregate framework?

I'm using MongoDB's Aggregate Framework. I have an existing field in each of my documents:

time: Date

And I wish create a new field timeBlock based on a simple funcion:

var dateToTimeBlock = function(dateString, timeBlock){
    return new Date(dateString).valueOf() / timeBlock 
}

I understand that $group can add fields, but the functions used to calculate those fields seems to be built into mongo, eg, $avg, $add, etc. Is it possible to generate a computed value based on an arbitrary field?

Upvotes: 7

Views: 11440

Answers (1)

Christian P
Christian P

Reputation: 12240

You can compute fields using aggregation framework. If you want to use native JavaScript functions (like valueOf on Date object) you will have to use Map-Reduce.

Although, aggregation framework is not as flexible as Map-Reduce, in most cases it will be significantly faster. If performance is critical I would precalculate those values and use a simple query instead.

If you want to use aggregation, you can simplify it by converting the Date into an integer or add a new field in the document that's an integer. Then you can than do your calculations easily with $divide.

db.coll.aggregate([
    { $project : { dateToTime: { $divide : [ "$timeInt", timeBlock ] }}}
]);

Or if timeBlock is a field in the same document you can do it like this:

db.coll.aggregate([
    { $project : { dateToTime: { $divide : [ "$timeInt", "$timeBlock" ] }}}
]);

Upvotes: 11

Related Questions