I MongoDB, $sum
aggregeringspipeline-operatören beräknar och returnerar summan av numeriska värden.
Syntax
$sum
operatorn stöder två syntaxer.
Syntax 1:
{ $sum: <expression> }
Syntax 2:
{ $sum: [ <expression1>, <expression2> ... ] }
Den första syntaxen accepterar ett argument och den andra syntaxen accepterar flera argument.
När den används i $group
steg kan du bara använda den första syntaxen. I det här fallet, $sum
returnerar den samlade summan av alla numeriska värden som är resultatet av att tillämpa det angivna uttrycket på varje dokument i en grupp av dokument som delar samma grupp per nyckel.
Exempel på syntax 1 (enkelt argument)
Här är ett par exempel som använder syntax 1.
Grupperade dokument
Det här exemplet använder $sum
i samband med $group
för att returnera summan över en grupp av dokument som är grupperade efter nyckel.
Anta att vi har en samling som heter pets
med följande dokument:
{ "_id" :1, "name" :"Wag", "type" :"Hund", "weight" :20 }{ "_id" :2, "name" :"Bark", "typ" :"Hund", "vikt" :10 }{ "_id" :3, "name" :"Mjau", "typ" :"Katt", "vikt" :7 }{ "_id" :4, "namn" :"Scratch", "type" :"Cat", "weight" :8 }{ "_id" :5, "name" :"Bruce", "type" :"Känguru", "weight" :100 }{ " _id" :6, "name" :"Hop", "type" :"Känguru", "vikt" :130 }{ "_id" :7, "name" :"Punch", "type" :"Känguru", "weight" :200 }{ "_id" :8, "name" :"Snap", "type" :"Cat", "weight" :12 }{ "_id" :9, "name" :"Ruff", "type" :"Hund", "vikt" :30 }
Vi kan gruppera dessa dokument efter deras type
och använd sedan $sum
för att returnera summan av weight
fält för varje grupp:
db.pets.aggregate(
[
{
$group:
{
_id: "$type",
sum: { $sum: "$weight" }
}
}
]
)
Resultat:
{ "_id" :"Känguru", "sum" :430 }{ "_id" :"Katt", "sum" :27 }{ "_id" :"Hund", "summa" :60 }Arrayer
Det här exemplet gäller
$sum
till ett enda dokument som innehåller ett fält med en rad värden.Det här alternativet är endast tillgängligt när du använder syntaxen för enstaka argument. Matriser ignoreras när man använder flerargumentsyntaxen (mer om detta nedan).
Anta att vi har en samling som heter
players
med följande dokument:{ "_id" :1, "player" :"Homer", "scores" :[ 1, 7, 2, 3, 8, 7, 1 ] }{ "_id" :2, "player" :" Marge", "scores" :[ 0, 1, 8, 17, 18, 8 ] }{ "_id" :3, "player" :"Bart", "scores" :[ 15, 11, 8, 0, 1 , 3 ] }{ "_id" :4, "player" :"Brian", "scores" :[ 7 ] }{ "_id" :5, "player" :"Farnsworth", "scores" :[ ] }{ "_id" :6, "player" :"Meg", "scores" :null }{ "_id" :7, "player" :"Ron" }Vi kan tillämpa
$sum
tillscores
fält i varje dokument:db.players.aggregate( [ { $project: { player: 1, sum: { $sum: "$scores" } } } ] )
Resultat:
{ "_id" :1, "player" :"Homer", "sum" :29 }{ "_id" :2, "player" :"Marge", "sum" :52 }{ "_id" :3, "player" :"Bart", "sum" :38 }{ "_id" :4, "player" :"Brian", "sum" :7 }{ "_id" :5, "player" :"Farnsworth ", "sum" :0 }{ "_id" :6, "player" :"Meg", "summa" :0 }{ "_id" :7, "player" :"Ron", "summa" :0 }I det här fallet returnerade de första fyra dokumenten summan av de olika siffrorna som fanns i sina respektive arrayer.
I dokument 4:s fall var detta detsamma som numret, eftersom det bara fanns ett nummer i arrayen.
Dokument 5 returnerade
0
eftersom vi tillhandahållit en tom array.Dokument 6 returnerade
0
eftersom vi tillhandahållitnull
som argument.Dokument 7 returnerade
0
eftersom fältet inte ens existerade.Exempel på syntax 2 (flera argument)
Den andra syntaxen innebär att du tillhandahåller
$sum
med mer än ett argument.$sum
beräknar sedan summan baserat på alla angivna argument.Anta att vi har en samling som heter
data
med följande dokument:{ "_id" :1, "a" :1, "b" :2, "c" :3, "d" :4 }{ "_id" :2, "a" :1, "b" :2, "c" :3, "d" :[ 4 ] }{ "_id" :3, "a" :1, "b" :2, "c" :3, "d" :"Hej" } { "_id" :4, "a" :"En", "b" :"Två", "c" :"Tre", "d" :"Fyra" }Vi kan använda
$sum
för att returnera summan ava
,b
,c
ochd
fält för varje dokument:db.data.aggregate( [ { $project: { sum: { $sum: [ "$a", "$b", "$c", "$d" ] } } } ] )
Resultat:
{ "_id" :1, "sum" :10 }{ "_id" :2, "sum" :6 }{ "_id" :3, "summa" :6 }{ "_id" :4, " summa" :0 }Dokument 1 returnerar summan av ingångsvärdena för
1
,2
,3
och4
.De följande två dokumenten returnerade dock bara summan av ingångsvärdena för
1
,2
och3
.$sum
operatören ignorerade derasd
fält.Detta beror på att
$sum
ignorerar icke-numeriska värden. Så i det här fallet ignorerade den"Hey"
i dokument 3 och beräknade summan från de återstående (numeriska) fälten.När det gäller dokument 2, dess
d
fältet innehåller en array. Som nämnts,$sum
operatorn ignorerar matriser när syntaxen för flera argument används. Närmare bestämt behandlar den arrayer som icke-numeriska värden när de används i detta sammanhang, och$sum
ignorerar icke-numeriska värden.Om alla värden är icke-numeriska, då
$sum
returnerar0
. Vi kan se detta med dokument 4.Fält saknas
När du använder syntaxen för flera argument,
$sum
ignorerar eventuella saknade fält. Det vill säga, om du anger ett fält som inte finns ignorerar det det. Om inget av fälten finns returnerar det0
.Exempel:
db.data.aggregate( [ { $project: { sum: { $sum: [ "$a", "$b", "$c", "$d", "$e" ] } } } ] )
Resultat:
{ "_id" :1, "sum" :10 }{ "_id" :2, "sum" :6 }{ "_id" :3, "summa" :6 }{ "_id" :4, " summa" :0 }I det här fallet angav jag ett extra fält (
$e
) som inte finns i dokumenten.$sum
beräknade summan baserat på de återstående fälten som gör finns.Men här är vad som händer när ingen av fälten finns:
db.data.aggregate( [ { $project: { result: { $sum: [ "$x", "$y", "$z" ] } } } ] )
Resultat:
{ "_id" :1, "result" :0 }{ "_id" :2, "result" :0 }{ "_id" :3, "result" :0 }{ "_id" :4, " resultat" :0 }Resultatet är
0
för alla dokument.Som vi såg tidigare, när man använder syntaxen med ett argument, resulterar ett saknat fält i
0
.Exempel:
db.pets.aggregate( [ { $group: { _id: "$type", sum: { $sum: "$oops!" } } } ] )
Resultat:
{ "_id" :"Katt", "sum" :0 }{ "_id" :"Hund", "sum" :0 }{ "_id" :"Känguru", "summa" :0 }Tillgängliga steg
$sum
är tillgänglig i följande steg:
$group
$project
$addFields
$set
$replaceRoot
$replaceWith
$match
steg som inkluderar en$expr
uttryck