AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

mapReduce(データベースコマンド)

注意

map-reduce の代替としての集計パイプライン

MongoDB 5.0 以降、map-reduce は非推奨になっています。

  • map-reduceの代わりに、集計パイプラインを使用する必要があります。 集計パイプラインは、map-reduce よりもパフォーマンスとユーザビリティが優れています。

  • map-reduce 操作は、$group$merge などの集計パイプライン ステージ を使用して書き換えることができます。

  • カスタム機能を必要とする map-reduce 操作には、 $accumulator$functionの集計演算子を使用できます。 これらの演算子を使用して、JavaScript でカスタム集計式を定義できます。

map-reduce を集計パイプラインに置き換える例については、以下を参照してください。

mapReduce

コレクションに対してmap-reduce集計操作を実行します。

Tip

In mongosh, this command can also be run through the mapReduce() helper method.

Helper methods are convenient for mongosh users, but they may not return the same level of information as database commands. In cases where the convenience is not needed or the additional return fields are required, use the database command.

このコマンドは、次の環境でホストされている配置で使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のための完全管理サービスです

重要

このコマンドは、M0 および Flex クラスターではサポートされていません。詳細については、サポートされていないコマンド を参照してください。

  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

注意

MongoDB は冗長オプションを無視します。

MongoDB バージョン 4.2 以降、次の機能が廃止されます。

このコマンドの構文は、次のとおりです。

db.runCommand(
{
mapReduce: <string>,
map: <string or JavaScript>,
reduce: <string or JavaScript>,
finalize: <string or JavaScript>,
out: <output>,
query: <document>,
sort: <document>,
limit: <number>,
scope: <document>,
jsMode: <boolean>,
verbose: <boolean>,
bypassDocumentValidation: <boolean>,
collation: <document>,
maxTimeMS: <integer>,
writeConcern: <document>,
comment: <any>
}
)

コマンドは、次のフィールドを引数として受け取ります。

フィールド
タイプ
説明

string

map-reduce を実行するコレクションの名前。このコレクションは、map 関数によって処理される前に query を使用してフィルターされます。

ビューでは map-reduce 操作をサポートしていません。

javascript または文字列

valuekey に関連付けたり「マッピング」したり、key と値 pair 値を出力したりする JavaScript 関数。関数は、BSON 型JavaScript(BSON 型 13)または文字列(BSON 型 2)として指定できます。

For more information, see Requirements for the map Function.

javascript または文字列

特定のkeyに関連付けられているすべてのvaluesを 1 つのオブジェクトに「reduce」する JavaScript 関数。 関数は、 BSON型JavaScript ( BSON型 13)またはstring ( BSON型 2)として指定できます。

For more information, see Requirements for the reduce Function.

文字列またはドキュメント

map-reduce 操作の結果を出力する場所を指定します。 コレクションに出力することも、結果をインラインで返すこともできます。 レプリカセットのプライマリでは、コレクションまたはインラインでの出力が可能ですが、セカンダリでは、インライン出力のみが可能です。

For more information, see out Options.

ドキュメント

任意。map 関数への入力ドキュメントを決定するための選択基準をクエリ演算子を使用して指定します。

ドキュメント

任意。入力ドキュメントを並べ替えます。例えば、sort キーを emit キーと同じものに指定すると、reduce 操作の数を減らせます。sort キーは、このコレクションの既存のインデックス内になければなりません。

数値

任意。map 関数に入力するドキュメントの最大数を指定します。

javascript または文字列

任意。 reduce関数の後の出力を変更する JavaScript 関数。 関数は、 BSON型JavaScript ( BSON型 13)またはstring ( BSON型 2)として指定できます。

For more information, see Requirements for the finalize Function.

ドキュメント

任意.mapreducefinalize 関数で使用可能なグローバル変数を指定します。

ブール値

任意。map 関数と reduce 関数の実行の間に中間データを BSON 形式に変換するかどうかを指定します。

デフォルトは false です。

false場合:

  • MongoDB は内部的に、 map関数によって出力された JavaScript オブジェクトを BSON オブジェクトに変換します。 これらの BSON オブジェクトは、 reduce関数を呼び出すときに JavaScript オブジェクトに変換されます。

  • map-reduce 操作は、中間 BSON オブジェクトを一時的なディスク上のストレージに配置します。 これにより、任意の大きなデータセットに対して map-reduce 操作を実行できます。

true場合:

  • 内部的には、 map関数中に発行される JavaScript オブジェクトは JavaScript オブジェクトとして残ります。 reduce関数のオブジェクトを変換する必要がないため、実行が高速化します。

  • jsModeは、マッパーのemit()関数への個別のkey引数が 500,000 未満の結果セットにのみ使用できます。

ブール値

任意。結果情報に timing 情報を含めるかどうかを指定します。verbosetrue に設定して、timing 情報を含めます。

デフォルトは false です。

This option is ignored. The result information always excludes the timing information. You can view timing information by running explain with the mapReduce command in the "executionStats" or "allPlansExecution" verbosity modes.

ブール値

Optional. Enables mapReduce to bypass schema validation during the operation. This lets you insert documents that do not meet the validation requirements.

If the output option is set to inline, no schema validation occurs. If the output goes to a collection, mapReduce observes any validation rules which the collection has and does not insert any invalid documents unless the bypassDocumentValidation parameter is set to true.

ドキュメント

任意。

任意。操作に使用する照合を指定します。

照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。

照合オプションの構文は次のとおりです。

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

照合を指定する場合、locale フィールドは必須ですが、その他の照合フィールドはすべて任意です。フィールドの説明については、照合ドキュメントを参照してください。

照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合(db.createCollection() を参照)には、コレクションの照合が使用されます。

コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。

1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。

maxTimeMS

non-negative integer

任意。

時間制限をミリ秒単位で指定します。maxTimeMS の値を指定しない場合、操作はタイムアウトしません。値を 0 にすると、デフォルトの無制限動作を明示的に指定します。

MongoDB は、db.killOp() と同じメカニズムを使用して、割り当てられた時間制限を超えた操作を終了します。MongoDB は、指定された割り込みポイントのいずれかでのみ操作を終了します。

ドキュメント

任意.コレクションに出力する際に使用する書込み保証 (write concern)を指定します。デフォルトの書込み保証 (write concern) を使用する場合は省略します。

comment

any

任意。このコマンドに添付するユーザー指定のコメント。設定すると、このコメントは以下の場所にこのコマンドの記録と合わせて表示されます。

コメントには、有効な BSON 型(string, integer, object, array など)を使用できます。

The following is a prototype usage of the mapReduce command:

var mapFunction = function() { ... };
var reduceFunction = function(key, values) { ... };
db.runCommand(
{
mapReduce: <input-collection>,
map: mapFunction,
reduce: reduceFunction,
out: { merge: <output-collection> },
query: <query>
}
)

注意

MongoDB の JavaScript

Although mapReduce uses JavaScript, most interactions with MongoDB do not use JavaScript but use an idiomatic driver in the language of the interacting application.

map関数は、各入力ドキュメントを 0 個以上のドキュメントに変換するのを担当します。 scopeパラメータで定義された変数にアクセスでき、次のプロトタイプがあります。

function() {
...
emit(key, value);
}

map関数には次の要件があります。

  • map関数は、関数内で現在のドキュメントをthisとして参照します。

  • map関数は、何らかの理由で データベースにアクセスしてはなりません

  • map関数は純粋で、関数の外部に影響を与えないようにする必要があります( 副作用はありません。)

  • map関数は任意に、任意の回数でemit(key,value)を呼び出して、 keyvalueに関連付ける出力ドキュメントを作成できます。

次の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関数のプロトタイプは次のとおりです。

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 ] )

finalize関数のプロトタイプは次のとおりです。

function(key, reducedValue) {
...
return modifiedObject;
}

finalize関数は、引数としてkey値とreduce関数からのreducedValueを受け取ります。 注意すること:

  • finalize関数は、何らかの理由で データベースにアクセスしてはなりません

  • finalize関数は純粋で、関数の外部に影響を与えないようにする必要があります( 副作用はありません。)

  • finalize関数は、 scopeパラメータで定義された変数にアクセスできます。

outパラメータには次のオプションを指定できます。

このオプションは新しいコレクションに出力し、レプリカセットのセカンダリ ノードでは使用できません。

out: <collectionName>

注意

MongoDB バージョン 4.2 以降、次の機能が廃止されます。

  • The map-reduce option to create a new sharded collection as well as the use of the sharded option for map-reduce. To output to a sharded collection, create the sharded collection first. MongoDB 4.2 also deprecates the replacement of an existing sharded collection.

このオプションは、すでに存在するコレクションを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 }

結果はBSON ドキュメントの最大サイズ内に収まる必要があります。

If your MongoDB deployment enforces authentication, the user executing the mapReduce command must possess the following privilege actions:

{out : inline}出力オプションを使用した map-reduce の例:

コレクションに出力するときに、 replaceアクションを使用して map-reduce を実行します。

コレクションに出力するときに、 mergeまたはreduceアクションを使用して map-reduce を実行します。

readWrite組み込みロール は、map-reduce 集計を実行するために必要な権限を提供します。

The mapReduce command no longer supports afterClusterTime. As such, mapReduce cannot be associated with causally consistent sessions.

In mongosh, the db.collection.mapReduce() method is a wrapper around the mapReduce command. The following examples use the db.collection.mapReduce() method:

このセクションの例には、カスタム集計式を使用しない集計パイプラインの代替手段が含まれています。カスタム式を使用する代替方法については「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_idprice の合計値を計算します。

  1. 各入力ドキュメントを処理する map 関数を定義します。

    • この関数では、 this は map-reduce 操作で処理中のドキュメントを参照します。

    • この関数は、各ドキュメントのpricecust_idにマッピングし、 cust_idpriceを出力します。

    var mapFunction1 = function() {
    emit(this.cust_id, this.price);
    };
  2. 2つの引数keyCustIdvaluesPricesを使用して、対応する reduce 関数を定義します。

    • valuesPricesは、map 関数によって出力され、keyCustIdでグループ化された price 値を要素とする配列です。

    • この関数は valuesPrice 配列をその要素の合計にまで減らします。

    var reduceFunction1 = function(keyCustId, valuesPrices) {
    return Array.sum(valuesPrices);
    };
  3. orders コレクション内のすべてのドキュメントに対して、map 関数 mapFunction1 と reduce 関数reduceFunction1 を使用して map-reduce を実行します。

    db.orders.mapReduce(
    mapFunction1,
    reduceFunction1,
    { out: "map_reduce_example" }
    )

    この操作は、結果をmap_reduce_exampleという名前のコレクションに出力します。map_reduce_exampleコレクションがすでに存在する場合、この操作により、内容が map-reduce 操作の結果に置き換えられます。

  4. 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" }
])
  1. $groupステージはcust_idでグループ化し、 valueフィールドを計算します($sumも参照してください)。value フィールドには、各cust_idの合計priceが含まれます。

    このステージでは、次のドキュメントを次のステージに出力します。

    { "_id" : "Don Quis", "value" : 155 }
    { "_id" : "Ant O. Knee", "value" : 95 }
    { "_id" : "Cam Elot", "value" : 60 }
    { "_id" : "Busby Bee", "value" : 125 }
  2. 次に、 $outにより出力がコレクションagg_alternative_1に書き込まれます。あるいは、 $out の代わりに$mergeを使用することもできます

  3. 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 操作を示します。

この例での操作は次のとおりです。

  1. item.skuフィールドでグループ化し、各 sku の注文数と合計注文数量を計算します。

  2. sku値について、1 回の注文あたりの平均数量を計算し、結果を出力コレクションにマージします。

結果をマージするときに、既存のドキュメントが新しい結果と同じキーを持っている場合、操作によって既存のドキュメントが上書きされます。同じキーを持つ既存のドキュメントが存在しない場合は、この操作によってドキュメントが挿入されます。

手順の例:

  1. 各入力ドキュメントを処理する map 関数を定義します。

    • この関数では、 this は map-reduce 操作で処理中のドキュメントを参照します。

    • 各アイテムについて、この関数では skucount1 の新規オブジェクト value 、および注文アイテムの qty とと関連付け、skukeyに格納)と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. 2つの引数keySKUcountObjValsを使用して、対応する 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;
    };
  3. 2 つの引数keyreducedValを持つ finalize 関数を定義します。この関数は、 reducedValオブジェクトを変更してavgという名前の計算フィールドを追加し、変更されたオブジェクトを返します。

    var finalizeFunction2 = function (key, reducedVal) {
    reducedVal.avg = reducedVal.qty/reducedVal.count;
    return reducedVal;
    };
  4. orders コレクションに対して map-reduce 操作を実行するには、mapFunction2reduceFunction2、および 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 操作の結果に置き換えられます。つまり既存のドキュメントが新しい結果と同じキーを持っている場合、操作によって既存のドキュメントが上書きされます。同じキーを持つ既存のドキュメントが存在しない場合は、この操作によってドキュメントが挿入されます。

  5. 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" } }
] )
  1. $matchステージでは、 ord_datenew Date("2020-03-01")以上であるドキュメントのみが選択されます。

  2. $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" }
    ...
  3. $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 ] }
  4. $projectステージでは、出力ドキュメントを再形成して、map-reduce の出力をミラーリングし、2 つのフィールド_idvalueを含めます。$projectセット:

  5. $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" }
    ...
  6. $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 ] }
  7. $projectステージでは、出力ドキュメントを再形成して、map-reduce の出力をミラーリングし、2 つのフィールド_idvalueを含めます。$projectセット:

    • $size を使用して、 value.countorders_ids配列のサイズに合わせます

    • 入力ドキュメントの qty フィールドについてのvalue.qty

    • $divide$sizeを使用して、 value.avgを注文あたりの平均数量に換算します。

    { "_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 } }
  8. 最後に、 $mergeは出力をコレクションagg_alternative_3に書き込みます。既存のドキュメントに新しい結果と同じキー_idがある場合、この操作によって既存のドキュメントが上書きされます。 同じキーを持つ既存のドキュメントが存在しない場合は、この操作によってドキュメントが挿入されます。

  9. 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から集約パイプラインへの変換例」を参照してください。

詳細と例については、「 map-reduceページ 」および「 map-reduce の増分実行 」を参照してください

If you set the out parameter to write the results to a collection, the mapReduce command returns a document in the following form:

{ "result" : "map_reduce_example", "ok" : 1 }

If you set the out parameter to output the results inline, the mapReduce command returns a document in the following form:

{
"results" : [
{
"_id" : <key>,
"value" :<reduced or finalizedValue for key>
},
...
],
"ok" : <int>
}
mapReduce.result

コレクションに送信される出力の場合、この値は次のいずれかになります。

mapReduce.results

インラインで書き込まれた出力の場合、結果ドキュメントの配列。 結果の各ドキュメントには 2 つのフィールドが含まれています。

  • _id フィールドにはkey値が含まれており、

  • value フィールドには、関連付けられたkeyの減少または確定された値が含まれます。

mapReduce.ok

A value of 1 indicates the mapReduce command ran successfully. A value of 0 indicates an error.

上記のコマンド固有の戻りフィールドに加えて、 db.runCommand()には追加情報が含まれます。

  • レプリカ セットの場合、 $clusterTimeoperationTime

  • シャーディングされたクラスターの場合、operationTimeおよび$clusterTime

これらのフィールドの詳細については db.runCommand レスポンスを参照してください。