定義
- $reduce
- 配列内の各要素に式を適用し、それらを 1 つの値に結合します。 - $reduceの構文は次のとおりです。- { - $reduce: { - input: <array>, - initialValue: <expression>, - in: <expression> - } - } フィールドタイプ説明- input- 配列 - 配列に変換される有効な式であればどれでもかまいません。 式の詳細については、「式 」を参照してください。 - 引数が - nullの値に解決されるか、欠落しているフィールドを参照する場合、- $reduce- nullは を返します。- 引数が配列または - nullに解決されず、欠落しているフィールドを参照しない場合は、- $reduceはエラーを返します。- initialValue- 式 - inの前に設定された最初の推計- valueは、- input配列の最初の要素に適用されます。- in- 式 - input配列で、左から右へそれぞれの要素に- $reduceを適用する有効な式。- input値を- $reverseArrayでラップすると、結合式を右から左に適用するのと同じ結果が得られます。- in式の評価では 2 つの変数が利用可能です。- inputが空の配列に解決された場合、- $reduceは- initialValueを返します。
| 例 | 結果 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|  | 
 | ||||||||||
|  | 
 | ||||||||||
|  | 
 | 
例
乗算
確率
events という名前のコレクションには、確率実験のイベントが含まれています。各実験には、目的の結果を得るためにサイコロを複数回振ったり、カードを複数回(交換せずに)連続して引いたりするなど、複数の events が含まれる場合があります。実験の全体的な確率を取得するには、実験内の各イベントの確率を掛け合わせる必要があります。
db.events.insertMany( [    { _id : 1, type : "die", experimentId :"r5", description : "Roll a 5", eventNum : 1, probability : 0.16666666666667 },    { _id : 2, type : "card", experimentId :"d3rc", description : "Draw 3 red cards", eventNum : 1, probability : 0.5 },    { _id : 3, type : "card", experimentId :"d3rc", description : "Draw 3 red cards", eventNum : 2, probability : 0.49019607843137 },    { _id : 4, type : "card", experimentId :"d3rc", description : "Draw 3 red cards", eventNum : 3, probability : 0.48 },    { _id : 5, type : "die", experimentId :"r16", description : "Roll a 1 then a 6", eventNum : 1, probability : 0.16666666666667 },    { _id : 6, type : "die", experimentId :"r16", description : "Roll a 1 then a 6", eventNum : 2, probability : 0.16666666666667 },    { _id : 7, type : "card", experimentId :"dak", description : "Draw an ace, then a king", eventNum : 1, probability : 0.07692307692308 },    { _id : 8, type : "card", experimentId :"dak", description : "Draw an ace, then a king", eventNum : 2, probability : 0.07843137254902 } ] ) 
手順:
- $groupを使用して- experimentIdでグループ化し、- $pushを使用して各イベントの確率を含む配列を作成します。
- $reduceと- $multiplyを使用して、- probabilityArrの要素を乗算して単一の値に結合し、それを出力します。
db.probability.aggregate(   [     {       $group: {         _id: "$experimentId",         probabilityArr: { $push: "$probability" }       }     },     {       $project: {         description: 1,         results: {           $reduce: {             input: "$probabilityArr",             initialValue: 1,             in: { $multiply: [ "$$value", "$$this" ] }           }         }       }     }   ] ) 
この操作では、以下を返します。
{ _id : "dak", results : 0.00603318250377101 } { _id : "r5", results : 0.16666666666667 } { _id : "r16", results : 0.027777777777778886 } { _id : "d3rc", results : 0.11764705882352879 } 
割引商品
clothes という名前のコレクションには次のドキュメントが含まれています。
db.clothes.insertMany( [    { _id : 1, productId : "ts1", description : "T-Shirt", color : "black", size : "M", price : 20, discounts : [ 0.5, 0.1 ] },    { _id : 2, productId : "j1", description : "Jeans", color : "blue", size : "36", price : 40, discounts : [ 0.25, 0.15, 0.05 ] },    { _id : 3, productId : "s1", description : "Shorts", color : "beige", size : "32", price : 30, discounts : [ 0.15, 0.05 ] },    { _id : 4, productId : "ts2", description : "Cool T-Shirt", color : "White", size : "L", price : 25, discounts : [ 0.3 ] },    { _id : 5, productId : "j2", description : "Designer Jeans", color : "blue", size : "30", price : 80, discounts : [ 0.1, 0.25 ] } ] ) 
各ドキュメントには、各商品で現在利用可能な割引クーポンを含む discounts 配列が含まれています。各割引率を製品に 1 回適用できる場合は、$reduce を使用して discounts 配列の各要素に (1-割引率) * 価格の式を適用することで、最低価格を計算できます。
db.clothes.aggregate(   [     {       $project: {         discountedPrice: {           $reduce: {             input: "$discounts",             initialValue: "$price",             in: { $multiply: [ "$$value", { $subtract: [ 1, "$$this" ] } ] }           }         }       }     }   ] ) 
この操作では、以下を返します。
{ _id : ObjectId("57c893067054e6e47674ce01"), discountedPrice : 9 } { _id : ObjectId("57c9932b7054e6e47674ce12"), discountedPrice : 24.224999999999998 } { _id : ObjectId("57c993457054e6e47674ce13"), discountedPrice : 24.224999999999998 } { _id : ObjectId("57c993687054e6e47674ce14"), discountedPrice : 17.5 } { _id : ObjectId("57c993837054e6e47674ce15"), discountedPrice : 54 } 
文字列の連結
people という名前のコレクションには次のドキュメントが含まれています。
db.people.insertMany( [    { _id : 1, name : "Melissa", hobbies : [ "softball", "drawing", "reading" ] },    { _id : 2, name : "Brad", hobbies : [ "gaming", "skateboarding" ] },    { _id : 3, name : "Scott", hobbies : [ "basketball", "music", "fishing" ] },    { _id : 4, name : "Tracey", hobbies : [ "acting", "yoga" ] },    { _id : 5, name : "Josh", hobbies : [ "programming" ] },    { _id : 6, name : "Claire" } ] ) 
次の例では、文字列の配列 hobbies を単一の文字列 bio に縮小します。
db.people.aggregate(    [      // Filter to return only non-empty arrays      { $match: { "hobbies": { $gt: [ ] } } },      {        $project: {          name: 1,          bio: {            $reduce: {              input: "$hobbies",              initialValue: "My hobbies include:",              in: {                $concat: [                  "$$value",                  {                    $cond: {                      if: { $eq: [ "$$value", "My hobbies include:" ] },                      then: " ",                      else: ", "                    }                  },                  "$$this"                ]              }            }          }        }      }    ] ) 
この操作では、以下を返します。
{ _id : 1, name : "Melissa", bio : "My hobbies include: softball, drawing, reading" } { _id : 2, name : "Brad", bio : "My hobbies include: gaming, skateboarding" } { _id : 3, name : "Scott", bio : "My hobbies include: basketball, music, fishing" } { _id : 4, name : "Tracey", bio : "My hobbies include: acting, yoga" } { _id : 5, name : "Josh", bio : "My hobbies include: programming" } 
配列の連結
matrices という名前のコレクションには次のドキュメントが含まれています。
db.matrices.insertMany( [    { _id : 1, arr : [ [ 24, 55, 79 ], [ 14, 78, 35 ], [ 84, 90, 3 ], [ 50, 89, 70 ] ] },    { _id : 2, arr : [ [ 39, 32, 43, 7 ], [ 62, 17, 80, 64 ], [ 17, 88, 11, 73 ] ] },    { _id : 3, arr : [ [ 42 ], [ 26, 59 ], [ 17 ], [ 72, 19, 35 ] ] },    { _id : 4 } ] ) 
単一の削減の計算
次の例では、2 次元配列を 1 つの配列 collapsed に折りたたみます。
db.arrayconcat.aggregate(   [     {       $project: {         collapsed: {           $reduce: {             input: "$arr",             initialValue: [ ],             in: { $concatArrays: [ "$$value", "$$this" ] }           }         }       }     }   ] ) 
この操作では、以下を返します。
{ _id : 1, collapsed : [ 24, 55, 79, 14, 78, 35, 84, 90, 3, 50, 89, 70 ] } { _id : 2, collapsed : [ 39, 32, 43, 7, 62, 17, 80, 64, 17, 88, 11, 73 ] } { _id : 3, collapsed : [ 42, 26, 59, 17, 72, 19, 35 ] } { _id : 4, collapsed : null } 
多重削減の計算
次の例では、上の例と同じ 2 次元配列の削減を実行しますが、各配列の最初の要素のみを含む新しい配列も作成します。
db.arrayconcat.aggregate(   [     {       $project: {         results: {           $reduce: {             input: "$arr",             initialValue: [ ],             in: {               collapsed: {                 $concatArrays: [ "$$value.collapsed", "$$this" ]               },               firstValues: {                 $concatArrays: [ "$$value.firstValues", { $slice: [ "$$this", 1 ] } ]               }             }           }         }       }     }   ] ) 
この操作では、以下を返します。
{ _id : 1, results : { collapsed : [ 24, 55, 79, 14, 78, 35, 84, 90, 3, 50, 89, 70 ], firstValues : [ 24, 14, 84, 50 ] } } { _id : 2, results : { collapsed : [ 39, 32, 43, 7, 62, 17, 80, 64, 17, 88, 11, 73 ], firstValues : [ 39, 62, 17 ] } } { _id : 3, results : { collapsed : [ 42, 26, 59, 17, 72, 19, 35 ], firstValues : [ 42, 26, 17, 72 ] } } { _id : 4, results : null }