MongoDB Total Weekly Amount for All Previous Weeks

I have a series of documents in MongoDB. An example doc would be

{ 
  createdAt: Mon Oct 12 2015 09:45:20 GMT-0700 (PDT),
  year: 2015,
  week: 41 
}

Imagine that they cover all the weeks of the year, and there can be many in the same week. I want to combine them in such a way that the obtained values ​​represent the sum of each week and all previous weeks, including the final documents.

So, if in the first week of the year there was something like 10, and in the second - 20, the result could be something like

[{ week: 1, total: 10, weekTotal: 10},
 { week: 2, total: 30, weekTotal: 20}]

Creating aggregation to search for weekTotal is quite simple. Turn on projection to display the first part

db.collection.aggregate([
  {
    $project: {
      "createdAt": 1,
      year: {$year: "$createdAt"},
      week: {$week: "$createdAt"},
      _id: 0
    }
  },
  {
    $group: {
      _id: {year: "$year", week: "$week"},
      weekTotal : { $sum : 1 }
    }
  },
]);

But overcoming this amount, based on that week and previous weeks, is not easy.

+4
1

, . "", - , " ", mapReduce :

db.collection.mapReduce(
    function() {

        Date.prototype.getWeekNumber = function(){
            var d = new Date(+this);
            d.setHours(0,0,0);
            d.setDate(d.getDate()+4-(d.getDay()||7));
            return Math.ceil((((d-new Date(d.getFullYear(),0,1))/8.64e7)+1)/7);
        };


        emit({ year: this.createdAt.getFullYear(), week: this.createdAt.getWeekNumber() }, 1);
    },
    function(values) {
        return Array.sum(values);
    },
    { 
        out: { inline: 1 },
        scope: { total: 0 },
        finalize: function(value) {
            total += value;
            return { total: total, weekTotal: value }
        }
    }
)

, "", :

var total = 0;

db.collection.aggregate([
    { "$group": {
        "_id": {
            "year": { "$year": "$createdAt" },
            "week": { "$week": "$createdAt" }
        },
        "weekTotal": { "$sum": 1 }
    }},
    { "$sort": { "_id": 1 } }
]).map(function(doc) {
    total += doc.weekTotal;
    doc.total = total;
    return doc;
});

, , . "", , , - , .

+1

Source: https://habr.com/ru/post/1614819/


All Articles