2013-07-14 4 views
3

J'utilise la bibliothèque node-mongodb-native pour exécuter MapReduce sur MongoDB (à partir de node.js).MapReduce, MongoDB et node-mongodb-native

Voici mon code:

var map = function() { 
     emit(this._id, {'count': this.count}); 
    }; 
var reduce = function(key, values) { 
     return {'testing':1}; 
    }; 
collection.mapReduce(
    map, 
    reduce, 
    { 
     query:{ '_id': /s.*/g }, 
     sort: {'count': -1}, 
     limit: 10, 
     jsMode: true, 
     verbose: false, 
     out: { inline: 1 } 
    }, 
    function(err, results) { 
     logger.log(results); 
    } 
); 

Deux questions:

1) Au fond, mes réduire la fonction est ignorée. Peu importe ce que je mets dedans, la sortie reste juste le résultat de ma fonction de carte (pas de 'test', dans ce cas). Des idées?

2) J'obtiens une erreur sauf si un index est défini sur le champ utilisé pour le tri (dans ce cas - le champ de compte). Je comprends que c'est à prévoir. Il semble inefficace car sûrement le bon index serait (_id, count) et non (count), car en théorie le _id devrait être utilisé en premier (pour la requête), et seulement alors le tri devrait être appliqué aux résultats applicables. Est-ce que j'ai râté quelque chose? MongoDB est-il inefficace? Est-ce un bug?

Merci! :)

+0

Comment êtes-vous que exécutaient map/reduce? Pourriez-vous coller la commande? –

+0

Ce qui précède est mon code complet dans node.js, en utilisant node-mongodb-native (qui est le code client officiel supporté par 10gen). node-mongodb-native exécute la commande pour vous lorsque vous appelez mapReduce pour une collection. Le code dans la bibliothèque commence par "Collection.prototype.mapReduce =" à: https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js –

+0

Je reçois le résultats dans le rappel, c'est juste qu'il semble que la fonction de réduction est ignorée ... –

Répondre

4

La raison pour laquelle la fonction de réduction n'est jamais appelée est due à l'émission d'une seule valeur pour chaque touche, donc il n'y a aucune raison pour que la fonction de réduction s'exécute réellement. Voici un exemple de la façon dont vous déclenchez la fonction réduire

collection.insert([{group: 1, price:41}, {group: 1, price:22}, {group: 2, price:12}], {w:1}, function(err, r) { 

// String functions 
var map = function() { 
     emit(this.group, this.price); 
    }; 

var reduce = function(key, values) { 
     return Array.sum(values); 
    }; 

collection.mapReduce(
    map, 
    reduce, 
    { 
     query:{}, 
     // sort: {'count': -1}, 
     // limit: 10, 
     // jsMode: true, 
     // verbose: false, 
     out: { inline: 1 } 
    }, 
    function(err, results) { 
     console.log("----------- 0") 
     console.dir(err) 
     console.dir(results) 
     // logger.log(results); 
    } 
); 

avis que nous émettons par la signification clé « groupe » il est n> = 0 entrées groupées par la touche « groupe ». Puisque vous émettez _id chaque touche est unique et donc la fonction de réduction n'est pas nécessaire.

http://docs.mongodb.org/manual/reference/command/mapReduce/#requirements-for-the-reduce-function

Questions connexes