Docs Menu
Docs Home
/
MongoDBマニュアル
/ / /

db.collection.mapReduce()

項目一覧

  • 互換性
  • 構文
  • 出力
  • 制限事項
  • 詳細情報

注意

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

MongoDB 5.0以降、 map-reduceは非推奨です。

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

db.collection.mapReduce(map,reduce, { <options> })

重要

mongosh メソッド

このページでは、mongosh メソッドについて説明します。ただし、データベースコマンドや Node.js などの言語固有のドライバーのドキュメントには該当しません

データベースコマンドについては、mapReduce コマンドを参照してください。

MongoDB API ドライバーについては、各言語の MongoDB ドライバー ドキュメントを参照してください。

注意

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

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

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです

重要

このコマンドは、M 0 、M 2 、M 5クラスターではサポートされていません。 詳細については、「サポートされていないコマンド 」を参照してください。

  • 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
タイプ
説明
map
javascript または文字列

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

詳細については、 map 関数の要件 を参照してください。

reduce
javascript または文字列

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

詳細については、「 reduce 関数の要件 」を参照してください。

options
ドキュメント
db.collection.mapReduce() に追加のパラメータを指定するドキュメント。

次の表では、db.collection.mapReduce() が受け入れることができる追加の引数について説明します。

フィールド
タイプ
説明
out
文字列またはドキュメント

map-reduce 操作の結果のロケーション所を指定します。コレクションに出力したり、アクションを使用してコレクションに出力したり、インラインで出力したりできます。セットのプライマリ ノードに対して map-reduce を実行するときにコレクションに出力できます。セカンダリ ノードでは、 inline 出力のみを使用できます。

詳細については、アウト オプションを参照してください。

query
ドキュメント
map 関数への入力ドキュメントを決定するための選択基準をクエリ演算子を使用して指定します。
sort
ドキュメント
入力ドキュメントを並べ替えます。このオプションは、最適化に役立ちます。たとえば、sort キーを emit キーと同じものに指定すると、reduce 操作の数を減らせます。sort キーは、このコレクションの既存のインデックス内になければなりません。
limit
数値
map 関数に入力するドキュメントの最大数を指定します。
finalize
javascript または文字列

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

詳細については、 finalize 関数の要件を参照してください。

scope
ドキュメント
mapreducefinalize 関数でアクセス可能なグローバル変数を指定します。
jsMode
ブール値

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 未満の結果セットにのみ使用できます。

verbose
ブール値

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

デフォルトは false です。

このオプションは無視されます。 結果情報には常に timing 情報が除外されます。モードまたはdb.collection.explain() db.collection.mapReduce()"executionStats""allPlansExecution"verbosityモードで とともに を実行中すると、タイミング情報を表示できます。

collation
ドキュメント

任意。

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

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

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

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

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

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

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

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

bypassDocumentValidation
ブール値
任意。mapReduce を有効にすると、操作中にドキュメント検証をバイパスできます。これにより、検証要件を満たさないドキュメントを挿入できるようになります。

注意

map-reduce operations および $where 演算子式は、mongosh 内で使用可能な db などの特定のグローバル関数またはプロパティにアクセスできません

次の JavaScript 関数とプロパティは、map-reduce operationsおよび$where 演算子の式で使用できます

利用可能なプロパティ
利用可能な機能
args
MaxKey
MinKey
assert()
BinData()
DBPointer()
DBRef()
doassert()
emit()
gc()
HexData()
hex_md5()
isNumber()
isObject()
ISODate()
isString()
Map()
MD5()
NumberInt()
NumberLong()
ObjectId()
print()
printjson()
printjsononeline()
sleep()
Timestamp()
tojson()
tojsononeline()
tojsonObject()
UUID()
version()

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

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 }

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

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

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

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

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

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

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

このセクションの例には、カスタム集計式を使用しない集計パイプラインの代替手段が含まれています。カスタム式を使用する代替方法については「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から集約パイプラインへの変換例」を参照してください。

db.collection.mapReduce()メソッドの出力はmapReduceコマンドの出力と同じです。 出力の詳細については、 mapReducedb.collection.mapReduce()コマンドの 出力 セクションを参照してください。

db.collection.mapReduce() afterClusterTime のサポートを終了しました。このため、db.collection.mapReduce()因果一貫性のあるセッションに関連付けることはできません。

戻る

db.collection.latencyStats