В MongoDB, $trunc
Операторът на конвейера за агрегиране съкращава число до цяло число или до определен десетичен знак.
Имате възможност да посочите колко десетични знака, за които да съкратите числото. За да направите това, предайте втори аргумент. Първият аргумент е числото, което трябва да се съкрати, а вторият (по избор) аргумент е броят на десетичните знаци, до които да се съкрати.
Пропускането на втория аргумент съкращава всички цифри вдясно от десетичната запетая и връща цялата стойност на цяло число.
Пример
Да предположим, че имаме колекция, наречена test
със следните документи:
{ "_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 }
Можем да използваме $trunc
оператор за съкращаване на стойностите в data
поле:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Резултат:
{ "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 }
Забележете, че $trunc
не закръглява числа като $round
прави. $trunc
операторът просто съкращава числото. Ако бяхме приложили $round
към тази колекция, първият и четвъртият документ биха били закръглени до 9
и -9
съответно.
Посочете десетичен знак
Имаме възможност да използваме втори аргумент, за да посочим до колко десетични знака да съкратим числото.
Пример:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 1 ] }
}
}
]
)
Резултат:
{ "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 }
Отново, това просто съкращава числото. Ако използвахме $round
, би закръгляло някои от тези числа.
Отрицателни десетични знаци
Вторият аргумент може да бъде всеки валиден израз, който се разрешава до цяло число между -20 и 100, изключително. Следователно можете да посочите отрицателен знак след десетичната запетая.
Когато направите това, числото се съкращава вляво от десетичната запетая. Ако абсолютната стойност на отрицателното цяло число е по-голяма от броя на цифрите вляво от десетичната запетая, резултатът е 0
.
Да предположим, че добавяме следните документи към нашата колекция:
{ "_id" : 9, "data" : 8111.32 } { "_id" : 10, "data" : 8514.321 } { "_id" : 11, "data" : 8999.454 }
Ето пример за използване на различни отрицателни десетични знаци при прилагане на $trunc
към тези документи:
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()
Резултат:
{ "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 }
Десично място на нула
Когато предоставите десетичен знак 0
, $trunc
Операторът съкращава всички цифри вдясно от десетичната запетая и връща цялата стойност на цяло число.
Пример:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 0 ] }
}
}
]
)
Резултат:
{ "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 }
Типове числа
Числото за съкращаване може да бъде всеки валиден израз, който се разрешава до цяло число, двойно, десетично или дълго. Връщаната стойност съвпада с типа данни на входната стойност.
Така че, ако добавим следните документи към нашата колекция:
{ "_id" : 12, "data" : NumberDecimal("128.4585") } { "_id" : 13, "data" : NumberDecimal("128.12345678912") }
Можем да приложим $trunc
към data
поле:
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()
Резултат:
{ "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") }
Отрязване до нулеви десетични знаци
Ако вторият аргумент е null
, резултатът е null
.
Пример:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", null ] }
}
}
]
)
Резултат:
{ "data" : 8.99, "truncated" : null } { "data" : 8.45, "truncated" : null } { "data" : 8.451, "truncated" : null }
Отрязване на нулева стойност
Ако стойността, която трябва да бъде съкратена, е null
, резултатът е null
.
Да предположим, че добавяме следния документ към колекцията:
{ "_id" : 14, "data" : null }
И ние използваме $trunc
за да съкратите нулевата стойност:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 14 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", null ] }
}
}
]
)
Резултат:
{ "data" : null, "truncated" : null }
Отрязване на безкрайността
Ако числото, което трябва да бъде съкратено, е Infinity
, резултатът е Infinity
. По същия начин, ако е -Infinity
, резултатът е -Infinity
.
Нека добавим два документа с такива стойности:
{ "_id" : 15, "data" : Infinity } { "_id" : 16, "data" : -Infinity }
И нека ги съкратим:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 15, 16 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data", 2 ] }
}
}
]
)
Резултат:
{ "data" : Infinity, "truncated" : Infinity } { "data" : -Infinity, "truncated" : -Infinity }
Отрязване на NaN
Съкращаване на NaN
води до NaN
.
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" * 2 ] }
}
}
]
)
Резултат:
{ "data" : 8.99, "truncated" : NaN } { "data" : 8.45, "truncated" : NaN }
Нечислови типове
Ако се опитате да съкратите стойност, която е грешен тип данни (т.е. не е цяло число, двойна, десетична или дълга), се връща грешка.
Да предположим, че добавяме следния документ към нашата колекция:
{ "_id" : 17, "data" : "Thirty five" }
И сега се опитваме да съкратим data
поле:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 17 ] } } },
{
$project:
{
_id: 0,
data: 1,
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Резултат:
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