Definición
Cambiado en la versión 5.0.
Calcula y devuelve la suma colectiva de valores numéricos. ignora los valores no$sum numéricos.
$sum está disponible en estas etapas:
$setWindowFields(Disponible a partir de MongoDB 5.0)
Compatibilidad
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.
Sintaxis
Cuando se usa como acumulador, tiene esta$sum sintaxis:
{ $sum: <expression> }
Cuando no se usa como acumulador, tiene esta$sum sintaxis:
{ $sum: [ <expression1>, <expression2> ... ] }
Para obtener más información sobre las expresiones, consulta Expresiones.
Comportamiento
Tipo de datos del resultado
Cuando se mezclan los tipos de entrada, $sum promueve el tipo de entrada menor al mayor de los dos. Un tipo se considera mayor cuando representa un rango más amplio de valores. El orden de los tipos numéricos, de menor a mayor, es: entero → largo → doble → decimal
El tipo de entrada mayor también determina el tipo de resultado, a menos que la operación se desborde y salga del rango representado por ese tipo de dato mayor. En casos de desbordamiento, $sum promueve el resultado según el siguiente orden:
Campos no numéricos o no existentes
Si se utiliza en un campo que contiene valores numéricos y no numéricos, ignora los valores no numéricos y devuelve la suma de los valores$sum 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 matrices o contienen null valores, $sum 0devuelve. Para obtener más información sobre cómo $sum maneja las matrices, consulte Operando de matriz.
Arreglo Operand
En la etapa, si la expresión $group $sum se resuelve en una matriz, trata el operando como un valor no numérico.
En las otras etapas admitidas:
Con una sola expresión como operando, si la expresión se resuelve en una matriz, recorre la matriz para operar sobre los elementos numéricos de la matriz para devolver un único
$sumvalor.Con una lista de expresiones como operando, si alguna de las expresiones se resuelve en una matriz,no recorre
$sumla matriz, sino que trata la matriz como un valor no numérico.
Por ejemplo, cuando no se utiliza en una etapa $group:
Si el operando
$sumes[ 2, 2 ],$sumsuma los elementos del arreglo y devuelve 4.Si el operando
$sumes[ 2, [ 3, 4 ] ],$sumdevuelve 2 porque trata el arreglo anidado[ 3, 4 ]como un valor no numérico.
Ejemplos
Uso en la etapa $group
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") } ] )
Agrupando los documentos por el día y el año del date campo, la siguiente operación utiliza el acumulador para calcular el importe total y el recuento para cada grupo de $sum 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 }
Usar en un campo inexistente devuelve un $sum valor 0 de. La siguiente operación intenta $sum qtyen:
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.
Uso en la etapa $project
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 para calcular las calificaciones totales del cuestionario, las calificaciones totales del laboratorio y el total del examen final y el examen $project 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 }
Uso en la etapa $setWindowFields
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 para generar la suma de $setWindowFields los quantity pasteles vendidos en state cada:
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 enstate. Existen particiones paraCAyWA.sortBy: { orderDate: 1 }ordena los documentos de cada partición pororderDateen orden ascendente (1), de modo que elorderDatemás antiguo sea el primero.
outputestablece elsumQuantityForStatecampo a la suma de losquantityvalores usando que se$sumejecuta en una ventana de documentos.La ventana contiene documentos entre un
unboundedlímite inferior y elcurrentdocumento en la salida. Esto significa que devuelve la suma de$sumlosquantityvalores 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 }