El marco de canalización de agregación de MongoDB incluye un $round
operador y un $trunc
operador. Estos operadores realizan tareas similares, pero diferentes.
Definiciones
Primero, veamos las definiciones de cada operador:
- La
$round
operador rondas un número a un entero entero o a un lugar decimal especificado. - El
$truncate
el operador trunca un número a un entero entero o a un lugar decimal especificado.
Básicamente, la diferencia está en las palabras redonda vs truncar .
En algunos casos, ambos operadores devolverán el mismo resultado. En otros casos, sus resultados serán diferentes. Esto se debe a que $round
el operador puede redondear el número, dependiendo del valor. El $truncate
el operador no redondea el número. En cambio, simplemente lo trunca. En otras palabras, simplemente corta el número como se especifica, mientras deja los dígitos restantes como están.
Ejemplo
Supongamos que tenemos una colección llamada test
con los siguientes documentos:
{ "_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 }
Esto es lo que sucede cuando aplicamos $round
y $truncate
a esos documentos:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data" ] },
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Resultado:
{ "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 }
Podemos ver que en algunos casos, el resultado es el mismo. En otros, es diferente. Por ejemplo, cuando el valor de entrada es 0.9
, el $round
el operador redondea el número a 1
. El $truncate
por otro lado, el operador simplemente elimina el .9
part, que produce un resultado de 0
.
Lugares fraccionarios negativos
Ambos operadores aceptan un segundo argumento opcional. Cuando está presente, este argumento especifica el número de lugares decimales para redondear/truncar el número.
Proporcionar este segundo argumento puede resaltar aún más la diferencia entre los dos operadores.
Ejemplo:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", 1 ] },
truncated: { $trunc: [ "$data", 1 ] }
}
}
]
)
Resultado:
{ "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 }
Nuevamente podemos ver que algunos resultados son idénticos mientras que otros no lo son.
Lugares fraccionarios negativos
Ambos operadores aceptan un valor negativo para el segundo argumento.
Ejemplo:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", -1 ] },
truncated: { $trunc: [ "$data", -1 ] }
}
}
]
)
Resultado:
{ "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 }
Esta vez hay un marcado contraste entre los resultados producidos por los dos operadores. El $trunc
operador produjo 0
para cada documento, mientras que el $round
El operador devolvió varios valores, la mayoría de los cuales se redondearon hacia arriba o hacia abajo.
$suelo y $techo
Dos operadores más a tener en cuenta al realizar operaciones como esta son $floor
y $ceil
. Estos operadores funcionan de manera similar, pero ligeramente diferente.
$floor
devuelve el más grande entero menor o igual que el número especificado$ceil
devuelve el menor entero mayor o igual que el número especificado.