How to batch update documents on a server in MongoDB using calculated values?

I have a collection of things, each thing has some user reviews, and each review has a numerical rating (1-5). I would like to periodically run a batch task that will calculate the average rating for each β€œthing” based on individual ratings in these user reviews and then save the β€œthing” again with this new rating. I would like this to happen on the server without having to download and upload each document.

In other words, I am looking for a solution that will sort through all the things in my collection, summarize the ratings from user reviews, then divide this amount by the number of ratings (thus, get the average value) and store this average value in the property of each document.

I tried to approach this with a map / reduce first, for example:

function () {
    var rating = 0;
    for (var i = 0; i < this.Reviews.length; i++) {
        rating += this.Reviews[i].Rating;
    }
    rating = rating / this.Reviews.length;
    emit(this._id, rating);
}

function(key, values) {
    return null;
}

The ratings look right, but I was not able to call db.things.update () inside the first or second function. I was able to update ratings using the resulting table as follows:

db.reduced.find().forEach(function(thing) {
  db.things.update({_id: thing._id},{$set:{Rating:thing.value}});
});

But this is a client-side solution that is not satisfactory ... It should not be a card / reduction, but is it probably the way to go?

+3
source share
1 answer

Use db.eval (your_JS_code_here).

+1
source

All Articles