En MongoDB, el $trunc
El operador de canalización de agregación trunca un número a un entero entero o a un lugar decimal específico.
Tiene la opción de especificar cuántos lugares decimales desea truncar el número. Para hacer esto, pase un segundo argumento. El primer argumento es el número a truncar, y el segundo argumento (opcional) es el número de decimales a truncar.
Omitir el segundo argumento trunca todos los dígitos a la derecha del decimal y devuelve el valor entero entero.
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 }
Podemos usar el $trunc
operador para truncar los valores en los data
campo:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Resultado:
{ "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 }
Note que $trunc
no redondea números como $round
hace. El $trunc
el operador simplemente trunca el número. Si hubiéramos aplicado $round
a esta colección, los documentos primero y cuarto se habrían redondeado a 9
y -9
respectivamente.
Especifique un lugar decimal
Tenemos la opción de usar un segundo argumento para especificar a cuántos lugares decimales truncar el número.
Ejemplo:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 1 ] }
}
}
]
)
Resultado:
{ "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 }
Nuevamente, esto simplemente trunca el número. Si hubiéramos usado $round
, habría redondeado algunos de estos números.
Posiciones decimales negativas
El segundo argumento puede ser cualquier expresión válida que se resuelva en un número entero entre -20 y 100, exclusivo. Por lo tanto, puede especificar un lugar decimal negativo.
Cuando hace esto, el número se trunca a la izquierda del lugar decimal. Si el valor absoluto del entero negativo es mayor que el número de dígitos a la izquierda del decimal, el resultado es 0
.
Supongamos que agregamos los siguientes documentos a nuestra colección:
{ "_id" : 9, "data" : 8111.32 } { "_id" : 10, "data" : 8514.321 } { "_id" : 11, "data" : 8999.454 }
Aquí hay un ejemplo del uso de varios lugares decimales negativos al aplicar $trunc
a esos documentos:
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()
Resultado:
{ "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 }
Posición decimal del cero
Cuando proporciona un lugar decimal de 0
, el $trunc
El operador trunca todos los dígitos a la derecha del decimal y devuelve el valor entero entero.
Ejemplo:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 0 ] }
}
}
]
)
Resultado:
{ "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 }
Tipos de números
El número a truncar puede ser cualquier expresión válida que se resuelva en un número entero, doble, decimal o largo. El valor devuelto coincide con el tipo de datos del valor de entrada.
Entonces, si agregamos los siguientes documentos a nuestra colección:
{ "_id" : 12, "data" : NumberDecimal("128.4585") } { "_id" : 13, "data" : NumberDecimal("128.12345678912") }
Podemos aplicar $trunc
a los data
campo:
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()
Resultado:
{ "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") }
Truncamiento a lugares decimales nulos
Si el segundo argumento es null
, el resultado es null
.
Ejemplo:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", null ] }
}
}
]
)
Resultado:
{ "data" : 8.99, "truncated" : null } { "data" : 8.45, "truncated" : null } { "data" : 8.451, "truncated" : null }
Truncamiento de un valor nulo
Si el valor a truncar es null
, el resultado es null
.
Supongamos que agregamos el siguiente documento a la colección:
{ "_id" : 14, "data" : null }
Y usamos $trunc
para truncar el valor nulo:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 14 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", null ] }
}
}
]
)
Resultado:
{ "data" : null, "truncated" : null }
Truncamiento del infinito
Si el número a truncar es Infinity
, el resultado es Infinity
. Del mismo modo, si es -Infinity
, el resultado es -Infinity
.
Agreguemos dos documentos con tales valores:
{ "_id" : 15, "data" : Infinity } { "_id" : 16, "data" : -Infinity }
Y vamos a truncarlos:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 15, 16 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 2 ] }
}
}
]
)
Resultado:
{ "data" : Infinity, "truncated" : Infinity } { "data" : -Infinity, "truncated" : -Infinity }
Truncamiento de NaN
Truncar NaN
da como resultado NaN
.
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" * 2 ] }
}
}
]
)
Resultado:
{ "data" : 8.99, "truncated" : NaN } { "data" : 8.45, "truncated" : NaN }
Tipos no numéricos
Si intenta truncar un valor que es del tipo de datos incorrecto (es decir, no es un número entero, doble, decimal o largo), se devuelve un error.
Supongamos que agregamos el siguiente documento a nuestra colección:
{ "_id" : 17, "data" : "Thirty five" }
Y ahora tratamos de truncar los data
campo:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 17 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Resultado:
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