MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

MongoDB :Existe-t-il un moyen de détecter une tendance de valeur en utilisant l'agrégation ?

Schéma approximatif :je calculerais la moyenne pour la période de dix minutes :

> 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 }

Ensuite, je le stockerais dans une autre collection :

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

Enfin, rappelez les deux moyennes dont vous avez besoin pour calculer la différence, et calculez-la :

> 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

Vous pouvez également ignorer les agrégations périodiques et conserver à la place une moyenne mobile mise à jour dans sensor_averages , en passant à un nouveau document toutes les 10 minutes. Au début de chaque période de 10 minutes, insérez dans sensor_averages un document

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

puis à chaque insertion d'un sensor_reading document pendant les dix prochaines minutes, mettez également à jour les sensor_averages doc :

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

Ensuite, lorsque vous voulez la différence entre les moyennes, rappelez les deux documents appropriés, divisez svalues par nvalues pour obtenir la moyenne, et soustrayez.