J'ai une collection d'objets, chaque objet a des évaluations d'utilisateurs et chaque évaluation a une note numérique (1-5). J'aimerais exécuter périodiquement un travail par lots qui calculera la note moyenne de chaque "objet" en fonction des notes individuelles des évaluations des utilisateurs de cet objet, puis réenregistrer l'objet avec cette nouvelle note. J'aimerais que cela se fasse sur le serveur sans qu'il soit nécessaire de télécharger et d'envoyer chaque document.
En d'autres termes, je cherche une solution qui permette d'itérer sur tous les éléments de ma collection, d'additionner les évaluations des utilisateurs, de diviser cette somme par le nombre d'évaluations (ce qui permet d'obtenir la moyenne) et de stocker cette moyenne dans une propriété de chaque document.
J'ai d'abord essayé de l'approcher avec un map/reduce, quelque chose comme :
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;
}
Les évaluations semblent être calculées correctement, mais je n'ai pas réussi à appeler db.things.update() dans la première ou la deuxième fonction. I était capable de mettre à jour les évaluations en utilisant le tableau résultant comme suit :
db.reduced.find().forEach(function(thing) {
db.things.update({_id: thing._id},{$set:{Rating:thing.value}});
});
Mais c'est une solution côté client qui n'est pas satisfaisante... Il n'est pas nécessaire que ce soit map/reduce, mais c'est probablement la voie à suivre ?