В MongoDB, $range
Операторът на конвейера за агрегиране връща генерирана последователност от числа в масив.
Тази последователност от числа се основава на въведените от вас стойности.
Синтаксис
Синтаксисът е така:
{ $range: [ <start>, <end>, <non-zero step> ] }
Където <start>
е началото и <end>
е краят на поредицата. Всеки от тях може да бъде всеки валиден израз, който се разрешава до цяло число.
<non-zero step>
е незадължителен аргумент, който по подразбиране е 1. Този аргумент ви позволява да зададете стойност на увеличение. Ако е предоставен, той трябва да е валиден израз, който се разрешава до цяло число, различно от нула.
Пример
Да предположим, че имаме колекция, наречена range
със следните документи:
{ "_id" : 1, "start" : 0, "end" : 5 } { "_id" : 2, "start" : 1, "end" : 5 }
Можем да използваме $range
оператор, за да върне масив въз основа на стойностите в тези документи.
db.range.aggregate(
[
{ $match: { _id: { $in: [ 1, 2 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end" ] }
}
}
]
)
Резултат:
{ "start" : 0, "end" : 5, "result" : [ 0, 1, 2, 3, 4 ] } { "start" : 1, "end" : 5, "result" : [ 1, 2, 3, 4 ] }
В този случай не предоставихме трети аргумент и така $range
използва стойността на стъпката по подразбиране 1. Следователно елементите на масива се увеличават с 1.
Добавяне на изрично увеличение
Можем да добавим трети аргумент, за да посочим изрично с колко трябва да се увеличава всеки елемент от масива.
Да предположим, че нашата колекция съдържа следните документи:
{ "_id" : 3, "start" : 0, "end" : 5, "step" : 1 } { "_id" : 4, "start" : 0, "end" : 10, "step" : 2 } { "_id" : 5, "start" : 1, "end" : 10, "step" : 2 } { "_id" : 6, "start" : 100, "end" : 150, "step" : 10 }
Тези документи имат step
поле и така можем да използваме това поле за нарастваща стойност за съответния документ.
Сега нека приложим $range
към тези документи и включете step
поле като трети аргумент:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 3, 4, 5, 6 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
step: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Резултат:
{ "start" : 0, "end" : 5, "step" : 1, "result" : [ 0, 1, 2, 3, 4 ] } { "start" : 0, "end" : 10, "step" : 2, "result" : [ 0, 2, 4, 6, 8 ] } { "start" : 1, "end" : 10, "step" : 2, "result" : [ 1, 3, 5, 7, 9 ] } { "start" : 100, "end" : 150, "step" : 10, "result" : [ 100, 110, 120, 130, 140 ] }
Отрицателни стойности на стъпката
Стъпката може да бъде отрицателна стойност, въпреки че това трябва да се направи в контекста на намаляване от по-висок start
номер до по-нисък end
номер.
Нека добавим още няколко документа към нашата колекция:
{ "_id" : 7, "start" : 0, "end" : 5, "step" : -1 } { "_id" : 8, "start" : 5, "end" : 0, "step" : -1 } { "_id" : 9, "start" : 0, "end" : -5, "step" : -1 }
Сега нека приложим $range
към тези документи:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 7, 8, 9 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
step: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Резултат:
{ "start" : 0, "end" : 5, "step" : -1, "result" : [ ] } { "start" : 5, "end" : 0, "step" : -1, "result" : [ 5, 4, 3, 2, 1 ] } { "start" : 0, "end" : -5, "step" : -1, "result" : [ 0, -1, -2, -3, -4 ] }
Можем да видим, че първият документ върна празен масив, тъй като отрицателната стойност на стъпката е извън диапазона, предоставен от start
и end
полета.
Следващите документи обаче дадоха намаляващ диапазон от стойности.
Когато стъпката е нула
Стойността на стъпката трябва да е цяло число, различно от нула. Предоставяне на стъпка от 0
връща грешка.
Да предположим, че добавяме следния документ към нашата колекция:
{ "_id" : 10, "start" : 1, "end" : 5, "step" : 0 }
Ето какво се случва, когато приложим $range
към този документ:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 10 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Резултат:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$range requires a non-zero step value", "code" : 34449, "codeName" : "Location34449" } : 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
Съобщението за грешка изрично ни казва, че $range requires a non-zero step value
.
Нулеви стъпки
Стъпката не може да бъде null
или.
Да предположим, че имаме следния документ:
{ "_id" : 11, "start" : 1, "end" : 5, "step" : null }
И ние прилагаме $range
към него:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 11 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Резултат:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$range requires a numeric step value, found value of type:null", "code" : 34447, "codeName" : "Location34447" } : 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
Това ни казва, че $range requires a numeric step value, found value of type:null
.
Нулеви диапазони
Ако start
и/или end
полетата са null
, след което се връща грешка.
Да предположим, че имаме следния документ:
{ "_id" : 11, "start" : 1, "end" : 5, "step" : null }
И приложете $range
към него:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 11 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Резултат:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$range requires a numeric starting value, found value of type: null", "code" : 34443, "codeName" : "Location34443" } : 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
Това ни казва, че $range requires a numeric starting value, found value of type: null
.
Подобно съобщение ще се появи, ако крайната стойност е нула.
Ето документ с null
крайна стойност:
{ "_id" : 13, "start" : 1, "end" : null, "step" : 1 }
Нека приложим $range
:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 13 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Резултат:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$range requires a numeric ending value, found value of type: null", "code" : 34445, "codeName" : "Location34445" } : 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
Този път ни казва, че $range requires a numeric ending value, found value of type: null
.