注意
map-reduce の代替としての集計パイプライン
MongoDB 5.0 以降、map-reduce は非推奨になっています。
map-reduceの代わりに、集計パイプラインを使用する必要があります。 集計パイプラインは、map-reduce よりもパフォーマンスとユーザビリティが優れています。
map-reduce 操作は、
$group、$mergeなどの集計パイプライン ステージ を使用して書き換えることができます。カスタム機能を必要とする map-reduce 操作には、
$accumulatorと$functionの集計演算子を使用できます。 これらの演算子を使用して、JavaScript でカスタム集計式を定義できます。
map-reduce を集計パイプラインに置き換える例については、以下を参照してください。
重要
mongosh メソッド
This page documents a mongosh method. This is not the documentation for database commands or language-specific drivers, such as Node.js.
データベースコマンドについては、mapReduce コマンドを参照してください。
MongoDB API ドライバーについては、各言語の「MongoDB ドライバーのドキュメント」を参照してください。
定義
db.collection.mapReduce(map,reduce, { <options> })注意
ビューでは map-reduce 操作をサポートしていません。
互換性
このメソッドは、次の環境でホストされている配置で使用できます。
- MongoDB Atlas はクラウドでの MongoDB 配置のための完全管理サービスです
重要
このコマンドは、M0 および Flex クラスターではサポートされていません。詳細については、サポートされていないコマンド を参照してください。
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
注意
MongoDB は冗長オプションを無視します。
MongoDB バージョン 4.2 以降、次の機能が廃止されます。
- 新しいシャーディングされたコレクションを作成するための map-reduce オプション、および、map-reduce のシャードオプションの使用。シャーディングされたコレクションに出力するには、まずシャーディングされたコレクションを作成します。MongoDB 4.2 では、既存のシャーディングされたコレクションの置き換えも非推奨となります。ん。
db.collection.mapReduce() の構文は次のとおりです。
db.collection.mapReduce( <map>, <reduce>, { out: <collection>, query: <document>, sort: <document>, limit: <number>, finalize: <function>, scope: <document>, jsMode: <boolean>, verbose: <boolean>, bypassDocumentValidation: <boolean> } )
パラメーター
db.collection.mapReduce() は以下のパラメーターを取ります。
Parameter | タイプ | 説明 |
|---|---|---|
| javascript または文字列 |
See Requirements for the map Function for more information. |
| javascript または文字列 | 特定の See Requirements for the reduce Function for more information. |
| ドキュメント | A document that specifies additional parameters to |
フィールド
The following table describes additional arguments that db.collection.mapReduce() can accept.
フィールド | タイプ | 説明 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 文字列またはドキュメント | map-reduce 操作の結果のロケーション所を指定します。コレクションに出力したり、アクションを使用してコレクションに出力したり、インラインで出力したりできます。セットのプライマリ ノードに対して map-reduce を実行するときにコレクションに出力できます。セカンダリ ノードでは、 See out Options for more information. | ||||||||||
| ドキュメント |
| ||||||||||
| ドキュメント | 入力ドキュメントを並べ替えます。このオプションは、最適化に役立ちます。たとえば、sort キーを emit キーと同じものに指定すると、reduce 操作の数を減らせます。sort キーは、このコレクションの既存のインデックス内になければなりません。 | ||||||||||
| 数値 |
| ||||||||||
| javascript または文字列 | 任意。 See Requirements for the finalize Function for more information. | ||||||||||
| ドキュメント |
| ||||||||||
| ブール値 |
デフォルトは
| ||||||||||
| ブール値 | 結果情報に デフォルトは This option is ignored. The result information always excludes the | ||||||||||
| ドキュメント | 任意。 任意。操作に使用する照合を指定します。 照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。 照合オプションの構文は次のとおりです。 照合を指定する場合、 照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合( コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。 1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。 | ||||||||||
| ブール値 | オプション。 |
注意
map-reduce operations and $where operator expressions cannot access certain global functions or properties, such as db, that are available in mongosh.
次の JavaScript 関数とプロパティは、map-reduce operationsおよび$where 演算子の式で使用できます。
利用可能なプロパティ | 利用可能な機能 | |
|---|---|---|
|
|
|
map 関数の要件
map関数は、各入力ドキュメントを 0 個以上のドキュメントに変換するのを担当します。 scopeパラメータで定義された変数にアクセスでき、次のプロトタイプがあります。
function() { ... emit(key, value); }
map関数には次の要件があります。
map関数は、関数内で現在のドキュメントをthisとして参照します。map関数は、何らかの理由で データベースにアクセスしてはなりません。map関数は純粋で、関数の外部に影響を与えないようにする必要があります( 副作用はありません。)map関数は任意に、任意の回数でemit(key,value)を呼び出して、keyをvalueに関連付ける出力ドキュメントを作成できます。
次のmap関数は、入力ドキュメントのstatusフィールドの値に応じてemit(key,value)を 0 回または 1 回呼び出します。
function() { if (this.status == 'A') emit(this.cust_id, 1); }
次のmap関数は、入力ドキュメントのitemsフィールドの要素数に応じて、 emit(key,value)を複数回呼び出す場合があります。
function() { this.items.forEach(function(item){ emit(item.sku, 1); }); }
reduce 関数の要件
reduce関数のプロトタイプは次のとおりです。
function(key, values) { ... return result; }
reduce関数は、次の動作を示します。
reduce関数は、読み取り操作を実行する場合でも、データベースにアクセスしないでください。reduce関数は外部システムに影響を与えないようにする必要があります。MongoDB では、同じキーに対して
reduce関数を複数回呼び出すことができます。 この場合、そのキーのreduce関数からの前回の出力は、そのキーの次のreduce関数を呼び出すへの入力値の 1 つになります。reduce関数は、scopeパラメータで定義された変数にアクセスできます。reduceへの入力は、MongoDB の最大 BSON ドキュメント サイズの半分を超えてはなりません。 この要件は、大きなドキュメントが返され、後続のreduceステップで結合された場合に違反される可能性があります。
同じキーに対してreduce関数を複数回呼び出すことができるため、次のプロパティが true である必要があります。
返されるオブジェクトの型は、
map関数によって出力されるvalueの型と同一である必要があります。reduce関数は連想である必要があります。 次のステートメントは true である必要があります。reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( key, [ C, A, B ] ) reduce関数は冪等である必要があります。 次の文が true であることを確認します。reduce( key, [ reduce(key, valuesArray) ] ) == reduce( key, valuesArray ) reduce関数はメンバーシップである必要があります 。つまり、valuesArray内の要素の順序はreduce関数の出力に影響を与えず、次のステートメントが当てはまります。reduce( key, [ A, B ] ) == reduce( key, [ B, A ] )
out オプション
outパラメータには次のオプションを指定できます。
コレクションへの出力
このオプションは新しいコレクションに出力し、レプリカセットのセカンダリ ノードでは使用できません。
out: <collectionName>
アクションを使用したコレクションへの出力
注意
MongoDB バージョン 4.2 以降、次の機能が廃止されます。
- 新しいシャーディングされたコレクションを作成するための map-reduce オプション、および、map-reduce のシャードオプションの使用。シャーディングされたコレクションに出力するには、まずシャーディングされたコレクションを作成します。MongoDB 4.2 では、既存のシャーディングされたコレクションの置き換えも非推奨となります。ん。
このオプションは、すでに存在するコレクションをoutに渡す場合にのみ使用できます。 レプリカセットの セカンダリ ノードでは使用できません。
out: { <action>: <collectionName> [, db: <dbName>] [, sharded: <boolean> ] }
アクションを使用してコレクションに出力する場合、 outには次のパラメータがあります。
<action>: 次のいずれかのアクションを指定します。replace<collectionName>のコレクションが存在する場合は、<collectionName>の内容を置き換えます。merge出力コレクションがすでに存在する場合は、新しい結果を既存の結果とマージします。 既存のドキュメントが新しい結果と同じキーを持っている場合は、その既存のドキュメントを上書きします。
reduce出力コレクションがすでに存在する場合は、新しい結果を既存の結果とマージします。 既存のドキュメントが新しい結果と同じキーを持つ場合は、新しいドキュメントと既存のドキュメントの両方に
reduce関数を適用し、既存のドキュメントを結果で上書きします。
db:任意。 map-reduce 操作で出力を書込むデータベースの名前。 デフォルトでは、これは入力コレクションと同じデータベースになります。
インラインでの出力
メモリ内で map-reduce 操作を実行し、結果を返します。 このオプションは、レプリカセットのセカンダリ ノードでoutのみ使用できるオプションです。
out: { inline: 1 }
finalize 関数の要件
finalize関数のプロトタイプは次のとおりです。
function(key, reducedValue) { ... return modifiedObject; }
finalize関数は、引数としてkey値とreduce関数からのreducedValueを受け取ります。 注意すること:
finalize関数は、何らかの理由で データベースにアクセスしてはなりません。finalize関数は純粋で、関数の外部に影響を与えないようにする必要があります( 副作用はありません。)finalize関数は、scopeパラメータで定義された変数にアクセスできます。
map-reduce の例
このセクションの例には、カスタム集計式を使用しない集計パイプラインの代替手段が含まれています。カスタム式を使用する代替方法については「map-reduce から集計パイプラインへの変換例」を参照してください。
次のドキュメントを含むサンプル コレクションordersを作成します。
db.orders.insertMany([ { _id: 1, cust_id: "Ant O. Knee", ord_date: new Date("2020-03-01"), price: 25, items: [ { sku: "oranges", qty: 5, price: 2.5 }, { sku: "apples", qty: 5, price: 2.5 } ], status: "A" }, { _id: 2, cust_id: "Ant O. Knee", ord_date: new Date("2020-03-08"), price: 70, items: [ { sku: "oranges", qty: 8, price: 2.5 }, { sku: "chocolates", qty: 5, price: 10 } ], status: "A" }, { _id: 3, cust_id: "Busby Bee", ord_date: new Date("2020-03-08"), price: 50, items: [ { sku: "oranges", qty: 10, price: 2.5 }, { sku: "pears", qty: 10, price: 2.5 } ], status: "A" }, { _id: 4, cust_id: "Busby Bee", ord_date: new Date("2020-03-18"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" }, { _id: 5, cust_id: "Busby Bee", ord_date: new Date("2020-03-19"), price: 50, items: [ { sku: "chocolates", qty: 5, price: 10 } ], status: "A"}, { _id: 6, cust_id: "Cam Elot", ord_date: new Date("2020-03-19"), price: 35, items: [ { sku: "carrots", qty: 10, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "A" }, { _id: 7, cust_id: "Cam Elot", ord_date: new Date("2020-03-20"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" }, { _id: 8, cust_id: "Don Quis", ord_date: new Date("2020-03-20"), price: 75, items: [ { sku: "chocolates", qty: 5, price: 10 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "A" }, { _id: 9, cust_id: "Don Quis", ord_date: new Date("2020-03-20"), price: 55, items: [ { sku: "carrots", qty: 5, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 }, { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" }, { _id: 10, cust_id: "Don Quis", ord_date: new Date("2020-03-23"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" } ])
カスタマーあたりの合計価格を返す
orders コレクションに対して map-reduce 操作を実行して、cust_idごとにグループ化し、各cust_id の price の合計値を計算します。
各入力ドキュメントを処理する map 関数を定義します。
この関数では、
thisは map-reduce 操作で処理中のドキュメントを参照します。この関数は、各ドキュメントの
priceをcust_idにマッピングし、cust_idとpriceを出力します。
var mapFunction1 = function() { emit(this.cust_id, this.price); }; 2つの引数
keyCustIdとvaluesPricesを使用して、対応する reduce 関数を定義します。valuesPricesは、map 関数によって出力され、keyCustIdでグループ化されたprice値を要素とする配列です。この関数は
valuesPrice配列をその要素の合計にまで減らします。
var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; ordersコレクション内のすべてのドキュメントに対して、map 関数mapFunction1と reduce 関数reduceFunction1を使用して map-reduce を実行します。db.orders.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } ) この操作は、結果を
map_reduce_exampleという名前のコレクションに出力します。map_reduce_exampleコレクションがすでに存在する場合、この操作により、内容が map-reduce 操作の結果に置き換えられます。map_reduce_exampleコレクションをクエリして、結果を検証します。db.map_reduce_example.find().sort( { _id: 1 } ) この操作では、次のドキュメントが返されます。
{ "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Busby Bee", "value" : 125 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Don Quis", "value" : 155 }
集計の代替手段
次のとおり利用可能な集約パイプライン演算子を使用すると、カスタム関数を定義しなくても map-reduce 操作を書き換えることができます。
db.orders.aggregate([ { $group: { _id: "$cust_id", value: { $sum: "$price" } } }, { $out: "agg_alternative_1" } ])
agg_alternative_1コレクションをクエリして、結果を検証します。db.agg_alternative_1.find().sort( { _id: 1 } ) この操作により、次のドキュメントが返されます。
{ "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Busby Bee", "value" : 125 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Don Quis", "value" : 155 }
Tip
カスタム集計式を使用する代替方法については、「Map-Reduceから集約パイプラインへの変換例」を参照してください。
アイテムごとの平均数量で注文と合計数量を計算
次の例では、orders 上でord_date の値が 2020-03-01 以上となるすべてのドキュメントについての map-reduce 操作を示します。
この例での操作は次のとおりです。
item.skuフィールドでグループ化し、各skuの注文数と合計注文数量を計算します。各
sku値について、1 回の注文あたりの平均数量を計算し、結果を出力コレクションにマージします。
結果をマージするときに、既存のドキュメントが新しい結果と同じキーを持っている場合、操作によって既存のドキュメントが上書きされます。同じキーを持つ既存のドキュメントが存在しない場合は、この操作によってドキュメントが挿入されます。
手順の例:
各入力ドキュメントを処理する map 関数を定義します。
この関数では、
thisは map-reduce 操作で処理中のドキュメントを参照します。各アイテムについて、この関数では
skuをcountが1の新規オブジェクトvalue、および注文アイテムのqtyとと関連付け、sku(keyに格納)とvalueを出力します。
var mapFunction2 = function() { for (var idx = 0; idx < this.items.length; idx++) { var key = this.items[idx].sku; var value = { count: 1, qty: this.items[idx].qty }; emit(key, value); } }; 2つの引数
keySKUとcountObjValsを使用して、対応する reduce 関数を定義します。countObjValsは、map 関数によって reducer 関数に渡される、グループ化されたkeySKU値にマップされたオブジェクトを要素とする配列です。この関数は
countObjVals配列をcountフィールドとqtyフィールドを含む 1 つのオブジェクトreducedValueに縮小します。reducedValでは、countフィールドには個々の配列エレメントのcountフィールドの合計が含まれ、qtyフィールドには個々の配列エレメントのqtyフィールドの合計が含まれます。
var reduceFunction2 = function(keySKU, countObjVals) { reducedVal = { count: 0, qty: 0 }; for (var idx = 0; idx < countObjVals.length; idx++) { reducedVal.count += countObjVals[idx].count; reducedVal.qty += countObjVals[idx].qty; } return reducedVal; }; 2 つの引数
keyとreducedValを持つ finalize 関数を定義します。この関数は、reducedValオブジェクトを変更してavgという名前の計算フィールドを追加し、変更されたオブジェクトを返します。var finalizeFunction2 = function (key, reducedVal) { reducedVal.avg = reducedVal.qty/reducedVal.count; return reducedVal; }; ordersコレクションに対して map-reduce 操作を実行するには、mapFunction2、reduceFunction2、およびfinalizeFunction2関数を使用します。db.orders.mapReduce( mapFunction2, reduceFunction2, { out: { merge: "map_reduce_example2" }, query: { ord_date: { $gte: new Date("2020-03-01") } }, finalize: finalizeFunction2 } ); この操作では、
queryフィールドを使用して、ord_dateの値がnew Date("2020-03-01")以上のドキュメントのみを選択します。次に、結果をコレクションmap_reduce_example2に出力します。map_reduce_example2コレクションがすでに存在する場合、この操作により、内容が map-reduce 操作の結果に置き換えられます。つまり既存のドキュメントが新しい結果と同じキーを持っている場合、操作によって既存のドキュメントが上書きされます。同じキーを持つ既存のドキュメントが存在しない場合は、この操作によってドキュメントが挿入されます。map_reduce_example2コレクションをクエリして、結果を検証します。db.map_reduce_example2.find().sort( { _id: 1 } ) この操作では、次のドキュメントが返されます。
{ "_id" : "apples", "value" : { "count" : 4, "qty" : 35, "avg" : 8.75 } } { "_id" : "carrots", "value" : { "count" : 2, "qty" : 15, "avg" : 7.5 } } { "_id" : "chocolates", "value" : { "count" : 3, "qty" : 15, "avg" : 5 } } { "_id" : "oranges", "value" : { "count" : 7, "qty" : 63, "avg" : 9 } } { "_id" : "pears", "value" : { "count" : 1, "qty" : 10, "avg" : 10 } }
集計の代替手段
次のとおり利用可能な集約パイプライン演算子を使用すると、カスタム関数を定義しなくても map-reduce 操作を書き換えることができます。
db.orders.aggregate( [ { $match: { ord_date: { $gte: new Date("2020-03-01") } } }, { $unwind: "$items" }, { $group: { _id: "$items.sku", qty: { $sum: "$items.qty" }, orders_ids: { $addToSet: "$_id" } } }, { $project: { value: { count: { $size: "$orders_ids" }, qty: "$qty", avg: { $divide: [ "$qty", { $size: "$orders_ids" } ] } } } }, { $merge: { into: "agg_alternative_3", on: "_id", whenMatched: "replace", whenNotMatched: "insert" } } ] )
$matchステージでは、ord_dateがnew Date("2020-03-01")以上であるドキュメントのみが選択されます。$unwindステージでは、items配列フィールドでドキュメントを分割して、配列要素ごとにドキュメントを出力します。たとえば:{ "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "apples", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "oranges", "qty" : 8, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "pears", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 4, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-18T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 5, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-19T00:00:00Z"), "price" : 50, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } ... $groupステージでは各 SKU について計算し、items.skuでグループ化します。qtyフィールド。qtyフィールドには次が含まれます。- 各
items.skuごとに注文されたqtyの合計($sumを参照)。
orders_ids配列。orders_idsフィールドには次が含まれます。items.skuについての、個別の注文の_id($addToSetを参照してください)。
{ "_id" : "chocolates", "qty" : 15, "orders_ids" : [ 2, 5, 8 ] } { "_id" : "oranges", "qty" : 63, "orders_ids" : [ 4, 7, 3, 2, 9, 1, 10 ] } { "_id" : "carrots", "qty" : 15, "orders_ids" : [ 6, 9 ] } { "_id" : "apples", "qty" : 35, "orders_ids" : [ 9, 8, 1, 6 ] } { "_id" : "pears", "qty" : 10, "orders_ids" : [ 3 ] } $unwindステージでは、items配列フィールドでドキュメントを分割して、配列要素ごとにドキュメントを出力します。たとえば:{ "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "apples", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "oranges", "qty" : 8, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "pears", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 4, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-18T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 5, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-19T00:00:00Z"), "price" : 50, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } ... $groupステージでは各 SKU について計算し、items.skuでグループ化します。qtyフィールド。qtyフィールドには、$sumにより、各items.skuごとに注文されたqtyの合計が含まれます。orders_ids配列。orders_idsフィールドには、$addToSetにより、items.skuについての個別の注文_idの配列が含まれます。
{ "_id" : "chocolates", "qty" : 15, "orders_ids" : [ 2, 5, 8 ] } { "_id" : "oranges", "qty" : 63, "orders_ids" : [ 4, 7, 3, 2, 9, 1, 10 ] } { "_id" : "carrots", "qty" : 15, "orders_ids" : [ 6, 9 ] } { "_id" : "apples", "qty" : 35, "orders_ids" : [ 9, 8, 1, 6 ] } { "_id" : "pears", "qty" : 10, "orders_ids" : [ 3 ] } $projectステージでは、出力ドキュメントを再形成して、map-reduce の出力をミラーリングし、2 つのフィールド_idとvalueを含めます。$projectセット:$sizeを使用して、value.countをorders_ids配列のサイズに合わせます入力ドキュメントの
qtyフィールドについてのvalue.qty。
{ "_id" : "apples", "value" : { "count" : 4, "qty" : 35, "avg" : 8.75 } } { "_id" : "pears", "value" : { "count" : 1, "qty" : 10, "avg" : 10 } } { "_id" : "chocolates", "value" : { "count" : 3, "qty" : 15, "avg" : 5 } } { "_id" : "oranges", "value" : { "count" : 7, "qty" : 63, "avg" : 9 } } { "_id" : "carrots", "value" : { "count" : 2, "qty" : 15, "avg" : 7.5 } } 最後に、
$mergeは出力をコレクションagg_alternative_3に書き込みます。既存のドキュメントに新しい結果と同じキー_idがある場合、この操作によって既存のドキュメントが上書きされます。 同じキーを持つ既存のドキュメントが存在しない場合は、この操作によってドキュメントが挿入されます。agg_alternative_3コレクションをクエリして、結果を検証します。db.agg_alternative_3.find().sort( { _id: 1 } ) この操作により、次のドキュメントが返されます。
{ "_id" : "apples", "value" : { "count" : 4, "qty" : 35, "avg" : 8.75 } } { "_id" : "carrots", "value" : { "count" : 2, "qty" : 15, "avg" : 7.5 } } { "_id" : "chocolates", "value" : { "count" : 3, "qty" : 15, "avg" : 5 } } { "_id" : "oranges", "value" : { "count" : 7, "qty" : 63, "avg" : 9 } } { "_id" : "pears", "value" : { "count" : 1, "qty" : 10, "avg" : 10 } }
Tip
カスタム集計式を使用する代替方法については、「Map-Reduceから集約パイプラインへの変換例」を参照してください。
出力
The output of the db.collection.mapReduce() method is identical to that of the mapReduce command. See the Output section of the mapReduce command for information on the db.collection.mapReduce() output.
制限事項
db.collection.mapReduce() no longer supports afterClusterTime. As such, db.collection.mapReduce() cannot be associatd with causally consistent sessions.
詳細情報
mapReduceコマンド