2011-11-11 5 views
2

私はmapReduceを学んでいます。私は、以下のmap reduce関数をユーザの集合に対して呼び出すようにしました。MongoのMapReduce配列を分割して再結合

function() { 

    m = function() { 
      emit(this.city, {num:1, arr:this}); 
    } 

    r = function (key, arr_values) { 
      var resultArray = []; 
      var count = 0; 
      arr_values.forEach(function (value) { 
            resultArray.push(value); 
            count++; 
           }); 
      return {num:count, arr:resultArray}; 
    } 

    res = db.AdsOnPage.mapReduce(m, r, {out:"ReducedCollection"}); 


} 

これは、私が必要とするもの、つまり「都市」をキーとし、その都市のユーザの配列を値として与えることになります。しかし、それは実際にはネストされた配列の不条理な数で私にそれを与えています。私はこれがシャーディングの結果として起こると思いますか?しかし、私はどのようにすべてに戻ってきますか?現在、結果は次のようになります。

{ 
    "city":"Chicago", 
    "value" : { 
    "num" : 2.0, 
    "arr" : [{ 
     "num" : 2.0, 
     "arr" : [{ 
      "num" : 1.0, 
      "arr" : [{ 
       <user doc is here> 
       }] 
      }, { 
      "num" : 1.0, 
      "arr" : [{ 
       <user doc is here> 
       }] 
      }] 
     } 
....... 
for many many arrays 

なぜこのようなことが起こりますか?私の結果を一貫した単一アレイに再結合する方法はありますか?

答えて

1

シャーディングとは関係ありませんが、これはMap/Reduceロジックで行う必要があります。

mapvalueの関数は、reduceの戻り値と同じ形状である必要があります。

reduceは複数回実行できます。実際、シャーディングの場合は、シャードごとに1回実行され、その後、要求を行うmongosによって再び実行されます。

あなたがマップ/仕事に削減するために

reduce(key, [a,b,c])

を実行すると、出力は以下と同じでなければならない何が起こるかを考えている:

reduce(key, [a, reduce(key, [b,c])) OR

reduce(key, [reduce(key, [a,b]), c])

あなたの場合reduce(key, [b,c])はreturniです

reduce(key, [a, reduce(key, [b,c])) =>reduce(key, [a, [b,c] ])

お知らせ余分な配列:あなたは、次のよう得る配列をngの?だから、あなたは入れ子になっています。

この問題を解決するには、2つの部分が必要です。

  1. valuesがする配列を予定されている場合は、emit出力する必要があり、その中に一つの項目の配列。
  2. この変更を行うと、arr_valuesは「配列の配列」になります。それらを正しく組み合わせる必要があります。

うまくいけば、それは正しい方向にあなたを指しています。デバッグの詳細な方法については、Troubleshooting M/Rのページをご覧ください。

+0

ありがとう、@ゲート。しかし、実際の問題は、ネスティングを解決した後でも、私の結果が複数の配列に分割されて返されているという事実です。あなたは「それらを正しく組み合わせる」と言います。どうすればいい? – carlbenson

+0

'reduce'メソッドでは' arr_values'は値の配列です。各値は、それ自身が配列です。だから 'resultArray.push(value);'を実行することはできません。プッシュしている 'value'は配列です。したがって、各値をループする 'reduce'の内部に別のループが必要です。 –

0

私はこの種の問題を解決するために配列関数Array.isArray(param)とindexOf(param)を使用しますが、私はスタック配列内にユニークな要素を押します。

Array.isArray()を試すことができます。

関連する問題