moving average with mongodb??

447 views
Skip to first unread message

Andrés

unread,
Sep 10, 2014, 10:11:29 AM9/10/14
to mongod...@googlegroups.com
Hello,

How can I to create a moving average with mongodb?

My documents have 2 fields: Month and visits

thx!

Will Berkeley

unread,
Sep 10, 2014, 11:48:29 AM9/10/14
to mongod...@googlegroups.com
You didn't specify your data structure very well or give an example of exactly what you want, so I'm going to make it up to make it convenient. In the mongo shell, assuming documents of the form

    { "month": 0, "visits": 100 }
    { "month": 1, "visits": 200 }
    { "month": 2, "visits": 300 }
    { "month": 3, "visits": 400 }
    { "month": 4, "visits": 500 }

use an aggregation pipeline with input the current month

// return the average number of visits going back backMonth months from currentMonth (inclusive both ends)
movingAverage
= function(currentMonth, backMonths) {
   
var result = db.visitsByMonth.aggregate([
     
{ "$match" : { "month" : { "$lte" : currentMonth, "$gte" : currentMonth - backMonths } } },
     
{ "$group" : { "_id" : 0, "sum" : { "$sum" : "$visits" }, "count" : { "$sum" : 1 } } },
      { "$project" : { "average" : { "$divide" : ["$sum", "$count"] } } }
    ])
   
return result.toArray()[0].average
}

This isn't a robust function but it has the essential ideas.

> movingAverage(4, 0)
500
> movingAverage(4, 1)
450
> movingAverage(4, 2)
400
> movingAverage(4, 3)
350
> movingAverage(4, 4)
300

-Will

Andrés

unread,
Sep 11, 2014, 3:38:45 AM9/11/14
to mongod...@googlegroups.com
Will! Is perfect!!! Thank you soooo much!!!!

César Antonio Pérez Quintana

unread,
Sep 11, 2014, 12:04:40 PM9/11/14
to mongod...@googlegroups.com
The last two elements of the pipeline can be reduced to this one:

{$group: {_id:0, average:{$avg: "$visits"}}}

Will Berkeley

unread,
Sep 11, 2014, 12:57:38 PM9/11/14
to mongod...@googlegroups.com
Good point. I overlooked that operator.

-Will
Reply all
Reply to author
Forward
0 new messages