W MongoDB $trunc
Operator potoku agregacji obcina liczbę do liczby całkowitej lub do określonego miejsca dziesiętnego.
Masz możliwość określenia, o ile miejsc dziesiętnych należy skrócić liczbę. Aby to zrobić, przekaż drugi argument. Pierwszy argument to liczba do skrócenia, a drugi (opcjonalny) argument to liczba miejsc dziesiętnych, do których należy go skrócić.
Pominięcie drugiego argumentu obcina wszystkie cyfry z prawej strony przecinka i zwraca całą wartość całkowitą.
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 }
Możemy użyć $trunc
operator do obcinania wartości w data
pole:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Wynik:
{ "data" : 8.99, "truncated" : 8 } { "data" : 8.45, "truncated" : 8 } { "data" : 8.451, "truncated" : 8 } { "data" : -8.99, "truncated" : -8 } { "data" : -8.45, "truncated" : -8 } { "data" : -8.451, "truncated" : -8 } { "data" : 8, "truncated" : 8 } { "data" : 0, "truncated" : 0 }
Zauważ, że $trunc
nie zaokrągla liczb, takich jak $round
robi. $trunc
operator po prostu obcina liczbę. Gdybyśmy zastosowali $round
do tej kolekcji pierwszy i czwarty dokument zostałyby zaokrąglone do 9
i -9
odpowiednio.
Określ miejsce dziesiętne
Mamy możliwość użycia drugiego argumentu, aby określić, do ilu miejsc dziesiętnych należy skrócić liczbę.
Przykład:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 1 ] }
}
}
]
)
Wynik:
{ "data" : 8.99, "truncated" : 8.9 } { "data" : 8.45, "truncated" : 8.4 } { "data" : 8.451, "truncated" : 8.4 } { "data" : -8.99, "truncated" : -8.9 } { "data" : -8.45, "truncated" : -8.4 } { "data" : -8.451, "truncated" : -8.4 } { "data" : 8, "truncated" : 8 } { "data" : 0, "truncated" : 0 }
Ponownie, to po prostu obcina liczbę. Gdybyśmy użyli $round
, niektóre z tych liczb zostałyby zaokrąglone.
Ujemne miejsca dziesiętne
Drugi argument może być dowolnym poprawnym wyrażeniem, które daje w wyniku liczbę całkowitą z przedziału od -20 do 100, z wyłączeniem. Dlatego możesz określić ujemne miejsce dziesiętne.
Gdy to zrobisz, liczba zostanie obcięta z lewej strony miejsca dziesiętnego. Jeśli wartość bezwzględna ujemnej liczby całkowitej jest większa od liczby cyfr z lewej strony przecinka dziesiętnego, wynikiem jest 0
.
Załóżmy, że do naszej kolekcji dodamy następujące dokumenty:
{ "_id" : 9, "data" : 8111.32 } { "_id" : 10, "data" : 8514.321 } { "_id" : 11, "data" : 8999.454 }
Oto przykład użycia różnych ujemnych miejsc dziesiętnych podczas stosowania $trunc
do tych dokumentów:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 9, 10, 11 ] } } },
{
$project:
{
_id: 0,
data: 1,
a: { $trunc: [ "$data", -1 ] },
b: { $trunc: [ "$data", -2 ] },
c: { $trunc: [ "$data", -3 ] },
d: { $trunc: [ "$data", -4 ] },
e: { $trunc: [ "$data", -5 ] }
}
}
]
).pretty()
Wynik:
{ "data" : 8111.32, "a" : 8110, "b" : 8100, "c" : 8000, "d" : 0, "e" : 0 } { "data" : 8514.321, "a" : 8510, "b" : 8500, "c" : 8000, "d" : 0, "e" : 0 } { "data" : 8999.454, "a" : 8990, "b" : 8900, "c" : 8000, "d" : 0, "e" : 0 }
Dziesiętne miejsce zera
Gdy podasz miejsce dziesiętne 0
, $trunc
operator obcina wszystkie cyfry z prawej strony przecinka dziesiętnego i zwraca całą wartość całkowitą.
Przykład:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 0 ] }
}
}
]
)
Wynik:
{ "data" : 8.99, "truncated" : 8 } { "data" : 8.45, "truncated" : 8 } { "data" : 8.451, "truncated" : 8 } { "data" : -8.99, "truncated" : -8 } { "data" : -8.45, "truncated" : -8 } { "data" : -8.451, "truncated" : -8 } { "data" : 8, "truncated" : 8 } { "data" : 0, "truncated" : 0 } { "data" : 8111.32, "truncated" : 8111 } { "data" : 8514.321, "truncated" : 8514 } { "data" : 8999.454, "truncated" : 8999 }
Typy liczb
Liczba do obcięcia może być dowolnym prawidłowym wyrażeniem, które daje w wyniku liczbę całkowitą, podwójną, dziesiętną lub długą. Zwracana wartość odpowiada typowi danych wartości wejściowej.
Jeśli więc dodamy do naszej kolekcji następujące dokumenty:
{ "_id" : 12, "data" : NumberDecimal("128.4585") } { "_id" : 13, "data" : NumberDecimal("128.12345678912") }
Możemy zastosować $trunc
do data
pole:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 12, 13 ] } } },
{
$project:
{
_id: 0,
data: 1,
a: { $trunc: [ "$data", -1 ] },
b: { $trunc: [ "$data", 0 ] },
c: { $trunc: [ "$data", 3 ] },
d: { $trunc: [ "$data", 4 ] },
e: { $trunc: [ "$data", 5 ] }
}
}
]
).pretty()
Wynik:
{ "data" : NumberDecimal("128.4585"), "a" : NumberDecimal("1.2E+2"), "b" : NumberDecimal("128"), "c" : NumberDecimal("128.458"), "d" : NumberDecimal("128.4585"), "e" : NumberDecimal("128.45850") } { "data" : NumberDecimal("128.12345678912"), "a" : NumberDecimal("1.2E+2"), "b" : NumberDecimal("128"), "c" : NumberDecimal("128.123"), "d" : NumberDecimal("128.1234"), "e" : NumberDecimal("128.12345") }
Obcinanie do pustych miejsc dziesiętnych
Jeśli drugim argumentem jest null
, wynik to null
.
Przykład:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", null ] }
}
}
]
)
Wynik:
{ "data" : 8.99, "truncated" : null } { "data" : 8.45, "truncated" : null } { "data" : 8.451, "truncated" : null }
Obcinanie wartości Null
Jeśli wartość do obcięcia to null
, wynik to null
.
Załóżmy, że dodajemy do kolekcji następujący dokument:
{ "_id" : 14, "data" : null }
I używamy $trunc
aby skrócić wartość null:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 14 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", null ] }
}
}
]
)
Wynik:
{ "data" : null, "truncated" : null }
Obcinanie nieskończoności
Jeśli liczba do skrócenia to Infinity
, wynikiem jest Infinity
. Podobnie, jeśli jest to -Infinity
, wynikiem jest -Infinity
.
Dodajmy dwa dokumenty z takimi wartościami:
{ "_id" : 15, "data" : Infinity } { "_id" : 16, "data" : -Infinity }
I skróćmy je:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 15, 16 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 2 ] }
}
}
]
)
Wynik:
{ "data" : Infinity, "truncated" : Infinity } { "data" : -Infinity, "truncated" : -Infinity }
Obcinanie NaN
Obcinanie NaN
wyniki w NaN
.
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" * 2 ] }
}
}
]
)
Wynik:
{ "data" : 8.99, "truncated" : NaN } { "data" : 8.45, "truncated" : NaN }
Typy nieliczbowe
Jeśli spróbujesz skrócić wartość, która jest niewłaściwym typem danych (tj. nie jest liczbą całkowitą, podwójną, dziesiętną lub długą), zostanie zwrócony błąd.
Załóżmy, że do naszej kolekcji dodamy następujący dokument:
{ "_id" : 17, "data" : "Thirty five" }
A teraz próbujemy skrócić data
pole:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 17 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Wynik:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$trunc only supports numeric types, not string", "code" : 51081, "codeName" : "Location51081" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1