W MongoDB $sum Operator potoku agregacji oblicza i zwraca sumę wartości liczbowych.
Składnia
$sum operator obsługuje dwie składnie.
Składnia 1:
{ $sum: <expression> } Składnia 2:
{ $sum: [ <expression1>, <expression2> ... ] } Pierwsza składnia akceptuje jeden argument, a druga – wiele argumentów.
W przypadku użycia w grupie $group etapie, możesz użyć tylko pierwszej składni. W tym przypadku $sum zwraca zbiorczą sumę wszystkich wartości liczbowych, które wynikają z zastosowania określonego wyrażenia do każdego dokumentu w grupie dokumentów, które dzielą tę samą grupę według klucza.
Przykłady składni 1 (pojedynczy argument)
Oto kilka przykładów używających składni 1.
Dokumenty zgrupowane
W tym przykładzie użyto $sum w połączeniu z $group aby zwrócić sumę w grupie dokumentów pogrupowanych według klucza.
Załóżmy, że mamy kolekcję o nazwie pets z następującymi dokumentami:
{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 }
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 }
{ "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 }
{ "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 }
Możemy pogrupować te dokumenty według ich type pole, a następnie użyj $sum aby zwrócić sumę weight pole dla każdej grupy:
db.pets.aggregate(
[
{
$group:
{
_id: "$type",
sum: { $sum: "$weight" }
}
}
]
) Wynik:
{ "_id" : "Kangaroo", "sum" : 430 }
{ "_id" : "Cat", "sum" : 27 }
{ "_id" : "Dog", "sum" : 60 } Tablice
Ten przykład dotyczy $sum do pojedynczego dokumentu, który zawiera pole z tablicą wartości.
Ta opcja jest dostępna tylko w przypadku używania składni jednoargumentowej. Tablice są ignorowane podczas używania składni wieloargumentowej (więcej na ten temat poniżej).
Załóżmy, że mamy kolekcję o nazwie players z następującymi dokumentami:
{ "_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" }
Możemy zastosować $sum do scores pole w każdym dokumencie:
db.players.aggregate(
[
{
$project:
{
player: 1,
sum: { $sum: "$scores" }
}
}
]
) Wynik:
{ "_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", "sum" : 0 }
{ "_id" : 7, "player" : "Ron", "sum" : 0 } W tym przypadku pierwsze cztery dokumenty zwróciły sumę różnych liczb, które znajdowały się w ich odpowiednich tablicach.
W przypadku dokumentu 4 było to to samo co liczba, ponieważ w tablicy była tylko jedna liczba.
Dokument 5 zwrócił 0 ponieważ dostarczyliśmy pustą tablicę.
Dokument 6 zwrócił 0 ponieważ podaliśmy null jako argument.
Dokument 7 zwrócił 0 ponieważ pole nawet nie istniało.
Przykład składni 2 (wiele argumentów)
Druga składnia polega na podaniu $sum z więcej niż jednym argumentem. $sum następnie oblicza sumę na podstawie wszystkich dostarczonych argumentów.
Załóżmy, że mamy kolekcję o nazwie data z następującymi dokumentami:
{ "_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" : "Hey" }
{ "_id" : 4, "a" : "One", "b" : "Two", "c" : "Three", "d" : "Four" }
Możemy użyć $sum aby zwrócić sumę a , b , c i d pola każdego dokumentu:
db.data.aggregate(
[
{
$project:
{
sum: { $sum: [ "$a", "$b", "$c", "$d" ] }
}
}
]
) Wynik:
{ "_id" : 1, "sum" : 10 }
{ "_id" : 2, "sum" : 6 }
{ "_id" : 3, "sum" : 6 }
{ "_id" : 4, "sum" : 0 }
Dokument 1 zwraca sumę wartości wejściowych 1 , 2 , 3 i 4 .
Jednak kolejne dwa dokumenty zwróciły tylko sumę wartości wejściowych 1 , 2 i 3 . $sum operator zignorował ich d pola.
Dzieje się tak, ponieważ $sum ignoruje wartości nieliczbowe. Więc w tym przypadku zignorował "Hey" w dokumencie 3 i obliczył sumę z pozostałych (liczbowych) pól.
Jeśli chodzi o dokument 2, jego d pole zawiera tablicę. Jak wspomniano, $sum operator ignoruje tablice podczas używania składni wieloargumentowej. Dokładniej, w tym kontekście traktuje tablice jako wartości nieliczbowe, a $sum ignoruje wartości nieliczbowe.
Jeśli wszystkie wartości nie są numeryczne, to $sum zwraca 0 . Możemy to zobaczyć w dokumencie 4.
Brakujące pola
Używając składni wieloargumentowej, $sum ignoruje brakujące pola. Oznacza to, że jeśli podasz pole, które nie istnieje, ignoruje je. Jeśli żadne z pól nie istnieje, zwraca 0 .
Przykład:
db.data.aggregate(
[
{
$project:
{
sum: { $sum: [ "$a", "$b", "$c", "$d", "$e" ] }
}
}
]
) Wynik:
{ "_id" : 1, "sum" : 10 }
{ "_id" : 2, "sum" : 6 }
{ "_id" : 3, "sum" : 6 }
{ "_id" : 4, "sum" : 0 }
W tym przypadku dodałem dodatkowe pole ($e ), która nie istnieje w dokumentach. $sum obliczyła sumę na podstawie pozostałych pól, które wykonaj istnieje.
Oto jednak, co się dzieje, gdy brak z pól istnieje:
db.data.aggregate(
[
{
$project:
{
result: { $sum: [ "$x", "$y", "$z" ] }
}
}
]
) Wynik:
{ "_id" : 1, "result" : 0 }
{ "_id" : 2, "result" : 0 }
{ "_id" : 3, "result" : 0 }
{ "_id" : 4, "result" : 0 }
Wynik to 0 dla wszystkich dokumentów.
Jak widzieliśmy wcześniej, podczas używania składni jednoargumentowej, brakujące pole daje wynik 0 .
Przykład:
db.pets.aggregate(
[
{
$group:
{
_id: "$type",
sum: { $sum: "$oops!" }
}
}
]
) Wynik:
{ "_id" : "Cat", "sum" : 0 }
{ "_id" : "Dog", "sum" : 0 }
{ "_id" : "Kangaroo", "sum" : 0 } Dostępne etapy
$sum jest dostępny w następujących etapach:
$group$project$addFields$set$replaceRoot$replaceWith$matchetap zawierający$exprwyrażenie