MongoDB - aggregate multiple fields in one query -
i'm developing monitoring system our company's production system. means nature of data i'll storing time-series. picked mongodb purpose, after reviewing several other databases. events production system arrive time, intend store events in 10-minute interval document. eventually, documents in collection this:
{ _id: '04/25/2015 13:00', event1_count : 130, event2_count : 50, event3_count : 200 }, { _id: '04/25/2015 13:10', event1_count : 230, event2_count : 20, event3_count : 400 }
the document _id: '04/25/2015 13:00'
means has events arrived between 04/25/2015 13:00 , 04/25/2015 13:10.
ultimately, i'll want different reports run on data. example - count of events within last 20 minutes. result event count in last 20 minute is:
{ event1_count : 360, event2_count : 70, event3_count : 600 }
my question - there way aggregate multiple fields different documents, in 1 query?
btw - it's important me keep data @ 10 minute interval, because other reports need time resolution.
yes it's indeed possible. suppose collection storing documents in above-mentioned structure, modify structure adding field date
stores _id isodate, rather string timestamp can aggregation using date operators. conversion, can use mongo's foreach()
cursor method atomic update $set
operator:
db.collection.find().foreach(function (doc){ var dateobject = new date(doc._id); db.collection.update({_id: doc._id}, { $set: { date: dateobject } }); });
the above create field date
in documents contains isodate object representation of _id
string.
suppose have following sample documents in collection after update above:
/* 0 */ { "_id" : "04/25/2015 13:00", "event1_count" : 130, "event2_count" : 50, "event3_count" : 200, "date" : isodate("2015-04-25t13:00:00.000z") } /* 1 */ { "_id" : "04/25/2015 13:10", "event1_count" : 230, "event2_count" : 20, "event3_count" : 400, "date" : isodate("2015-04-25t13:10:00.000z") } /* 2 */ { "_id" : "04/25/2015 13:20", "event1_count" : 240, "event2_count" : 30, "event3_count" : 350, "date" : isodate("2015-04-25t13:20:00.000z") } /* 3 */ { "_id" : "04/25/2015 13:30", "event1_count" : 180, "event2_count" : 60, "event3_count" : 500, "date" : isodate("2015-04-25t13:30:00.000z") }
the following aggregation pipeline give desired result, based on 20 minute interval:
var interval = 20, pipeline = [ { "$group": { "_id": { "year": { "$year": "$date" }, "dayofyear": { "$dayofyear": "$date" }, "interval": { "$subtract": [ { "$minute": "$date" }, { "$mod": [{ "$minute": "$date" }, interval ] } ] } }, "event1_count": { "$sum": "$event1_count" }, "event2_count": { "$sum": "$event2_count" }, "event3_count": { "$sum": "$event3_count" } } }, { "$project": { "_id": 0, "event1_count": 1, "event2_count": 1, "event3_count": 1 } } ]; db.collection.aggregate(pipeline);
output:
/* 0 */ { "result" : [ { "event1_count" : 420, "event2_count" : 90, "event3_count" : 850 }, { "event1_count" : 360, "event2_count" : 70, "event3_count" : 600 } ], "ok" : 1 }
Comments
Post a Comment