2013-06-06 4 views
11

J'essayais d'utiliser MongoDB 2.4.3 (également essayé 2.4.4) avec mapReduce sur un cluster avec 2 partitions avec 3 réplicas. J'ai un problème avec les résultats du travail mapReduce n'étant pas réduit dans la collection de sortie. J'ai essayé un Incremental Map Reduce. J'ai également essayé de "fusionner" au lieu de réduire, mais cela n'a pas fonctionné non plus.MapReduce dans MongoDB ne sort pas

La carte à réduire l'exécution de commandes sur mongos: (Coll ne fragmentées)

db.coll.mapReduce(map, reduce, {out: {reduce: "events", "sharded": true}}) 

Ce qui donne le résultat suivant:

{ 
    "result" : "events", 
    "counts" : { 
     "input" : NumberLong(2), 
     "emit" : NumberLong(2), 
     "reduce" : NumberLong(0), 
     "output" : NumberLong(28304112) 
    }, 
    "timeMillis" : 418, 
    "timing" : { 
     "shardProcessing" : 11, 
     "postProcessing" : 407 
    }, 
    "shardCounts" : { 
     "stats2/192.168.…:27017,192.168.…" : { 
      "input" : 2, 
      "emit" : 2, 
      "reduce" : 0, 
      "output" : 2 
     } 
    }, 
    "postProcessCounts" : { 
     "stats1/192.168.…:27017,…" : { 
      "input" : NumberLong(0), 
      "reduce" : NumberLong(0), 
      "output" : NumberLong(14151042) 
     }, 
     "stats2/192.168.…:27017,…" : { 
      "input" : NumberLong(0), 
      "reduce" : NumberLong(0), 
      "output" : NumberLong(14153070) 
     } 
    }, 
    "ok" : 1, 
} 

Je vois que le MapReduce est exécuté sur 2 enregistrements, ce qui résulte en 2 enregistrements produits. Cependant, dans le postProcessCounts pour les deux fragments, le nombre d'entrées reste 0. Essayer également de trouver l'enregistrement avec une recherche sur _id ne donne aucun résultat. Dans le fichier journal de MongoDB, je n'ai pas pu trouver les messages d'erreur liés à cela. Après avoir essayé de reproduire cela avec une collection de sortie nouvellement créée, que j'ai aussi hachée sur hashid _id et j'ai aussi donné les mêmes index, je n'ai pas pu reproduire cela. Lors de la sortie de la même entrée à une autre collection

db.coll.mapReduce(map, reduce, {out: {reduce: "events_test2", "sharded": true}}) 

Le résultat est stocké dans la collection de sortie et j'ai la sortie suivante:

{ 
    "result" : "events_test2", 
    "counts" : { 
     "input" : NumberLong(2), 
     "emit" : NumberLong(2), 
     "reduce" : NumberLong(0), 
     "output" : NumberLong(4) 
    }, 
    "timeMillis" : 321, 
    "timing" : { 
     "shardProcessing" : 68, 
     "postProcessing" : 253 
    }, 
    "shardCounts" : { 
     "stats2/192.168.…:27017,…" : { 
      "input" : 2, 
      "emit" : 2, 
      "reduce" : 0, 
      "output" : 2 
     } 
    }, 
    "postProcessCounts" : { 
     "stats1/192.168.…:27017,…" : { 
      "input" : NumberLong(2), 
      "reduce" : NumberLong(0), 
      "output" : NumberLong(2) 
     }, 
     "stats2/192.168.…:27017,…" : { 
      "input" : NumberLong(2), 
      "reduce" : NumberLong(0), 
      "output" : NumberLong(2) 
     } 
    }, 
    "ok" : 1, 
} 

Lors de l'exécution du script à nouveau avec la même entrée ouputting nouveau dans la deuxième collection, il montre qu'il est en train de réduire dans postProcessCounts. Ainsi, la carte et les fonctions de réduction font leur travail bien. Pourquoi cela ne marche-t-il pas sur la première grande collection? Est-ce que je fais quelque chose de mal ici? Y a-t-il des limitations spéciales sur les collections qui peuvent être utilisées comme sortie pour map-reduce? MapReduce s'exécute sur 2 enregistrements, ce qui donne 2 enregistrements en sortie.

+0

pour simplifier, puisque cette collection n'est pas ombrée (et est petite) pourquoi n'exécutez-vous pas mapreduce dans une collection de sortie non partagée? –

+1

aussi d'abord vous dites que coll n'est pas partitionné, mais plus tard vous dites que vous essayez à nouveau avec une nouvelle collection que vous * avez aussi * sharded. alors vous m'avez perdu sur le fait que la collection initiale est fragmentée et pourquoi vous partagez la collection de sortie. –

+0

La collection d'entrée n'est pas partitionnée, mais les collections de sortie sont. Ainsi, le problème est le suivant: dans la première collection mise en sourdine, aucune sortie n'est écrite, bien que dans la seconde sortie de collection tronquée ** est ** écrite. À des fins de test, j'ai utilisé une petite entrée ici pour rendre plus facile de voir ce qui se passe, je prévoyais de le faire avec des intrants plus importants à l'avenir. En outre, la mise à jour des enregistrements existants (avec réduire, voir http://docs.mongodb.org/manual/tutorial/perform-incremental-map-reduce/) est très pratique. – Mark

Répondre

0

Toutefois, dans le postProcessCounts pour les deux fragments, le nombre d'entrées reste 0.

La carte est exécutée sur 2 enregistrements. Si ces deux enregistrements ont une clé différente, la carte affichera 2 clés et une valeur pour chacune. Ce qui est normal Mais quelque chose que j'ai remarqué dans une ancienne version de MongoDB (je ne sais pas si cela s'applique dans votre cas) est que si le "tableau de valeurs" pour la phase de réduction a une longueur, la réduction sera ignorée.

La collection de sortie est-elle vide dans le premier cas?