On this page本页内容
$reduce
Applies an expression to each element in an array and combines them into a single value.将表达式应用于数组中的每个元素,并将它们组合为单个值。
$reduce
has the following syntax:语法如下:
{ $reduce: { input: <array>, initialValue: <expression>, in: <expression> } }
input | array |
|
initialValue | expression | value set before in is applied to the first element of the input array.in 之前设置的初始累积value 将应用于input 数组的第一个元素。
|
in | expression |
|
If 如果input
resolves to an empty array, $reduce
returns initialValue
.input
解析为空数组,$reduce
将返回initialValue
。
{ $reduce: { input: ["a", "b", "c"], initialValue: "", in: { $concat : ["$$value", "$$this"] } } } | "abc" |
{ $reduce: { input: [ 1, 2, 3, 4 ], initialValue: { sum: 5, product: 2 }, in: { sum: { $add : ["$$value.sum", "$$this"] }, product: { $multiply: [ "$$value.product", "$$this" ] } } } } | { "sum" : 15, "product" : 48 } |
{ $reduce: { input: [ [ 3, 4 ], [ 5, 6 ] ], initialValue: [ 1, 2 ], in: { $concatArrays : ["$$value", "$$this"] } } } | [ 1, 2, 3, 4, 5, 6 ] |
A collection named 名为events
contains the events of a probability experiment. events
的集合包含概率实验的事件。Each experiment can have multiple 每个实验可以有多个events
, such as rolling a die several times or drawing several cards (without replacement)in succession to achieve a desired result. events
,例如滚动一个模具几次或连续绘制几张卡片(无需更换)以获得预期结果。In order to obtain the overall probability of the experiment, we will need to multiply the probability of each event in the experiment.为了获得实验的总体概率,我们需要乘以实验中每个事件的概率。
{_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}
Steps:
$group
to group by the experimentId
and use $push
to create an array with the probability of each event.$group
按experimentalId
分组,并使用$push
创建一个具有每个事件概率的数组。$reduce
with $multiply
to multiply and combine the elements of probabilityArr
into a single value and project it.$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" ] } } } } } ] )
The operation returns the following:运算结果如下:
{ "_id" : "dak", "results" : 0.00603318250377101 } { "_id" : "r5", "results" : 0.16666666666667 } { "_id" : "r16", "results" : 0.027777777777778886 } { "_id" : "d3rc", "results" : 0.11764705882352879 }
A collection named 名为clothes
contains the following documents:clothes
的集合包含以下文档:
{ "_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 ] }
Each document contains a 每个文档都包含一个discounts
array containing the currently available percent-off coupons for each item. discounts
数组,其中包含每个项目当前可用的折扣优惠券百分比。If each discount can be applied to the product once, we can calculate the lowest price by using 如果每个折扣可以应用于产品一次,我们可以使用$reduce
to apply the following formula for each element in the discounts
array: (1 - discount) * price.$reduce
为discounts
数组中的每个元素应用以下公式来计算最低价格:(1 - discount) * price
。
db.clothes.aggregate( [ { $project: { "discountedPrice": { $reduce: { input: "$discounts", initialValue: "$price", in: { $multiply: [ "$$value", { $subtract: [ 1, "$$this" ] } ] } } } } } ] )
The operation returns the following:运算结果如下:
{ "_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 }
A collection named 名为people
contains the following documents:people
的集合包含以下文档:
{ "_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" }
The following example reduces the 以下示例将字符串的hobbies
array of strings into a single string bio
: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" ] } } } } } ] )
The operation returns the following:运算结果如下:
{ "_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" }
A collection named 名为matrices
contains the following documents:matrix
的集合包含以下文档:
{ "_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 }
The following example collapses the two dimensional arrays into a single array 以下示例将二维数组收拢为单个数组collapsed
:collapsed
:
db.arrayconcat.aggregate( [ { $project: { "collapsed": { $reduce: { input: "$arr", initialValue: [ ], in: { $concatArrays: [ "$$value", "$$this" ] } } } } } ] )
The operation returns the following:运算结果如下:
{ "_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 }
The following example performs the same two dimensional array collapse as the example above, but also creates a new array containing only the first element of each array.下面的示例执行与上面的示例相同的二维数组折叠,但也创建一个仅包含每个数组的第一个元素的新数组。
db.arrayconcat.aggregate( [ { $project: { "results": { $reduce: { input: "$arr", initialValue: [ ], in: { "collapsed": { $concatArrays: [ "$$value.collapsed", "$$this" ] }, "firstValues": { $concatArrays: [ "$$value.firstValues", { $slice: [ "$$this", 1 ] } ] } } } } } } ] )
The operation returns the following:运算结果如下:
{ "_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 }