Điều bạn cần đầu tiên là $sum
có điều kiện
dựa trên $cond
toán tử trong nhóm cho mỗi giá trị. Sau đó, bạn có thể $subtract
một cách riêng biệt
:
db.gas.aggregate([
{ "$group": {
"_id": "$timestamp",
"gas-in": {
"$sum": {
"$cond": [
{ "$eq": [ "$sensor", "gas-in" ] },
"$value",
0
]
}
},
"gas-out": {
"$sum": {
"$cond": [
{ "$eq": [ "$sensor", "gas-out"] },
"$value",
0
]
}
},
}},
{ "$project": {
"gasdifference": { "$subtract": [ "$gas-in", "$gas-out" ] }
}}
])
Điều này mang lại kết quả:
{ "_id" : ISODate("2015-09-17T21:20:35Z"), "gasdifference" : 5.5 }
{ "_id" : ISODate("2015-09-17T21:14:35Z"), "gasdifference" : 0.5 }
Phương pháp thay thế chỉ là làm cho các giá trị "hết gas" âm cho một giai đoạn duy nhất:
db.gas.aggregate([
{ "$group": {
"_id": "$timestamp",
"gasdifference": {
"$sum": {
"$cond": [
{ "$eq": [ "$sensor", "gas-in" ] },
"$value",
{ "$subtract": [ 0, "$value" ] }
]
}
}
}}
])
Và điều đó sẽ hiệu quả hơn.
Nếu bạn có nhiều hơn hai giá trị "cảm biến" có thể có thì bạn chỉ cần "lồng" $cond
tuyên bố:
db.gas.aggregate([
{ "$group": {
"_id": "$timestamp",
"gasdifference": {
"$sum": {
"$cond": [
{ "$eq": [ "$sensor", "gas-in" ] },
"$value",
{ "$cond": [
{ "$eq": [ "$sensor", "gas-out" ] },
{ "$subtract": [ 0, "$value" ] },
0
]}
]
}
}
}}
])
Vì chúng là toán tử "bậc ba" (if-then-else) nên bất kỳ logic nào khác đều nằm trong điều kiện "else".