Docs Menu
Docs Home
/ /

$sum (operador de acumulación)

$sum

Modificado en la versión 5.0.

Calcula y devuelve la suma colectiva de valores numéricos. $sum ignora valores no numéricos.

$sum está disponible en estas etapas:

  • $addFields

  • $bucket

  • $bucketAuto

  • $group

  • La $match etapa que incluye una $expr expresión

  • $project

  • $replaceRoot

  • $replaceWith

  • $set

  • $setWindowFields (Disponible a partir de MongoDB 5.0)

Puedes usar $sum para implementaciones alojadas en los siguientes entornos:

  • MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube

  • MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB

  • MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.

Cuando se utiliza como un acumulador, $sum tiene esta sintaxis:

{ $sum: <expression> }

Cuando no se utiliza como un acumulador, $sum tiene esta sintaxis:

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

Para obtener más información sobre las expresiones, consulta Expresiones.

El resultado tendrá el mismo tipo que la entrada excepto cuando no pueda representarse con precisión en ese tipo. En estos casos:

  • Un entero de 32bits se convertirá en un entero de 64bits si el resultado se puede representar como un entero de 64bits.

  • Un entero de 32bits se convertirá en un doble si el resultado no se puede representar como un entero de 64bits.

  • Un entero de 64bits se convertirá en doble si el resultado no se puede representar como un entero de 64bits.

Si se utiliza en un campo que contiene tanto valores numéricos como no numéricos, $sum ignora los valores no numéricos y devuelve la suma de los valores numéricos.

Si se utiliza en un campo que no existe en ningún documento de la colección, $sum devuelve 0 para ese campo.

Si todos los operandos no son numéricos, no son arreglos o contienen valores null, $sum devuelve 0. Para obtener detalles sobre cómo $sum gestiona los arreglos, consulta Operando de arreglo.

En la etapa $group, si la expresión se resuelve en un arreglo, $sum trata el operando como un valor no numérico.

En las otras etapas admitidas:

  • Con una única expresión como operando, si la expresión se resuelve en un arreglo, $sum recorre el arreglo para operar sobre sus elementos numéricos y devolver un único valor.

  • Con una lista de expresiones como su operando, si alguna de las expresiones se resuelve en un arreglo, $sum no recorre el arreglo sino que lo trata como un valor no numérico.

Por ejemplo, cuando no se utiliza en una etapa $group:

  • Si el operando $sum es [ 2, 2 ], $sum suma los elementos del arreglo y devuelve 4.

  • Si el operando $sum es [ 2, [ 3, 4 ] ], $sum devuelve 2 porque trata el arreglo anidado [ 3, 4 ] como un valor no numérico.

Considera una colección sales con los siguientes documentos:

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") }
] )

Al agrupar los documentos por el día y el año del campo date, la siguiente operación utiliza el acumulador $sum para calcular el importe total y el recuento de cada grupo de documentos.

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

La operación devuelve los siguientes resultados:

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

El uso de $sum en un campo inexistente devuelve un valor de 0. La siguiente operación intenta $sum sobre qty:

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

La operación arroja:

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

El acumulador de agregación $count se puede utilizar en lugar de { $sum : 1 } en la etapa de $group.

Tip

Una colección students contiene los siguientes documentos:

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

El siguiente ejemplo utiliza el $sum en la etapa $project para calcular las puntuaciones totales de los cuestionarios, las puntuaciones totales de los laboratorios y el total del examen final y del parcial:

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

La operación da como resultado los siguientes documentos:

{ "_id" : 1, "quizTotal" : 23, "labTotal" : 13, "examTotal" : 155 }
{ "_id" : 2, "quizTotal" : 19, "labTotal" : 16, "examTotal" : 175 }
{ "_id" : 3, "quizTotal" : 14, "labTotal" : 11, "examTotal" : 148 }

Nuevo en la versión 5.0.

Crea una colección de cakeSales que incluya ventas de pasteles en el estado de California (CA) y Washington (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 }
] )

Este ejemplo utiliza $sum en la etapa $setWindowFields para generar la suma de las quantity de pasteles vendidos en cada state:

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

En el ejemplo:

  • partitionBy: "$state" particiona los documentos de la colección en state. Existen particiones para CA y WA.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1), de modo que el orderDate más antiguo sea el primero.

  • output establece el campo sumQuantityForState a la suma de los valores de quantity usando $sum que se ejecuta en una ventana de documentos.

    La ventana contiene documentos entre un límite inferior de unbounded y el documento current en el resultado. Esto significa que $sum devuelve la suma de los valores de quantity para los documentos entre el inicio de la partición y el documento actual.

En este resultado, la suma de los valores de quantity para CA y WA se muestra en el campo 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 }

Volver

$stdDevSamp

En esta página