$sum (aggregation)
On this page本页内容
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:可在以下阶段使用:
$addFields
(Available starting in MongoDB 3.4)(从MongoDB 3.4开始提供)$bucket
$bucketAuto
$group
包含$match
stage that includes an$expr
expression$expr
表达式的$match
阶段$project
$replaceRoot
(Available starting in MongoDB 3.4)(从MongoDB 3.4开始提供)$replaceWith
(Available starting in MongoDB 4.2)(从MongoDB 4.2开始提供)$set
(Available starting in MongoDB 4.2)(从MongoDB 4.2开始提供)$setWindowFields
(Available starting in MongoDB 5.0)(从MongoDB 5.0开始提供)
In MongoDB 3.2 and earlier, 在MongoDB 3.2及更早版本中,$sum
is available in the $group
stage only.$sum
仅在$group
阶段可用。
Syntax语法
When used in the 在$bucket
, $bucketAuto
, $group
, and $setWindowFields
stages, $sum
has this syntax:$bucket
、$bucketAuto
、$group
和$setWindowFields
阶段中使用时,$sum
具有以下语法:
{ $sum: <expression> }
When used in other supported stages, 在其他支持的阶段中使用时,$sum
has one of two syntaxes:$sum
有两种语法之一:
$sum
has one specified expression as its operand:有一个指定的表达式作为其操作数:{ $sum: <expression> }
$sum
has a list of specified expressions as its operand:具有指定表达式的列表作为其操作数:{ $sum: [ <expression1>, <expression2> ... ] }
For more information on expressions, see Expressions.有关表达式的详细信息,请参阅表达式。
Behavior行为
Result Data Type结果数据类型
The result will have the same type as the input except when it cannot be represented accurately in that type. In these cases:结果将具有与输入相同的类型,除非无法在该类型中准确表示。在这些情况下:
A 32-bit integer will be converted to a 64-bit integer if the result is representable as a 64-bit integer.如果结果可以表示为64位整数,则32位整数将被转换为64位的整数。A 32-bit integer will be converted to a double if the result is not representable as a 64-bit integer.如果结果不能表示为64位整数,则32位整数将转换为双精度。A 64-bit integer will be converted to double if the result is not representable as a 64-bit integer.如果结果不能表示为64位整数,则64位整数将被转换为双。
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, 如果所有操作数都是非数字的,那么$sum
returns 0
.$sum
将返回0
。
Array Operand数组操作数
In the 在$group
stage, if the expression resolves to an array, $sum
treats the operand as a non-numerical value.$group
阶段,如果表达式解析为数组,$sum
会将操作数视为非数值。
In the other supported stages:在其他支持阶段:
With a single expression as its operand, if the expression resolves to an array,以单个表达式作为其操作数,如果表达式解析为数组,则$sum
traverses into the array to operate on the numerical 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,以表达式列表作为操作数,如果任何表达式解析为数组,$sum
does not traverse into the array but instead treats the array as a non-numerical value.$sum
不会遍历到数组中,而是将数组视为非数值。
Examples实例
Use in $group
Stage在$group
阶段中使用
$group
StageConsider a 考虑一个包含以下文档的sales
collection with the following documents:sales
集合:
{ "_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
. $sum
将返回值0
。The following operation attempts to 以下操作尝试对$sum
on qty
: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 }
。
See also: 另请参阅:
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
):CA
)和华盛顿州(WA
)蛋糕销售的cakeSales
系列:
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
.state
对集合中的文档进行分区。There are partitions forCA
andWA
.CA
和WA
有分区。sortBy: { orderDate: 1 }
sorts the documents in each partition by按orderDate
in ascending order (1
), so the earliestorderDate
is first.orderDate
按升序(1
)对每个分区中的文档进行排序,因此最早的orderDate
是第一个。
output
sets thesumQuantityForState
field to the sum of thequantity
values using$sum
that is run in a documents window.output
使用在文档窗口中运行的$sum
将sumQuantityForState
字段设置为quantity
值的总和。The window contains documents between an该窗口包含在unbounded
lower limit and thecurrent
document in the output.unbounded
下限和输出中的current
文档之间的文档。This means这意味着$sum
returns the sum of thequantity
values 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
的数量值之和显示在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 }