MongoDB : Is there a way to detect a value trend using aggregation?

后端 未结 2 1684
心在旅途
心在旅途 2021-01-25 10:01

I\'m trying to detect the \"trend\" of a value in a collection.

Let\'s say I have the following:

{ created_at: 2014-12-01, value:1015 }
{ created_at: 201         


        
2条回答
  •  臣服心动
    2021-01-25 10:51

    Rough outline: I would calculate the average for the ten minute period:

    > var avgCursor = db.sensor_readings.aggregate([
        { "$match" : { "created_at" : { "$gt" : ten_minutes_ago, "$lte" : now } } }
        { "$group" : { "_id" : 0, "average" : { "$avg" : "$value" } } }
    ]}
    > var avgDoc = avgCursor.toArray()[0]
    > avgDoc
    { "_id" : 0, "average" : 23 }
    

    Then I would store it in another collection:

    > db.sensor_averages.insert({ "start" : ten_minutes_ago, "end" : now, "average" : avgDoc.average })
    

    Finally, recall the two averages you need to compute the difference, and compute it:

    > var diffCursor = db.sensor_averages.find({ "start" : { "$gte" : twenty_minutes_ago } }).sort({ "start" : -1 })
    > var diffArray = diffCursor.toArray()
    > var difference = diffArray[0].average - diffArray[1].average
    

    You could also skip the periodic aggregations and instead keep a running average updated in sensor_averages, jumping to a new doc every 10 minutes. At the beginning of each 10 minute period, insert into sensor_averages a doc

    {
        "start" : now,
        "svalues" : 0,
        "nvalues" : 0
    }
    

    then on each insert of a sensor_reading document for the next ten minutes, also update the sensor_averages doc:

    db.sensor_averages.update(
        { "start" : now_rounded_to_the_ten_minute_boundary },
        { "$inc" : { "svalues" : value, "nvalues" : 1 } }
    )
    

    Then, when you want the difference between averages, recall the appropriate two docs, divide svalues by nvalues to get the average, and subtract.

提交回复
热议问题