MongoDB Group and Subtract Values from Different Documents

后端 未结 1 1192
情歌与酒
情歌与酒 2021-02-10 00:29

In my application I have the following documents

{
   \"timestamp\": ISODate(\"2015-09-17T21:14:35.0Z\"),
   \"sensor\": \"gas-in\",
   \"value\": 2.5,
},
{
   \         


        
1条回答
  •  臣服心动
    2021-02-10 01:19

    What you first need is a conditional $sum based on the $cond operator in the grouping for each value. Then you can separately $subtract:

    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" ] }
        }}
    ])
    

    Which gives the results:

    { "_id" : ISODate("2015-09-17T21:20:35Z"), "gasdifference" : 5.5 }
    { "_id" : ISODate("2015-09-17T21:14:35Z"), "gasdifference" : 0.5 }
    

    The alternate is just make the "gas-out" values negative for a single stage:

    db.gas.aggregate([
        { "$group": {
            "_id": "$timestamp",
            "gasdifference": { 
                "$sum": { 
                    "$cond": [
                        { "$eq": [ "$sensor", "gas-in" ] },
                        "$value", 
                        { "$subtract": [ 0, "$value" ] }
                    ]
                }
            }
        }}
    ])
    

    And that's going to be more efficient.

    If you have more than two possible "sensor" values then you just "nest" the $cond statements:

    db.gas.aggregate([
        { "$group": {
            "_id": "$timestamp",
            "gasdifference": { 
                "$sum": { 
                    "$cond": [
                        { "$eq": [ "$sensor", "gas-in" ] },
                        "$value", 
                        { "$cond": [
                            { "$eq": [ "$sensor", "gas-out" ] },
                            { "$subtract": [ 0, "$value" ] },
                            0
                        ]}
                    ]
                }
            }
        }}
    ])
    

    Since they are "ternary" operators ( if-then-else ) then any further logic falls within the "else" condition.

    0 讨论(0)
提交回复
热议问题