MapReduce pourrait être un bon ajustement qui peut traiter les documents sur le serveur sans faire de manipulation sur le client (car il n'y a pas de fonctionnalité pour diviser une chaîne sur le serveur de base de données (problème ouvert).
Commencez par la map
une fonction. Dans l'exemple ci-dessous (qui doit probablement être plus robuste), chaque document est passé à la map
fonction (comme this
). Le code recherche le summary
champ et s'il est là, le met en minuscules, se divise sur un espace, puis émet un 1
pour chaque mot trouvé.
var map = function() {
var summary = this.summary;
if (summary) {
// quick lowercase to normalize per your requirements
summary = summary.toLowerCase().split(" ");
for (var i = summary.length - 1; i >= 0; i--) {
// might want to remove punctuation, etc. here
if (summary[i]) { // make sure there's something
emit(summary[i], 1); // store a 1 for each word
}
}
}
};
Ensuite, dans le reduce
fonction, elle additionne tous les résultats trouvés par la map
fonction et renvoie un total discret pour chaque mot qui a été emit
ci-dessus.
var reduce = function( key, values ) {
var count = 0;
values.forEach(function(v) {
count +=v;
});
return count;
}
Enfin, exécutez le mapReduce :
> db.so.mapReduce(map, reduce, {out: "word_count"})
Les résultats avec vos exemples de données :
> db.word_count.find().sort({value:-1})
{ "_id" : "is", "value" : 3 }
{ "_id" : "bad", "value" : 2 }
{ "_id" : "good", "value" : 2 }
{ "_id" : "this", "value" : 2 }
{ "_id" : "neither", "value" : 1 }
{ "_id" : "or", "value" : 1 }
{ "_id" : "something", "value" : 1 }
{ "_id" : "that", "value" : 1 }