Definition定义
$sum
Changed in version 5.0.在版本5.0中的更改。
Calculates and returns the collective sum of numeric values. 计算并返回数值的总和。$sum ignores non-numeric values.$sum忽略非数值。
$sum is available in these stages:$sum在以下阶段可用:
$addFields$bucket$bucketAuto$group包含$matchstage that includes an$exprexpression$expr表达式的$match阶段$project$replaceRoot$replaceWith$set$setWindowFields(Available starting in MongoDB 5.0)(从MongoDB 5.0开始可用)
Compatibility兼容性
You can use 您可以将$sum for deployments hosted in the following environments:$sum用于在以下环境中托管的部署:
- MongoDB Atlas
: The fully managed service for MongoDB deployments in the cloud:云中MongoDB部署的完全托管服务
- MongoDB Enterprise
: The subscription-based, self-managed version of MongoDB:MongoDB的基于订阅的自我管理版本 - MongoDB Community
: The source-available, free-to-use, and self-managed version of MongoDB:MongoDB的源代码可用、免费使用和自我管理版本
Syntax语法
When used as an accumulator, 当用作累加器时,$sum has this syntax:$sum具有以下语法:
{ $sum: <expression> }
When not used as an accumulator, 当不作为累加器使用时,$sum has this syntax:$sum具有以下语法:
{ $sum: [ <expression1>, <expression2> ... ] }
For more information on expressions, see Expressions.有关表达式的详细信息,请参阅表达式。
Behavior行为
Result Data Type结果数据类型
When input types are mixed, 当输入类型混合时,$sum promotes the smaller input type to the larger of the two. A type is considered larger when it represents a wider range of values. The order of numeric types from smallest to largest is: $sum会将较小的输入类型升级为两者中较大的输入类型。当一个类型代表更宽的值范围时,它被认为更大。数字类型从最小到最大的顺序是:integer → long → double → decimal
The larger of the input types also determines the result type unless the operation overflows and is beyond the range represented by that larger data type. In cases of overflow, 较大的输入类型也决定了结果类型,除非操作溢出并且超出了较大数据类型表示的范围。在溢出的情况下,$sum promotes the result according to the following order:$sum会按照以下顺序提升结果:
If the larger input type is如果较大的输入类型是integer, the result type is promoted tolong.integer,则结果类型将提升为long。If the larger input type is如果较大的输入类型为long, the result type is promoted todouble.long,则结果类型将提升为double。If the larger type is如果较大的类型是doubleordecimal, the overflow result is represented as + or - infinity. There is no type promotion of the result.double或decimal,则溢出结果表示为+或-无穷大。结果没有类型推广。
Non-Numeric or Non-Existent Fields非数字或不存在字段
If used on a field that contains both numeric and non-numeric values, 如果在同时包含数值和非数值的字段上使用,$sum ignores the non-numeric values and returns the sum of the numeric values.$sum会忽略非数值,并返回数值的总和。
If used on a field that does not exist in any document in the collection, 如果用于集合中任何文档中都不存在的字段,$sum returns 0 for that field.$sum将为该字段返回0。
If all operands are non-numeric, non-arrays, or contain 如果所有操作数都是非数字、非数组或包含null values, $sum returns 0. For details on how $sum handles arrays, see Array Operand.null值,则$sum返回0。有关$sum如何处理数组的详细信息,请参阅数组运算数。
Array Operand数组运算数
In the 在$group stage, if the expression resolves to an array, $sum treats the operand as a non-numeric value.$group阶段,如果表达式解析为数组,$sum会将操作数视为非数值。
In the other supported stages:在其他支持的阶段:
With a single expression as its operand, if the expression resolves to an array,使用单个表达式作为操作数,如果表达式解析为数组,$sumtraverses into the array to operate on the numeric elements of the array to return a single value.$sum将遍历数组以对数组的数字元素进行操作,从而返回单个值。With a list of expressions as its operand, if any of the expressions resolves to an array,使用表达式列表作为操作数,如果任何表达式解析为数组,$sumdoes not traverse into the array but instead treats the array as a non-numeric value.$sum不会遍历到数组中,而是将数组视为非数值。
For example, when not used in a 例如,当不在$group stage:$group阶段使用时:
If the如果$sumoperand is[ 2, 2 ],$sumadds the array elements and returns 4.$sum操作数为[2,2],则$sum将数组元素相加并返回4。If the如果$sumoperand is[ 2, [ 3, 4 ] ],$sumreturns 2 because it treats the nested array[ 3, 4 ]as a non-numeric value.$sum操作数为[2,[3,4]],则$sum返回2,因为它将嵌套数组[3,4]视为非数值。
Examples示例
Use in $group Stage在$group阶段中使用
$group StageConsider a 考虑一个包含以下文件的销售集合:sales collection with the following documents:
db.sales.insertMany( [
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") },
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") },
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") },
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") },
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
] )
Grouping the documents by the day and the year of the 按date field, the following operation uses the $sum accumulator to compute the total amount and the count for each group of documents.date字段的日期和年份对文档进行分组,以下操作使用$sum累加器计算每组文档的总金额和计数。
db.sales.aggregate(
[
{
$group:
{
_id: { day: { $dayOfYear: "$date"}, year: { $year: "$date" } },
totalAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },
count: { $sum: 1 }
}
}
]
)
The operation returns the following results:该操作返回以下结果:
{ "_id" : { "day" : 46, "year" : 2014 }, "totalAmount" : 150, "count" : 2 }
{ "_id" : { "day" : 34, "year" : 2014 }, "totalAmount" : 45, "count" : 2 }
{ "_id" : { "day" : 1, "year" : 2014 }, "totalAmount" : 20, "count" : 1 }
Using 对不存在的字段使用$sum on a non-existent field returns a value of 0. The following operation attempts to $sum on qty:$sum将返回值0。以下操作尝试按qty计算$sum:
db.sales.aggregate(
[
{
$group:
{
_id: { day: { $dayOfYear: "$date"}, year: { $year: "$date" } },
totalAmount: { $sum: "$qty" },
count: { $sum: 1 }
}
}
]
)
The operation returns:操作返回:
{ "_id" : { "day" : 46, "year" : 2014 }, "totalAmount" : 0, "count" : 2 }
{ "_id" : { "day" : 34, "year" : 2014 }, "totalAmount" : 0, "count" : 2 }
{ "_id" : { "day" : 1, "year" : 2014 }, "totalAmount" : 0, "count" : 1 }
The $count aggregation accumulator can be used in place of { $sum : 1 } in the $group stage.$count聚合累加器可以用来代替$group阶段中的{ $sum : 1 }。
Use in $project Stage在$project阶段中使用
$project StageA collection students contains the following documents:students集合包含以下文档:
{ "_id": 1, "quizzes": [ 10, 6, 7 ], "labs": [ 5, 8 ], "final": 80, "midterm": 75 }
{ "_id": 2, "quizzes": [ 9, 10 ], "labs": [ 8, 8 ], "final": 95, "midterm": 80 }
{ "_id": 3, "quizzes": [ 4, 5, 5 ], "labs": [ 6, 5 ], "final": 78, "midterm": 70 }
The following example uses the 以下示例使用$sum in the $project stage to calculate the total quiz scores, the total lab scores, and the total of the final and the midterm:$project阶段中的$sum来计算测验总分、实验总分以及期末和期中考试的总分:
db.students.aggregate([
{
$project: {
quizTotal: { $sum: "$quizzes"},
labTotal: { $sum: "$labs" },
examTotal: { $sum: [ "$final", "$midterm" ] }
}
}
])
The operation results in the following documents:该操作产生了以下文件:
{ "_id" : 1, "quizTotal" : 23, "labTotal" : 13, "examTotal" : 155 }
{ "_id" : 2, "quizTotal" : 19, "labTotal" : 16, "examTotal" : 175 }
{ "_id" : 3, "quizTotal" : 14, "labTotal" : 11, "examTotal" : 148 }Use in $setWindowFields Stage在$setWindowFields阶段中使用
$setWindowFields StageNew in version 5.0.在版本5.0中新增。
Create a 创建一个cakeSales collection that contains cake sales in the states of California (CA) and Washington (WA):cakeSales集合,其中包含加利福尼亚州(CA)和华盛顿州(WA)的蛋糕销售:
db.cakeSales.insertMany( [
{ _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"),
state: "CA", price: 13, quantity: 120 },
{ _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"),
state: "WA", price: 14, quantity: 140 },
{ _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"),
state: "CA", price: 12, quantity: 145 },
{ _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"),
state: "WA", price: 13, quantity: 104 },
{ _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"),
state: "CA", price: 41, quantity: 162 },
{ _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"),
state: "WA", price: 43, quantity: 134 }
] )
This example uses 此示例在$sum in the $setWindowFields stage to output the sum of the quantity of cakes sold in each state:$setWindowFields阶段使用$sum来输出每个state销售的蛋糕quantity的总和:
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
sumQuantityForState: {
$sum: "$quantity",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
}
] )
In the example:在示例中:
partitionBy: "$state"partitions the documents in the collection by按state. There are partitions forCAandWA.state对集合中的文档进行分区。CA和WA有分区。sortBy: { orderDate: 1 }sorts the documents in each partition by按orderDatein ascending order (1), so the earliestorderDateis first.orderDate升序(1)对每个分区中的文档进行排序,因此最早的orderDate位居前列。
outputsets the使用在sumQuantityForStatefield to the sum of thequantityvalues using$sumthat is run in a documents window.documents窗口中运行的$sum将sumQuantityForState字段设置为quantity值的总和。The window contains documents between an该窗口包含的文档位于unboundedlower limit and thecurrentdocument in the output.unbounded下限和输出中的current文档之间。This means这意味着$sumreturns the sum of thequantityvalues for the documents between the beginning of the partition and the current document.$sum返回分区开始和当前文档之间的文档quantity值的总和。
In this output, the sum of the 在此输出中,quantity values for CA and WA is shown in the sumQuantityForState field:CA和WA的quantity值之和显示在sumQuantityForState字段中:
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162, "sumQuantityForState" : 162 }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120, "sumQuantityForState" : 282 }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145, "sumQuantityForState" : 427 }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134, "sumQuantityForState" : 134 }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104, "sumQuantityForState" : 238 }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140, "sumQuantityForState" : 378 }