Trong MongoDB, $range
toán tử đường ống tổng hợp trả về một chuỗi số được tạo trong một mảng.
Dãy số này dựa trên các giá trị đầu vào mà bạn cung cấp.
Cú pháp
Cú pháp như sau:
{ $range: [ <start>, <end>, <non-zero step> ] }
Ở đâu <start>
là bắt đầu và <end>
là phần cuối của dãy. Mỗi trong số này có thể là bất kỳ biểu thức hợp lệ nào phân giải thành số nguyên.
<non-zero step>
là một đối số tùy chọn mặc định là 1. Đối số này cho phép bạn chỉ định một giá trị gia tăng. Nếu được cung cấp, nó phải là một biểu thức hợp lệ phân giải thành một số nguyên khác 0.
Ví dụ
Giả sử chúng ta có một bộ sưu tập có tên là range
với các tài liệu sau:
{ "_id" : 1, "start" : 0, "end" : 5 } { "_id" : 2, "start" : 1, "end" : 5 }
Chúng ta có thể sử dụng $range
để trả về một mảng dựa trên các giá trị trong các tài liệu đó.
db.range.aggregate(
[
{ $match: { _id: { $in: [ 1, 2 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end" ] }
}
}
]
)
Kết quả:
{ "start" : 0, "end" : 5, "result" : [ 0, 1, 2, 3, 4 ] } { "start" : 1, "end" : 5, "result" : [ 1, 2, 3, 4 ] }
Trong trường hợp này, chúng tôi không cung cấp đối số thứ ba và vì vậy $range
sử dụng giá trị bước mặc định của nó là 1. Do đó, các phần tử mảng tăng lên 1.
Thêm phần gia tăng rõ ràng
Chúng ta có thể thêm đối số thứ ba để chỉ định rõ ràng mỗi phần tử mảng sẽ tăng lên bao nhiêu.
Giả sử bộ sưu tập của chúng tôi chứa các tài liệu sau:
{ "_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 }
Các tài liệu này có step
và vì vậy chúng tôi có thể sử dụng trường đó cho giá trị tăng dần cho tài liệu tương ứng.
Bây giờ hãy áp dụng $range
vào các tài liệu đó và bao gồm step
trường làm đối số thứ ba:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 3, 4, 5, 6 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
step: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Kết quả:
{ "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 ] }
Giá trị bước phủ định
Bước có thể là một giá trị âm, mặc dù điều này cần được thực hiện trong bối cảnh giảm từ start
cao hơn số thành end
thấp hơn con số.
Hãy thêm một vài tài liệu khác vào bộ sưu tập của chúng tôi:
{ "_id" : 7, "start" : 0, "end" : 5, "step" : -1 } { "_id" : 8, "start" : 5, "end" : 0, "step" : -1 } { "_id" : 9, "start" : 0, "end" : -5, "step" : -1 }
Bây giờ hãy áp dụng $range
đối với các tài liệu đó:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 7, 8, 9 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
step: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Kết quả:
{ "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 ] }
Chúng ta có thể thấy rằng tài liệu đầu tiên trả về một mảng trống vì giá trị bước âm nằm ngoài phạm vi được cung cấp bởi start
và end
các lĩnh vực.
Tuy nhiên, các tài liệu tiếp theo tạo ra một phạm vi giá trị giảm dần.
Khi bước bằng không
Giá trị bước phải là một số nguyên khác không. Cung cấp một bước 0
trả về một lỗi.
Giả sử chúng ta thêm tài liệu sau vào bộ sưu tập của mình:
{ "_id" : 10, "start" : 1, "end" : 5, "step" : 0 }
Đây là những gì sẽ xảy ra khi chúng tôi áp dụng $range
vào tài liệu đó:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 10 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Kết quả:
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
Thông báo lỗi cho chúng tôi biết rõ ràng rằng $range requires a non-zero step value
.
Các bước vô hiệu
Bước không được null
một trong hai.
Giả sử chúng ta có tài liệu sau:
{ "_id" : 11, "start" : 1, "end" : 5, "step" : null }
Và chúng tôi áp dụng $range
với nó:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 11 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Kết quả:
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
Điều này cho chúng tôi biết rằng $range requires a numeric step value, found value of type:null
.
Dãy rỗng
Nếu start
và / hoặc end
các trường null
, sau đó một lỗi được trả về.
Giả sử chúng ta có tài liệu sau:
{ "_id" : 11, "start" : 1, "end" : 5, "step" : null }
Và áp dụng $range
với nó:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 11 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Kết quả:
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
Điều này cho chúng tôi biết rằng $range requires a numeric starting value, found value of type: null
.
Một thông báo tương tự sẽ xuất hiện nếu giá trị cuối cùng là null.
Đây là tài liệu có null
giá trị cuối:
{ "_id" : 13, "start" : 1, "end" : null, "step" : 1 }
Hãy áp dụng $range
:
db.range.aggregate(
[
{ $match: { _id: { $in: [ 13 ] } } },
{
$project:
{
_id: 0,
start: 1,
end: 1,
result: { $range: [ "$start", "$end", "$step" ] }
}
}
]
)
Kết quả:
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
Lần này, nó cho chúng ta biết rằng $range requires a numeric ending value, found value of type: null
.