Struktura potoku agregacji MongoDB obejmuje $round
operator i $trunc
operator. Operatorzy ci wykonują podobne, ale różne zadania.
Definicje
Najpierw spójrzmy na definicje każdego operatora:
$round
operator rundy liczbę na liczbę całkowitą lub do określonego miejsca dziesiętnego.$truncate
operator obcina liczbę na liczbę całkowitą lub do określonego miejsca dziesiętnego.
Zasadniczo różnica polega na słowach okrągły kontra obcinanie .
W niektórych przypadkach oba operatory zwrócą ten sam wynik. W innych przypadkach ich wyniki będą się różnić. Dzieje się tak, ponieważ $round
operator może zaokrąglić liczbę w górę, w zależności od wartości. $truncate
operator nie zaokrągla liczby. Zamiast tego po prostu go obcina. Innymi słowy, po prostu wycina liczbę zgodnie z opisem, pozostawiając pozostałe cyfry bez zmian.
Przykład
Załóżmy, że mamy kolekcję o nazwie test
z następującymi dokumentami:
{ "_id" : 1, "data" : 8.99 } { "_id" : 2, "data" : 8.45 } { "_id" : 3, "data" : 8.451 } { "_id" : 4, "data" : -8.99 } { "_id" : 5, "data" : -8.45 } { "_id" : 6, "data" : -8.451 } { "_id" : 7, "data" : 8 } { "_id" : 8, "data" : 0 } { "_id" : 9, "data" : 0.5 } { "_id" : 10, "data" : 8111.32 } { "_id" : 11, "data" : 8514.321 } { "_id" : 12, "data" : 8999.454 }
Oto, co się dzieje, gdy zastosujemy $round
i $truncate
do tych dokumentów:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data" ] },
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Wynik:
{ "data" : 0, "rounded" : 0, "truncated" : 0 } { "data" : 8, "rounded" : 8, "truncated" : 8 } { "data" : 0.5, "rounded" : 0, "truncated" : 0 } { "data" : 0.9, "rounded" : 1, "truncated" : 0 } { "data" : 8.99, "rounded" : 9, "truncated" : 8 } { "data" : 8.45, "rounded" : 8, "truncated" : 8 } { "data" : 8.451, "rounded" : 8, "truncated" : 8 } { "data" : -8.99, "rounded" : -9, "truncated" : -8 } { "data" : -8.45, "rounded" : -8, "truncated" : -8 } { "data" : -8.451, "rounded" : -8, "truncated" : -8 }
Widzimy, że w niektórych przypadkach wynik jest taki sam. W innych jest inaczej. Na przykład, gdy wartość wejściowa to 0.9
, $round
operator zaokrągla liczbę w górę do 1
. $truncate
z drugiej strony operator po prostu usuwa .9
część, która daje wynik 0
.
Ujemne miejsca ułamkowe
Oba operatory akceptują opcjonalny drugi argument. Gdy jest obecny, ten argument określa liczbę miejsc dziesiętnych do zaokrąglenia/obcięcia liczby.
Podanie tego drugiego argumentu może dodatkowo podkreślić różnicę między tymi dwoma operatorami.
Przykład:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", 1 ] },
truncated: { $trunc: [ "$data", 1 ] }
}
}
]
)
Wynik:
{ "data" : 0, "rounded" : 0, "truncated" : 0 } { "data" : 8, "rounded" : 8, "truncated" : 8 } { "data" : 0.5, "rounded" : 0.5, "truncated" : 0.5 } { "data" : 0.9, "rounded" : 0.9, "truncated" : 0.9 } { "data" : 8.99, "rounded" : 9, "truncated" : 8.9 } { "data" : 8.45, "rounded" : 8.4, "truncated" : 8.4 } { "data" : 8.451, "rounded" : 8.5, "truncated" : 8.4 } { "data" : -8.99, "rounded" : -9, "truncated" : -8.9 } { "data" : -8.45, "rounded" : -8.4, "truncated" : -8.4 } { "data" : -8.451, "rounded" : -8.5, "truncated" : -8.4 }
Ponownie widzimy, że niektóre wyniki są identyczne, a inne nie.
Ujemne miejsca ułamkowe
Oba operatory przyjmują wartość ujemną dla drugiego argumentu.
Przykład:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", -1 ] },
truncated: { $trunc: [ "$data", -1 ] }
}
}
]
)
Wynik:
{ "data" : 0, "rounded" : 0, "truncated" : 0 } { "data" : 8, "rounded" : 10, "truncated" : 0 } { "data" : 0.5, "rounded" : 0, "truncated" : 0 } { "data" : 0.9, "rounded" : 0, "truncated" : 0 } { "data" : 8.99, "rounded" : 10, "truncated" : 0 } { "data" : 8.45, "rounded" : 10, "truncated" : 0 } { "data" : 8.451, "rounded" : 10, "truncated" : 0 } { "data" : -8.99, "rounded" : -10, "truncated" : 0 } { "data" : -8.45, "rounded" : -10, "truncated" : 0 } { "data" : -8.451, "rounded" : -10, "truncated" : 0 }
Tym razem istnieje wyraźny kontrast między wynikami uzyskanymi przez dwóch operatorów. $trunc
operator wyprodukował 0
dla każdego dokumentu, podczas gdy $round
operator zwrócił różne wartości, z których większość została zaokrąglona w górę lub w dół.
$podłoga i $ceil
Dwa kolejne operatory, o których należy pamiętać podczas wykonywania takich operacji, to $floor
i $ceil
. Operatorzy ci działają w podobny sposób, ale nieco inaczej.
$floor
zwraca największy liczba całkowita mniejsza lub równa podanej liczbie$ceil
zwraca najmniejszą liczba całkowita większa lub równa podanej liczbie.