> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

# $sum (accumulator operator)

## Definition

**Changed in version 5.0**

Calculates and returns the collective sum of numeric values. [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) ignores non-numeric values.

[`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) is available in these stages:

- [`$addFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields.md#mongodb-pipeline-pipe.-addFields)

- [`$bucket`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucket.md#mongodb-pipeline-pipe.-bucket)

- [`$bucketAuto`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucketAuto.md#mongodb-pipeline-pipe.-bucketAuto)

- [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group)

- [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) stage that includes an [`$expr`](https://www.mongodb.com/docs/manual/reference/operator/query/expr.md#mongodb-query-op.-expr) expression

- [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project)

- [`$replaceRoot`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceRoot.md#mongodb-pipeline-pipe.-replaceRoot)

- [`$replaceWith`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceWith.md#mongodb-pipeline-pipe.-replaceWith)

- [`$set`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/set.md#mongodb-pipeline-pipe.-set)

- [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) (Available starting in MongoDB 5.0)

## Compatibility

You can use `$sum` for deployments hosted in the following environments:

- [MongoDB Atlas](https://www.mongodb.com/docs/atlas): The fully managed service for MongoDB deployments in the cloud

* [MongoDB Enterprise](https://www.mongodb.com/docs/manual/administration/install-enterprise.md#std-label-install-mdb-enterprise): The subscription-based, self-managed version of MongoDB

* [MongoDB Community](https://www.mongodb.com/docs/manual/administration/install-community.md#std-label-install-mdb-community-edition): The source-available, free-to-use, and self-managed version of MongoDB

## Syntax

When used as an [accumulator](https://www.mongodb.com/docs/manual/reference/mql/accumulators.md#std-label-agg-operators-group-accumulators), [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) has this syntax:

```none
{ $sum: <expression> }
```

When not used as an accumulator, [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) has this syntax:

```none
{ $sum: [ <expression1>, <expression2> ... ]  }
```

For more information on expressions, see [Expressions.](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-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: 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:

- If the larger input type is [`integer`](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json.md#mongodb-bsontype-Int32), the result type is promoted to [`long`.](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json.md#mongodb-bsontype-Int64)

- If the larger input type is [`long`](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json.md#mongodb-bsontype-Int64), the result type is promoted to [`double`.](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json.md#mongodb-bsontype-Double)

- If the larger type is [`double`](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json.md#mongodb-bsontype-Double) or [`decimal`](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json.md#mongodb-bsontype-Decimal128), the overflow result is represented as + or - infinity. There is no type promotion of the result.

### Non-Numeric or Non-Existent Fields

If used on a field that contains both numeric and non-numeric values, [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) ignores the non-numeric values and returns the sum of the numeric values.

If used on a field that does not exist in any document in the collection, [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) returns `0` for that field.

If all operands are non-numeric, non-arrays, or contain `null` values, [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) returns `0`. For details on how `$sum` handles arrays, see [Array Operand.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#std-label-sum-array-operand)

### Array Operand

In the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage, if the expression resolves to an array, [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) treats the operand as a non-numeric value.

In the other supported stages:

- With a single expression as its operand, if the expression resolves to an array, [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) traverses into the array to operate on the numeric elements of the array to return a single value.

- With a list of expressions as its operand, if any of the expressions resolves to an array, [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) does **not** traverse into the array but instead treats the array as a non-numeric value.

For example, when not used in a `$group` stage:

- If the `$sum` operand is `[ 2, 2 ]`, `$sum` adds the array elements and returns 4.

- If the `$sum` operand is `[ 2, [ 3, 4 ] ]`, `$sum` returns 2 because it treats the nested array `[ 3, 4 ]` as a non-numeric value.

## Examples

### Use in `$group` Stage

Consider a `sales` collection with the following documents:

```javascript
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`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) accumulator to compute the total amount and the count for each group of documents.

```javascript
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:

```javascript
{ "_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`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) on a non-existent field returns a value of `0`. The following operation attempts to [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) on `qty`:

```javascript
db.sales.aggregate(
   [
     {
       $group:
         {
           _id: { day: { $dayOfYear: "$date"}, year: { $year: "$date" } },
           totalAmount: { $sum: "$qty" },
           count: { $sum: 1 }
         }
     }
   ]
)
```

The operation returns:

```javascript
{ "_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`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator.md#mongodb-group-grp.-count) aggregation accumulator can be used in place of `{ $sum : 1 }` in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage.

**See also:**

[`$count (aggregation accumulator)`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator.md#mongodb-group-grp.-count)

### Use in `$project` Stage

A collection `students` contains the following documents:

```javascript
{ "_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`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) in the [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) stage to calculate the total quiz scores, the total lab scores, and the total of the final and the midterm:

```javascript
db.students.aggregate([
   {
     $project: {
       quizTotal: { $sum: "$quizzes"},
       labTotal: { $sum: "$labs" },
       examTotal: { $sum: [ "$final", "$midterm" ] }
     }
   }
])
```

The operation results in the following documents:

```javascript
{ "_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

**New in version 5.0**

Create a `cakeSales` collection that contains cake sales in the states of California (`CA`) and Washington (`WA`):

```javascript
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`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage to output the sum of the `quantity` of cakes sold in each `state`:

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: "$state",
         sortBy: { orderDate: 1 },
         output: {
            sumQuantityForState: {
               $sum: "$quantity",
               window: {
                  documents: [ "unbounded", "current" ]
               }
            }
         }
      }
   }
] )
```

In the example:

- `partitionBy: "$state"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#std-label-setWindowFields-partitionBy) the documents in the collection by `state`. There are partitions for `CA` and `WA`.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`), so the earliest `orderDate` is first.

* `output` sets the `sumQuantityForState` field to the sum of the `quantity` values using [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) that is run in a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#std-label-setWindowFields-documents) window.

  The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#std-label-setWindowFields-window) contains documents between an `unbounded` lower limit and the `current` document in the output. This means [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) returns the sum of the `quantity` values for the documents between the beginning of the partition and the current document.

In this output, the sum of the `quantity` values for `CA` and `WA` is shown in the `sumQuantityForState` field:

```javascript
{ "_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 }
```
