2013-09-23 3 views
2

J'essaie d'exécuter un simple MapReduce MongoDB pour compter les utilisateurs actifs dans ma base de données (voir ci-dessous).MapReduce comportement étrange

Pour une raison quelconque, il semble que le script ne récupère pas toute la base de données. J'ai 400 disques mais ça n'en compte que 80 si j'en fais la somme.

Est-ce que je fais quelque chose de mal ou y a-t-il une limite de valeurs par clé? Toute aide bienvenue.

db.user.mapReduce(
// map 
function() { 
     emit(this.state, {count: 1}); 
}, 

// reduce 
function(key, val) { 

    var counttotal = 0; 
    var countActive = 0; 

    for (var i in val) { 
     data = val[i]; 

     counttotal++; 

     // active state 
     if (key == 1) { 
      countActive++; 
     } 

    } 

    return { 
     countActive: countActive, 
     counttotal: counttotal 
    }; 

}, 

{ 
    out: { 
     replace: "report" 
    }, 
    query: { 
     created_on: { $lt: new Date(2013, 8) } 
    } 
}) 
+1

carte réduire est dosé à 101 résultats qui signifie que votre fonction reduce est en fait le retour des derniers résultats par lots en raison de ' var counttotal = 0; var countActive = 0; 'qui réinitialise vos résultats – Sammaye

+0

Merci @Sammaye, cela a du sens. Comment pourrais-je faire une somme de ces lots alors, dans la finalisation? –

+0

Vous pouvez utiliser les résultats de la valeur précédente pour continuer à compter, vous pouvez utiliser l'opérateur '+ =' sur les vars pour les mettre seulement 0 s'ils sont etc etc – Sammaye

Répondre

0

Vous pouvez utiliser de simples pipeline cadre d'agrégation qui est officiellement recommandé sur la carte-réduire:

db.states.aggregate([ 
    {$match: {created_on: { $lt: new Date(2013, 8) }}}, 
    {$project: {state: 1, active: {$cond: [{$eq: ["$state", 1]}, 1, 0]}}}, 
    {$group: {_id : "$state", total: {$sum: 1}, totalActive: {$sum: "$active"}}} 
    ])