Il framework della pipeline di aggregazione di MongoDB include un $round
operatore e un $trunc
operatore. Questi operatori svolgono compiti simili, ma diversi.
Definizioni
Per prima cosa, diamo un'occhiata alle definizioni di ciascun operatore:
- Il
$round
operatore arrotonda un numero a un intero intero oa una cifra decimale specificata. - Il
$truncate
l'operatore tronca un numero a un intero intero oa una cifra decimale specificata.
Fondamentalmente, la differenza sta nelle parole round vs troncare .
In alcuni casi, entrambi gli operatori restituiranno lo stesso risultato. In altri casi, i loro risultati differiranno. Questo perché il $round
l'operatore può arrotondare il numero per eccesso, a seconda del valore. Il $truncate
l'operatore non arrotonda il numero. Invece, lo tronca semplicemente. In altre parole, taglia semplicemente il numero come specificato, lasciando le cifre rimanenti come sono.
Esempio
Supponiamo di avere una collezione chiamata test
con i seguenti documenti:
{ "_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 }
Ecco cosa succede quando applichiamo $round
e $truncate
a quei documenti:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data" ] },
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Risultato:
{ "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 }
Possiamo vedere che in alcuni casi il risultato è lo stesso. In altri, è diverso. Ad esempio, quando il valore di input è 0.9
, il $round
l'operatore arrotonda il numero a 1
. Il $truncate
l'operatore d'altra parte rimuove semplicemente il .9
parte, che produce un risultato di 0
.
Luoghi frazionari negativi
Entrambi gli operatori accettano un secondo argomento facoltativo. Quando presente, questo argomento specifica il numero di cifre decimali a cui arrotondare/troncare il numero.
Fornire questo secondo argomento può evidenziare ulteriormente la differenza tra i due operatori.
Esempio:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", 1 ] },
truncated: { $trunc: [ "$data", 1 ] }
}
}
]
)
Risultato:
{ "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 }
Ancora una volta possiamo vedere che alcuni risultati sono identici mentre altri no.
Luoghi frazionari negativi
Entrambi gli operatori accettano un valore negativo per il secondo argomento.
Esempio:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", -1 ] },
truncated: { $trunc: [ "$data", -1 ] }
}
}
]
)
Risultato:
{ "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 }
Questa volta c'è un netto contrasto tra i risultati prodotti dai due operatori. Il $trunc
l'operatore ha prodotto 0
per ogni documento, mentre il $round
l'operatore ha restituito vari valori, la maggior parte dei quali è stata arrotondata per eccesso o per difetto.
$piano e $ceil
Altri due operatori da tenere presente quando si eseguono operazioni come questa sono $floor
e $ceil
. Questi operatori lavorano in modo simile, ma leggermente diverso.
$floor
restituisce il più grande intero minore o uguale al numero specificato$ceil
restituisce il più piccolo intero maggiore o uguale al numero specificato.