MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB $ round vs $ trunc:qual è la differenza?

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.