MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mongo :compter le nombre d'occurrences de mots dans un ensemble de documents

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 }