Reputation: 5174
I have a collection which contains data like:
{
attribute: 'value',
date: ISODate("2016-09-20T18:51:05Z")
}
and I want to group by attribute
to get a total count per attribute and at the same time group by attribute
and $hour
to get a count per attribute and hour.
I know I can do something like:
{
$group: {
_id: '$attribute'
count: {
$sum: 1
}
}
}
and
{
$group: {
_id: {
attribute : '$attribute',
hour: {
'$hour' : '$date'
}
},
count: {
$sum: 1
}
}
},
{
$group: {
_id: {
attribute: '$_id.attribute'
},
hours: {
'$push': {
hour: '$_id.hour',
count: '$count'
}
}
}
}
to get both results in two separate aggregations, but is there a way to get the result I want in one query?
Edit as requested:
Perhaps this is utterly wrong but ideally I would like to get a response like:
{
_id: "attribute1",
total: 20, // Total number of attribute1 documents
// And the breakdown of those 20 documents per hour
hours: [{
hour: 10,
count: 8
},
{
hour: 14,
count: 12
}]
}
However the whole point of the question is whether this can be done (and how) on one query in mongodb. Not in two queries that would be merged on the application layer
Upvotes: 1
Views: 1653
Reputation: 10662
You can first group by attribute-hour pairs and their corresponding occurrences.
Then, you project the attribute, a pair of hour-count, and a copy of that count.
Finally, you group by the attribute alone, $push
the pairs, and sum the counts.
[
{
$group: {
_id: {
attribute: "$attribute",
hour: { "$hour": "$date" }
},
count: {
$sum: 1
}
}
},
{
$project: {
attribute: "$_id.attribute",
pair: { hour: "$_id.hour", count: "$count" },
count: "$count",
_id: 0
}
},
{
$group: {
_id: "$attribute",
hours: {
$push: "$pair"
},
total: {
$sum: "$count"
}
}
}
]
Upvotes: 1