Mongodb MapReduceプログラミングモデル
Mongodb公式サイトはMapReduceについて紹介します.
Map/reduce in MongoDB is useful for batch processing of data and aggregation operations. It is similar in spirit to using something like Hadoop with all input coming from a collection and output going to a collection. Often, in a situation where you would have used GROUP BY in SQL, map/reduce is the right tool in MongoDB.
MongodbのMap/reduceは主にデータの一括処理と集約操作に用いられ、Hadoopを用いて集合データを処理するのと似ており、すべての入力データは集合から取得され、MapReduce後に出力されたデータも集合に書き込まれる.通常、SQLでGroupBy文を使用するのと同じです.
MapReduceを使用して、MapとReduceの2つの関数を実装します.Map関数はemit(key,value)を呼び出して集合内のすべてのレコードを遍歴し,keyとvalueをReduce関数に渡して処理する.Map関数とReduce関数はJavascriptを用いて記述され、dbを通過することができる.runCommandまたはmapreduceコマンドは、MapReduce操作を実行します.
MapReduceコマンド構文は次のとおりです.
パラメータの説明:
mapreduce:操作するターゲットのセット
map:マッピング関数(Reduce関数のパラメータとしてキー値対シーケンスを生成)
reduce:統計関数
Query:ターゲットレコードフィルタ
sort:ターゲットレコードのソート
Limit:ターゲットレコード数の制限
out:統計結果格納コレクション(指定しない場合は一時コレクションを使用し、クライアントが切断された後に自動的に削除)
keeptemp:一時集合を保持するかどうか
finalize:最終処理関数(reduce戻り結果を最終整理して結果セットに格納)
scope:map、reduce、finalizeに外部変数をインポート
verbose:詳細な時間統計を表示
次に、MapReduceの具体的な使用例を用いて説明する.
適用シーン:studentsセットのデータを統計し、classidに基づいて各クラスの学生数を表示します.初期データは次のとおりです.
Mapグループ
Map関数は、emit(key,value)を呼び出してキー値ペアを返し、thisを使用して現在処理されているDocumentにアクセスする必要があります.次に、Map関数を使用してstudentsテーブルをclassidでグループ化します.
Reduce重合
Reduce関数は、Map関数から返された結果をパラメータとして受け取り、Map関数から返されたキー値シーケンス群合成{key,[value 1,value 2,value 3,...]}は、次のようにreduceに渡されます.
Reduce関数はvaluesを統計し,上のコードからReduce関数は主に1クラスと2クラスの記録数を求和演算していることがわかる.
Result取得結果
Result関数の役割は計算後の結果を取得するためのものであり、使用コマンドはdbである.结果集find().「結果セット」はoutパラメータで指定できます.コードは次のとおりです.
MapReduce処理後の結果はstudents_に格納されるresultコレクション.
Finalizeフォーマット出力
finalize()を用いてreduce()の結果を出力スタイルのフォーマット処理を行うことができる.コードは次のとおりです.
finalize関数を定義した後、MapReduceを再実行し、関数定義に「finalize」パラメータを追加すると、上で定義したfinalize関数を使用して戻り結果をフォーマットできます.コードは次のとおりです.
Queryはターゲットレコードをフィルタリングする
前述したMapReduce構文には、ターゲットセットを条件付きフィルタリングするためのqueryパラメータがあります.result関数に「query」パラメータを追加するだけで、結果セットをフィルタリングできます.コードは次のとおりです.
上記のコードから,result関数にqueryパラメータを追加し,age>22のdocumentのみを統計し,出力結果はクラス当たりの人数が従来より少なかったことがわかる.
MapReduceの詳細については、公式サイト:http://www.mongodb.org/display/DOCS/MapReduceを参照してください.
Map/reduce in MongoDB is useful for batch processing of data and aggregation operations. It is similar in spirit to using something like Hadoop with all input coming from a collection and output going to a collection. Often, in a situation where you would have used GROUP BY in SQL, map/reduce is the right tool in MongoDB.
MongodbのMap/reduceは主にデータの一括処理と集約操作に用いられ、Hadoopを用いて集合データを処理するのと似ており、すべての入力データは集合から取得され、MapReduce後に出力されたデータも集合に書き込まれる.通常、SQLでGroupBy文を使用するのと同じです.
MapReduceを使用して、MapとReduceの2つの関数を実装します.Map関数はemit(key,value)を呼び出して集合内のすべてのレコードを遍歴し,keyとvalueをReduce関数に渡して処理する.Map関数とReduce関数はJavascriptを用いて記述され、dbを通過することができる.runCommandまたはmapreduceコマンドは、MapReduce操作を実行します.
MapReduceコマンド構文は次のとおりです.
db.runCommand(
{ mapreduce : <collection>,
map : <mapfunction>,
reduce : <reducefunction>,
out : <see output options below>
[, query : <query filter object>]
[, sort : <sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces>]
[, limit : <number of objects to return from collection, not supported with sharding>]
[, keeptemp: <true|false>]
[, finalize : <finalizefunction>]
[, scope : <object where fields go into javascript global scope >]
[, jsMode : true]
[, verbose : true]
}
);
パラメータの説明:
mapreduce:操作するターゲットのセット
map:マッピング関数(Reduce関数のパラメータとしてキー値対シーケンスを生成)
reduce:統計関数
Query:ターゲットレコードフィルタ
sort:ターゲットレコードのソート
Limit:ターゲットレコード数の制限
out:統計結果格納コレクション(指定しない場合は一時コレクションを使用し、クライアントが切断された後に自動的に削除)
keeptemp:一時集合を保持するかどうか
finalize:最終処理関数(reduce戻り結果を最終整理して結果セットに格納)
scope:map、reduce、finalizeに外部変数をインポート
verbose:詳細な時間統計を表示
次に、MapReduceの具体的な使用例を用いて説明する.
適用シーン:studentsセットのデータを統計し、classidに基づいて各クラスの学生数を表示します.初期データは次のとおりです.
> db.students.find()
{ "_id" : ObjectId("5031143350f2481577ea81e5"), "classid" : 1, "age" : 20, "name" : "kobe" }
{ "_id" : ObjectId("5031144a50f2481577ea81e6"), "classid" : 1, "age" : 23, "name" : "nash" }
{ "_id" : ObjectId("5031145a50f2481577ea81e7"), "classid" : 2, "age" : 18, "name" : "james" }
{ "_id" : ObjectId("5031146a50f2481577ea81e8"), "classid" : 2, "age" : 19, "name" : "wade" }
{ "_id" : ObjectId("5031147450f2481577ea81e9"), "classid" : 2, "age" : 19, "name" : "bosh" }
{ "_id" : ObjectId("5031148650f2481577ea81ea"), "classid" : 2, "age" : 25, "name" : "allen" }
{ "_id" : ObjectId("5031149b50f2481577ea81eb"), "classid" : 1, "age" : 19, "name" : "howard" }
{ "_id" : ObjectId("503114a750f2481577ea81ec"), "classid" : 1, "age" : 22, "name" : "paul" }
{ "_id" : ObjectId("503114cd50f2481577ea81ed"), "classid" : 2, "age" : 24, "name" : "shane" }
>
Mapグループ
Map関数は、emit(key,value)を呼び出してキー値ペアを返し、thisを使用して現在処理されているDocumentにアクセスする必要があります.次に、Map関数を使用してstudentsテーブルをclassidでグループ化します.
> map=function(){emit(this.classid,1)}
function () {
emit(this.classid, 1);
}
>
Reduce重合
Reduce関数は、Map関数から返された結果をパラメータとして受け取り、Map関数から返されたキー値シーケンス群合成{key,[value 1,value 2,value 3,...]}は、次のようにreduceに渡されます.
> reduce=function(key,values){
... var x = 0;
... values.forEach(function(v){x+=v});
... return x;
... }
function (key, values) {
var x = 0;
values.forEach(function (v) {x += v;});
return x;
}
>
Reduce関数はvaluesを統計し,上のコードからReduce関数は主に1クラスと2クラスの記録数を求和演算していることがわかる.
Result取得結果
Result関数の役割は計算後の結果を取得するためのものであり、使用コマンドはdbである.结果集find().「結果セット」はoutパラメータで指定できます.コードは次のとおりです.
> result=db.runCommand({
... mapreduce:"students",
... map:map,
... reduce:reduce,
... out:"students_result"
... });
{
"result" : "students_result",
"timeMillis" : 297,
"counts" : {
"input" : 9,
"emit" : 9,
"reduce" : 2,
"output" : 2
},
"ok" : 1
}
> db.students_result.find()
{ "_id" : 1, "value" : 4 }
{ "_id" : 2, "value" : 5 }
>
MapReduce処理後の結果はstudents_に格納されるresultコレクション.
Finalizeフォーマット出力
finalize()を用いてreduce()の結果を出力スタイルのフォーマット処理を行うことができる.コードは次のとおりです.
> finalize=function(key,value){return {classid:key,count:value};}
function (key, value) {
return {classid:key, count:value};
}
>
finalize関数を定義した後、MapReduceを再実行し、関数定義に「finalize」パラメータを追加すると、上で定義したfinalize関数を使用して戻り結果をフォーマットできます.コードは次のとおりです.
> result=db.runCommand({
... mapreduce:"students",
... map:map,
... reduce:reduce,
... out:"students_result",
... finalize:finalize
... });
{
"result" : "students_result",
"timeMillis" : 137,
"counts" : {
"input" : 9,
"emit" : 9,
"reduce" : 2,
"output" : 2
},
"ok" : 1
}
> db.students_result.find()
{ "_id" : 1, "value" : { "classid" : 1, "count" : 4 } }
{ "_id" : 2, "value" : { "classid" : 2, "count" : 5 } }
>
Queryはターゲットレコードをフィルタリングする
前述したMapReduce構文には、ターゲットセットを条件付きフィルタリングするためのqueryパラメータがあります.result関数に「query」パラメータを追加するだけで、結果セットをフィルタリングできます.コードは次のとおりです.
> result=db.runCommand({
... mapreduce:"students",
... map:map,
... reduce:reduce,
... out:"students_result",
... finalize:finalize,
... query:{age:{$gt:22}}
... });
{
"result" : "students_result",
"timeMillis" : 776,
"counts" : {
"input" : 3,
"emit" : 3,
"reduce" : 1,
"output" : 2
},
"ok" : 1
}
> db.students_result.find()
{ "_id" : 1, "value" : { "classid" : 1, "count" : 1 } }
{ "_id" : 2, "value" : { "classid" : 2, "count" : 2 } }
>
上記のコードから,result関数にqueryパラメータを追加し,age>22のdocumentのみを統計し,出力結果はクラス当たりの人数が従来より少なかったことがわかる.
MapReduceの詳細については、公式サイト:http://www.mongodb.org/display/DOCS/MapReduceを参照してください.