MongoDB マップ リデュース
Map-Reduce はコンピューティング モデルです。簡単に言えば、大量の作業 (データ) が実行のために分解され (MAP)、その結果が最終結果にマージされます (REDUCE)。
MongoDB が提供する Map-Reduce は非常に柔軟で、大規模なデータ分析に非常に実用的です。
MapReduce コマンド
以下は、MapReduce の基本的な構文です:
>db.collection.mapReduce( function() {emit(key,value);}, //map 函数 function(key,values) {return reduceFunction}, //reduce 函数 { out: collection, query: document, sort: document, limit: number } )
MapReduce を使用して、Map 関数と Reduce 関数の 2 つの関数を実装します。Map 関数は、emit(key, value) を呼び出します。 コレクション内のすべてのレコードを走査し、キーと値を Reduce 関数に渡して処理します。
Map 関数は、キーと値のペアを返すために Emit(key, value) を呼び出す必要があります。
パラメータの説明:
map: マッピング関数 (reduce 関数のパラメータとしてキーと値のペアのシーケンスを生成します)。
reduce 統計関数、reduce 関数のタスクは、Key-Value を Key-Value に変換すること、つまり、values 配列を単一の値の値に変換することです。 。
out 統計結果のストレージコレクション (指定しない場合、一時的なコレクションが使用され、クライアントの切断後に自動的に削除されます)。
query フィルター条件。条件を満たすドキュメントのみがマップ関数を呼び出します。 (query.limit、sort は自由に組み合わせることができます)
sort sort 並べ替えパラメーターを limit と組み合わせると (マップ関数に送信する前にドキュメントを並べ替えることもできます)、グループ化メカニズムを最適化できます
limit Send to マップ関数のドキュメント数の上限 (制限がない場合、sort だけを使用してもあまり意味がありません)
MapReduce の使用
ユーザーの記事を保存するには、次のドキュメント構造を検討します。 document にはユーザーの user_name と記事の status フィールドが保存されます:
>db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "mark", "status":"active" }) WriteResult({ "nInserted" : 1 }) >db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "mark", "status":"active" }) WriteResult({ "nInserted" : 1 }) >db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "mark", "status":"active" }) WriteResult({ "nInserted" : 1 }) >db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "mark", "status":"active" }) WriteResult({ "nInserted" : 1 }) >db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "mark", "status":"disabled" }) WriteResult({ "nInserted" : 1 }) >db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "php", "status":"disabled" }) WriteResult({ "nInserted" : 1 }) >db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "php", "status":"disabled" }) WriteResult({ "nInserted" : 1 }) >db.posts.insert({ "post_text": "php中文网,最全的技术文档。", "user_name": "php", "status":"active" }) WriteResult({ "nInserted" : 1 })
次に、posts コレクションの mapReduce 関数を使用して、公開された記事 (ステータス: "active") を選択し、user_name ごとにグループ化し、記事の数を計算します。各ユーザーの記事:
>db.posts.mapReduce( function() { emit(this.user_name,1); }, function(key, values) {return Array.sum(values)}, { query:{status:"active"}, out:"post_total" } )
上記のmapReduceの出力結果は次のとおりです:
{ "result" : "post_total", "timeMillis" : 23, "counts" : { "input" : 5, "emit" : 5, "reduce" : 1, "output" : 2 }, "ok" : 1 }
この結果は、クエリ条件を満たすドキュメントが4つあることを示しています(ステータス: "アクティブ")。 Map関数で4つのキーと値のペアのドキュメントが生成され、最後にreduce関数を使用して同じキー値を2つのグループに分割します。
特定のパラメータの説明:
result: 結果を保存するコレクションの名前。これは一時的なコレクションであり、MapReduce 接続が閉じられると自動的に削除されます。
timeMillis: 実行にかかる時間 (ミリ秒単位)
input: 条件を満たし、マップ関数に送信されたドキュメントの数
emit: Emit が呼び出された回数マップ関数、つまり all コレクション内のデータの総量
output: 結果コレクション内のドキュメントの数 (カウントはデバッグに非常に役立ちます)
ok: かどうかは成功、成功は 1 です
エラー: 失敗した場合、失敗には理由があるかもしれませんが、経験上、その理由は曖昧で効果はほとんどありません
find 演算子を使用して、mapReduce クエリの結果を表示します:
>db.posts.mapReduce( function() { emit(this.user_name,1); }, function(key, values) {return Array.sum(values)}, { query:{status:"active"}, out:"post_total" } ).find()
上のクエリは、2 人のユーザー tom と mark が 2 つの公開記事を持っていることを示しています:
{ "_id" : "mark", "value" : 4 } { "_id" : "php", "value" : 1 }
同様の方法で、MapReduce を使用して Large を構築できます。複雑な集計クエリ。
Map 関数と Reduce 関数は JavaScript を使用して実装できるため、MapReduce を非常に柔軟かつ強力に使用できます。