MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB $trunc


No MongoDB, o $trunc operador de pipeline de agregação trunca um número para um inteiro inteiro ou para uma casa decimal especificada.

Você tem a opção de especificar quantas casas decimais para truncar o número. Para fazer isso, passe um segundo argumento. O primeiro argumento é o número a ser truncado e o segundo argumento (opcional) é o número de casas decimais para truncá-lo.

A omissão do segundo argumento trunca todos os dígitos à direita do decimal e retorna o valor inteiro inteiro.

Exemplo


Suponha que tenhamos uma coleção chamada test com os seguintes 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 o $trunc operador para truncar os valores no 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 }

Observe que $trunc não arredonda números como $round faz. O $trunc operador simplesmente trunca o número. Se tivéssemos aplicado $round para esta coleção, o primeiro e o quarto documentos teriam sido arredondados para 9 e -9 respectivamente.

Especifique uma casa decimal


Temos a opção de usar um segundo argumento para especificar para quantas casas decimais truncar o número.

Exemplo:
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 }

Novamente, isso simplesmente trunca o número. Se tivéssemos usado $round , teria arredondado alguns desses números.

Casas decimais negativas


O segundo argumento pode ser qualquer expressão válida que resolva um número inteiro entre -20 e 100, exclusivo. Portanto, você pode especificar uma casa decimal negativa.

Ao fazer isso, o número é truncado à esquerda da casa decimal. Se o valor absoluto do inteiro negativo for maior que o número de dígitos à esquerda do decimal, o resultado será 0 .

Suponha que adicionamos os seguintes documentos à nossa coleção:
{ "_id" : 9, "data" : 8111.32 }
{ "_id" : 10, "data" : 8514.321 }
{ "_id" : 11, "data" : 8999.454 }

Aqui está um exemplo de uso de várias casas decimais negativas ao aplicar $trunc a esses 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
}

Lugar decimal de zero


Quando você fornece uma casa decimal de 0 , o $trunc operador trunca todos os dígitos à direita do decimal e retorna o valor inteiro inteiro.

Exemplo:
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úmero


O número a ser truncado pode ser qualquer expressão válida que resolva para um número inteiro, duplo, decimal ou longo. O valor de retorno corresponde ao tipo de dados do valor de entrada.

Então, se adicionarmos os seguintes documentos à nossa coleção:
{ "_id" : 12, "data" : NumberDecimal("128.4585") }
{ "_id" : 13, "data" : NumberDecimal("128.12345678912") }

Podemos aplicar $trunc para os 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")
}

Truncar para casas decimais nulas


Se o segundo argumento for null , o resultado é null .

Exemplo:
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 }

Truncar um valor nulo


Se o valor a ser truncado for null , o resultado é null .

Suponha que adicionamos o seguinte documento à coleção:
{ "_id" : 14, "data" : null }

E usamos $trunc para truncar o valor nulo:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 14 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            truncated: { $trunc: [ "$data", null ] }
          }
     }
   ]
)

Resultado:
{ "data" : null, "truncated" : null }

Truncar o infinito


Se o número a ser truncado for Infinity , o resultado é Infinity . Da mesma forma, se for -Infinity , o resultado é -Infinity .

Vamos adicionar dois documentos com esses valores:
{ "_id" : 15, "data" : Infinity }
{ "_id" : 16, "data" : -Infinity }

E vamos truncá-los:
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 }

Truncar NaN


Truncando NaN resulta em 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 não numéricos


Se você tentar truncar um valor que é o tipo de dados errado (ou seja, não é um inteiro, duplo, decimal ou longo), um erro será retornado.

Suponha que adicionamos o seguinte documento à nossa coleção:
{ "_id" : 17, "data" : "Thirty five" }

E agora tentamos truncar os 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