Trong MongoDB, bạn có thể sử dụng $subtract
toán tử đường ống tổng hợp để trừ số và / hoặc ngày.
Cụ thể, $subtract
có thể thực hiện ba điều sau:
- Trừ hai số để trả về số chênh lệch
- Trừ một số (tính bằng mili giây) cho một ngày và trả về ngày kết quả
- Trừ hai ngày để trả về chênh lệch tính bằng mili giây
$subtract
toán tử chấp nhận các giá trị làm đối số. Các đối số có thể là bất kỳ biểu thức hợp lệ nào miễn là chúng phân giải thành số và / hoặc ngày. Để trừ một số khỏi một ngày, ngày phải là đối số đầu tiên ..
Dữ liệu mẫu
Giả sử chúng ta có một tập hợp được gọi là data
với tài liệu sau:
{ "_id" : 1, "a" : 20000, "b" : 250, "start" : ISODate("2021-01-03T00:00:00Z"), "end" : ISODate("2021-01-03T23:30:15.100Z") }
Trừ các số
Chúng ta có thể sử dụng $subtract
toán tử để trừ a
từ trường b
trường (hoặc ngược lại).
Ví dụ:
db.data.aggregate(
[
{ $project: {
_id: 0,
a: 1,
b: 1,
result: {
$subtract: [ "$a", "$b" ] } }
}
]
)
Kết quả:
{ "a" : 20000, "b" : 250, "result" : 19750 }
Trừ một số khỏi một ngày
Nếu đối số đầu tiên là ngày và đối số thứ hai là số thì $subtract
toán tử trừ số khỏi ngày tính bằng mili giây.
Ví dụ:
db.data.aggregate(
[
{ $project: {
_id: 0,
b: 1,
start: 1,
result: {
$subtract: [ "$start", "$b" ] } }
}
]
).pretty()
Kết quả:
{ "b" : 250, "start" : ISODate("2021-01-03T00:00:00Z"), "result" : ISODate("2021-01-02T23:59:59.750Z") }
Chúng ta có thể thấy rằng 250 mili giây đã bị trừ đi trong ngày.
Khi chúng ta trừ một số khỏi một ngày, ngày phải là đối số đầu tiên với số là đối số thứ hai.
Đây là những gì sẽ xảy ra nếu chúng ta chuyển đổi các đối số xung quanh:
db.data.aggregate(
[
{ $project: {
_id: 0,
b: 1,
start: 1,
result: {
$subtract: [ "$b", "$start" ] } }
}
]
).pretty()
Kết quả:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "cant $subtract adate from a double", "code" : 16556, "codeName" : "Location16556" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
Chúng tôi gặp lỗi khi cho chúng tôi biết rằng nó không thể trừ một ngày thành một ngày.
Trả lại sự khác biệt giữa hai ngày
Nếu cả hai đối số là ngày tháng thì $subtract
toán tử trả về sự khác biệt giữa hai ngày tính bằng mili giây.
Ví dụ:
db.data.aggregate(
[
{ $project: {
_id: 0,
start: 1,
end: 1,
result: {
$subtract: [ "$end", "$start" ] } }
}
]
).pretty()
Kết quả:
{ "start" : ISODate("2021-01-03T00:00:00Z"), "end" : ISODate("2021-01-03T23:30:15.100Z"), "result" : NumberLong(84615100) }
Nếu chúng ta chuyển đổi ngày tháng, kết quả sẽ trở thành giá trị âm:
db.data.aggregate(
[
{ $project: {
_id: 0,
start: 1,
end: 1,
result: {
$subtract: [ "$start", "$end" ] } }
}
]
).pretty()
Kết quả:
{ "start" : ISODate("2021-01-03T00:00:00Z"), "end" : ISODate("2021-01-03T23:30:15.100Z"), "result" : NumberLong(-84615100) }
Vượt qua số lượng lập luận sai
$subtract
toán tử chấp nhận chính xác hai đối số. Chuyển sai số đối số dẫn đến lỗi.
Ví dụ:
db.data.aggregate(
[
{ $project: {
result: {
$subtract: [ "$a" ] } }
}
]
)
Kết quả:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "Invalid $project :: caused by :: Expression $subtract takes exactly 2 arguments. 1 were passed in.", "code" : 16020, "codeName" : "Location16020" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
Chuyển giá trị Null
Chuyển hai null
các giá trị dẫn đến null
được trả lại.
Ví dụ:
db.data.aggregate(
[
{ $project: {
result: {
$subtract: [ null, null ] } }
}
]
)
Kết quả:
{ "_id" : 1, "result" : null }