Рамката на тръбопровода за агрегиране на MongoDB включва $round
оператор и $trunc
оператор. Тези оператори изпълняват подобни, но различни задачи.
Дефиниции
Първо, нека разгледаме дефинициите на всеки оператор:
$round
оператор кръгли число до цяло число или до определен десетичен знак.$truncate
оператор отрязва число до цяло число или до определен десетичен знак.
По принцип разликата е в думите кръгли срещу отрязване .
В някои случаи и двата оператора ще върнат един и същ резултат. В други случаи техните резултати ще се различават. Това е така, защото $round
операторът може да закръгли числото нагоре в зависимост от стойността. $truncate
операторът не закръгля числото. Вместо това просто го съкращава. С други думи, той просто изрязва числото, както е посочено, като оставя останалите цифри такива, каквито са.
Пример
Да предположим, че имаме колекция, наречена test
със следните документи:
{ "_id" :1, "data" :8,99 }{ "_id" :2, "data" :8,45 }{ "_id" :3, "data" :8,451 }{ "_id" :4, " данни" :-8,99 }{ "_id" :5, "данни" :-8,45 }{ "_id" :6, "данни" :-8,451 }{ "_id" :7, "данни" :8 }{ "_id " :8, "данни" :0 }{ "_id" :9, "данни" :0,5 }{ "_id" :10, "данни" :8111.32 }{ "_id" :11, "данни" :8514.321 }{ "_id" :12, "данни":8999.454 }
Ето какво се случва, когато приложим $round
и $truncate
към тези документи:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data" ] },
truncated: { $trunc: [ "$data" ] }
}
}
]
)
Резултат:
{ "данни" :0, "закръглени" :0, "скъсени" :0 }{ "данни" :8, "закръглени" :8, "скъсени" :8 }{ "данни" :0,5, "закръглени" " :0, "осечено" :0 }{ "данни" :0,9, "закръглено" :1, "скъсено" :0 }{ "данни" :8,99, "закръглено" :9, "осечено" :8 }{ " данни" :8,45, "закръглено" :8, "осечено" :8 }{ "данни" :8,451, "закръглено" :8, "осечено" :8 }{ "данни" :-8,99, "закръглено" :-9 , "осечено" :-8 }{ "данни" :-8,45, "закръглено" :-8, "осечено" :-8 }{ "данни" :-8,451, "закръглено" :-8, "осечено" :- 8 }
Виждаме, че в някои случаи резултатът е същият. В други е различно. Например, когато входната стойност е 0.9
, $round
операторът закръгля числото до 1
. $truncate
операторът от друга страна просто премахва .9
част, която произвежда резултат от 0
.
Отрицателни дробни места
И двата оператора приемат незадължителен втори аргумент. Когато присъства, този аргумент указва броя на десетичните знаци, до които да се закръгли/съкрати числото.
Предоставянето на този втори аргумент може допълнително да подчертае разликата между двата оператора.
Пример:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", 1 ] },
truncated: { $trunc: [ "$data", 1 ] }
}
}
]
)
Резултат:
{ "данни" :0, "закръглени" :0, "скъсени" :0 }{ "данни" :8, "закръглени" :8, "скъсени" :8 }{ "данни" :0,5, "закръглени" " :0,5, "отсечени" :0,5 }{ "данни" :0,9, "закръглени" :0,9, "осечени" :0,9 }{ "данни" :8,99, "закръглени" :9, "осечени" :8,9 }{ " данни" :8,45, "закръглени" :8,4, "скъсени" :8,4 }{ "данни" :8,451, "закръглени" :8,5, "скъсени" :8,4 }{ "данни" :-8,99, "закръглени" :-9 , "осечено" :-8,9 }{ "данни" :-8,45, "закръглено" :-8,4, "осечено" :-8,4 }{ "данни" :-8,451, "закръглено" :-8,5, "осечено" :- 8.4 }
Отново можем да видим, че някои резултати са идентични, докато други не са.
Отрицателни дробни места
И двата оператора приемат отрицателна стойност за втория аргумент.
Пример:
db.test.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
rounded: { $round: [ "$data", -1 ] },
truncated: { $trunc: [ "$data", -1 ] }
}
}
]
)
Резултат:
{ "данни" :0, "закръглени" :0, "скъсени" :0 }{ "данни" :8, "закръглени" :10, "скъсени" :0 }{ "данни" :0,5, "закръглени" " :0, "осечено" :0 }{ "данни" :0,9, "закръглено" :0, "скъсено" :0 }{ "данни" :8,99, "закръглено" :10, "осечено" :0 }{ " данни" :8,45, "закръглени" :10, "скъсени" :0 }{ "данни" :8,451, "закръглени" :10, "осечени" :0 }{ "данни" :-8,99, "закръглени" :-10 , "осечено" :0 }{ "данни" :-8,45, "закръглено" :-10, "осечено" :0 }{ "данни" :-8,451, "закръглено" :-10, "осечено" :0 }предварително>Този път има ярък контраст между резултатите, получени от двата оператора.
$trunc
произведен оператор0
за всеки документ, докато$round
операторът върна различни стойности, повечето от които бяха закръглени нагоре или надолу.$floor и $ceil
Още два оператора, които трябва да имате предвид, когато извършвате операции като тази, са
$floor
и$ceil
. Тези оператори работят по подобен начин, но малко по-различен.
$floor
връща най-големия цяло число, по-малко или равно на посоченото число$ceil
връща най-малкия цяло число, по-голямо или равно на посоченото число.