1)Mapreduceで集計をしたらreduceの処理途中にundefineのレコードがあり、一部集計が失敗した。
不良データを探そうとprint()で_idで調べたら以下のような結果となり不良データがないように見えた。
Map/reduce : _id
map : 1
map : 2
map : 3
reduce : 1
reduce : 2
reduce : 3
map : 4
map : 5
reduce : undefine
reduce : 4
reduce : 5
原因と対策方法は時間があるときに探そう。
2つのCollectionを纏めてMapreduce方法を探していたら
http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/に
2)上は解決したが、それでも集計結果が不一致。
以下の_id : 3 が集計されない。reduceの実行のタイミング怪しい?
Map/reduce :_id : group key(break key?)
map : 1 : 2013-01-01
map : 2 : 2013-01-01
map : 3 : 2013-01-02
reduce : 1 : 2013-01-01
reduce : 2 : 2013-01-01
reduce : 3 : 2013-01-02
map : 4 : 2013-01-02
map : 5 : 2013-01-03
reduce : undefined : undefined ← reduce : 3までの処理結果
reduce : 4 : 2013-01-02
reduce : 5 : 2013-01-03
原因:map -> reduce→map -> reduceが繰り返し処理される。
この繰り返しの時、前のreduceの結果を引き継ぐためにreduceのValue[0]に前回の処理結果が渡される。
例えば
emit( key: {user_id : [this.user_id], count:1}
reduce(key,v) { var reducedValue = {u_id:[], t_c:0}; ... }
にしたとき
同じkeyの中で2回目に呼ばれたv[0]はreducedValueのu_idとt_cの配列が来る。
http://ryooo321.blogspot.jp/2012/05/mongodbmapreduce.html からヒントを頂きました。
*2013/02/19追記
6576件のデータを集計してみたが
600件ずつ集めて、Groupkeyが変更される前の時点で
600件の配列を10回、576件の配列が1回繰り返しの処理に入って来た。
{Key: 2013-02-17 、件数: 201件}
{Key: 2013-02-18 、件数: 6576件}
reduce -> 2013-02-17 :(100件 X 2回)+1件呼出す
reduce -> 2013-02-18 :(100件 X 6回) X10回+(100件 X 5回)+76件 呼出す
finalize -> 2013-02-17 :1回 呼出す
reduce -> 2013-02-18 : (600件 X10回)+ (576件X1回) 呼出す // 新しい配列
finalize -> 2013-02-18 :1回 呼出す
結論は、
mapのemitで指定するValueのIDの名称とreduceのIDの名称を一致させるべき。(マニュアルにあったけど理解出来なかった。)
良い例)
emit( _id , { u_id : this.user_id, t_c : 1})
reduce (k, v) {
var rValue = {u_id : "", t_c : 0};
rValue.t_c += v.t_c;
rValue.t_c += v.u_id + rValue.u_id;
return rValue;
}
悪い例)
emit( _id , { user_id : this.user_id, count : 1})
reduce (k, v) {
var rValue = {u_id : "", t_c : 0};
rValue.t_c += v.count; // undefinedが発生する可能性有り
rValue.t_c += v.user_id + rValue.u_id; // undefinedが発生する可能性有り
return rValue;
}
不良データを探そうとprint()で_idで調べたら以下のような結果となり不良データがないように見えた。
Map/reduce : _id
map : 1
map : 2
map : 3
reduce : 1
reduce : 2
reduce : 3
map : 4
map : 5
reduce : undefine
reduce : 4
reduce : 5
原因と対策方法は時間があるときに探そう。
2つのCollectionを纏めてMapreduce方法を探していたら
http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/に
if (this.FY2009 !== undefined && this.FY2009 !== null) {
のようなCodeがあった。2)上は解決したが、それでも集計結果が不一致。
以下の_id : 3 が集計されない。reduceの実行のタイミング怪しい?
Map/reduce :_id : group key(break key?)
map : 1 : 2013-01-01
map : 2 : 2013-01-01
map : 3 : 2013-01-02
reduce : 1 : 2013-01-01
reduce : 2 : 2013-01-01
reduce : 3 : 2013-01-02
map : 4 : 2013-01-02
map : 5 : 2013-01-03
reduce : undefined : undefined ← reduce : 3までの処理結果
reduce : 4 : 2013-01-02
reduce : 5 : 2013-01-03
原因:map -> reduce→map -> reduceが繰り返し処理される。
この繰り返しの時、前のreduceの結果を引き継ぐためにreduceのValue[0]に前回の処理結果が渡される。
例えば
emit( key: {user_id : [this.user_id], count:1}
reduce(key,v) { var reducedValue = {u_id:[], t_c:0}; ... }
にしたとき
同じkeyの中で2回目に呼ばれたv[0]はreducedValueのu_idとt_cの配列が来る。
http://ryooo321.blogspot.jp/2012/05/mongodbmapreduce.html からヒントを頂きました。
*2013/02/19追記
6576件のデータを集計してみたが
600件ずつ集めて、Groupkeyが変更される前の時点で
600件の配列を10回、576件の配列が1回繰り返しの処理に入って来た。
{Key: 2013-02-17 、件数: 201件}
{Key: 2013-02-18 、件数: 6576件}
reduce -> 2013-02-17 :(100件 X 2回)+1件呼出す
reduce -> 2013-02-18 :(100件 X 6回) X10回+(100件 X 5回)+76件 呼出す
finalize -> 2013-02-17 :1回 呼出す
reduce -> 2013-02-18 : (600件 X10回)+ (576件X1回) 呼出す // 新しい配列
finalize -> 2013-02-18 :1回 呼出す
結論は、
mapのemitで指定するValueのIDの名称とreduceのIDの名称を一致させるべき。(マニュアルにあったけど理解出来なかった。)
良い例)
emit( _id , { u_id : this.user_id, t_c : 1})
reduce (k, v) {
var rValue = {u_id : "", t_c : 0};
rValue.t_c += v.t_c;
rValue.t_c += v.u_id + rValue.u_id;
return rValue;
}
悪い例)
emit( _id , { user_id : this.user_id, count : 1})
reduce (k, v) {
var rValue = {u_id : "", t_c : 0};
rValue.t_c += v.count; // undefinedが発生する可能性有り
rValue.t_c += v.user_id + rValue.u_id; // undefinedが発生する可能性有り
return rValue;
}
0 件のコメント:
コメントを投稿