MongoDB聚合运算符:$sum
文章目录
$sum
聚合运算符返回数值的合计值,计算式
$sum
会忽略非数值的值。
$sum
适用于以下阶段:
$addFields
阶段(从MongoDB3.4开始支持)$bucket
阶段$budketAuto
阶段$group
阶段$match
阶段的$expr
表达式$replaceRoot
阶段(从MongoDB3.4开始支持)$replaceWith
阶段(从MongoDB4.2开始支持)$set
阶段(从MongoDB4.2开始支持)$setWindowFields
阶段(从MongoDB5.0开始支持)
语法
当$sum
用作累加器时,语法为:
{
$sum: <expression> }
当$sum
用于非累加器时,语法为:
{
$sum: [ <expression1>, <expression2> ... ] }
使用
返回的数据类型
结果将与输入具有相同的类型,除非无法用该类型准确表示,在这些情况下:
- 如果结果可表示为64位整数,则32位整数将转换为64位整数。
- 如果结果无法表示为64位整数,则32位整数将转换为双精度型。
- 如果结果不能表示为64位整数,则64位整数将转换为double。
非数值或缺失字段的处理
- 如果用于同时包含数字值和非数字值的字段,
$sum
忽略非数字值并返回数字值的总和。 - 如果用于集合中任何文档中都不存在的字段,则
$sum
会为该字段返回0
。 - 如果所有操作数都是非数字,则
$sum
返回0
。
数组操作数
在$group
阶段,如果表达式解析为数组,$sum
会将操作数视为非数字值,对于其他支持的阶段:
- 当使用单个表达式作为操作数,如果表达式解析为数组,则
$sum
会遍历数组,对数字元素进行操作,返回累加值。 - 当使用表达式列表作为操作数,如果表达式解析为数组,
$sum
不会遍历数组,而是将数组视为非数字值。
举例
应用于$group
阶段
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") }
下面的聚合根据date
字段的日和年对文档进行分组,使用$sum
累加器计算每组文档的总金额和计数:
db.sales.aggregate(
[
{
$group:
{
_id: {
day: {
$dayOfYear: "$date"}, year: {
$year: "$date" } },
totalAmount: {
$sum