java - Group by query in a nested document -
document structure:
collection: mycollection
{ "_id" : objectid("578818ba8872933f6452c5b5"), "user" : objectid("578818ba8872933f6452c5b5") , "entries" : { "items" : [ { "_id" : objectid("578819018872933f6452c5ba") "date" : isodate("2016-07-14t22:57:58.715z"), "values" : [ { "type" : a, "value" : 4 }, { "type" : b, "value" : 3 }, ... ] }, ... ] } }
expected result
- group date (day wise, ignore time part)
average value each type
{ "_id" : "2016-07-14", "values" : [ { "type" : "a", "avgvalue" : 3.2 }, { "type" : "b", "avgvalue" : 4.2 }, ... ] }
tried did not help
db.getcollection('mycollection').aggregate( [ { "$match" : { "user" : objectid("578818ba8872933f6452c5b5") , "entries.items.date" : {"$gte" : new isodate("2016-07-11t00:00:00.715z"),"$lt" : new isodate("2016-07-18t00:00:00.715z")} } }, { "$unwind" : "entires.items"}, { "$unwind" : "$entries.items.values"}, { "$group" : { "_id" : { '$year' : '$entries.items.date','$month' : '$entries.items.date','$day' : '$entries.items.date' }, "values" : [{ "type": "$entries.items.values.type", "avgvalue" : { "$avg" : "$entries.items.values.value"} } ] } } ] )
what correct way of achieving result?
you can make 2 groups, 1 calculating average per type & date, pushing type & average value array , group these date :
in aggregate.js
:
var ret = db.device.aggregate( [{ "$match": { "user": objectid("578818ba8872933f6452c5b5"), "entries.items.date": { "$gte": new isodate("2016-07-11t00:00:00.715z"), "$lt": new isodate("2016-07-18t00:00:00.715z") } } }, { "$unwind": "$entries.items" }, { "$unwind": "$entries.items.values" }, { $project: { user: 1, entries: 1, day: { year: { $year: "$entries.items.date" }, month: { $month: "$entries.items.date" }, day: { $dayofmonth: "$entries.items.date" } } } }, { $project: { user: 1, entries: 1, day: { $concat: [{ $substr: ["$day.year", 0, 4] }, "-", { $substr: ["$day.month", 0, 2] }, "-", { $substr: ["$day.day", 0, 2] } ] } } }, { $group: { "_id": { "date": "$day", "type": "$entries.items.values.type" }, "avgvalue": { "$avg": "$entries.items.values.value" } } }, { $group: { "_id": "$_id.date", "values": { "$push": { "type": "$_id.type", "avgvalue": "$avgvalue" } } } }] ).toarray(); printjson(ret);
test :
mongo --quiet 127.0.0.1/yourdb aggregate.js
i used two projections before grouping because didn't grouping _id
working on system :
'$year' : '$entries.items.date','$month' : '$entries.items.date','$day' : '$entries.items.date'
i dont know if comes mongo version 2.6
result gives :
[ { "_id" : "2016-7-14", "values" : [ { "type" : "b", "avgvalue" : 4.5 }, { "type" : "a", "avgvalue" : 6 } ] } ]
Comments
Post a Comment