Reputation: 85
I'm trying to count documents containing { date, direction, procedure } e.g {'Dec 12', 'West', 'Up' }
and I want output: foreach date, foreach direction, count each procedure type
Dec 12
North Up 2 Down 3
South Up 4 Down 17
etc
It's fairly easy using javascript but I'd like to use mongodb if possible. I can't get aggregate group to filter more than one level and I'm not sure if map_reduce would help. I don't properly understand either.
I would appreciate a little guidance. Thanks
Some detail: It's a schema-less collection but the interesting bits look like this:
{ "_id" : ObjectId(), "direction" : String, "procedure" : String, "date" : String, .... , "format" : "procedure" }
date: "Mmm dd"
.... lots of other stuff
The output is not critical - it could be:
[ { date: "Mmm dd",
direction: { procedure: count, procedure: count },
direction: { procedure: count, ... },
....
}
{ ... }
...
]
e.g:
[ { date: "Dec 12",
"West": { "Arrive": 5, "Depart": 5 },
"East": { "Arrive": 1, "Depart": 7 },
...
},
{ date: ...},
...
]
The more I play with it the more I think it's a bit of a stretch - That could be good advise :-)
Upvotes: 0
Views: 74
Reputation: 1334
This is a solution for your aggregation pipeline:
[{
'$group': {
'_id': {
'date': '$date',
'direction': '$direction',
'procedure': '$procedure'
},
'count': {'$sum': 1}
}
},
{
'$group': {
'_id': '$_id.date',
'directions': {
'$push': {
'direction': '$_id.direction',
'procedure': '$_id.procedure',
'count': '$count'
}
}
}
}]
Giving the following result:
{
_id: "Dec 12",
directions: [
{ "direction": "North", "procedure": "Arrive", "count": 5},
{ "direction": "North", "procedure": "Depar", "count": 3},
{ "direction": "South", "procedure": "Arrive", "count": 1},
...
]
},
...
Basically what you are asking for is a count for each (date, direction, procedure)
tuple. You just want it to be a little reorganized, and more precisely: grouped by date with for each date all possible (direction, procedure)
couples, and the corresponding count.
So we are exactly doing this:
first $group
stage in the pipeline groups by unique (date, direction, procedure)
, putting them in the _id
field, and counting occurences; at this stage the output is:
[{ _id: { date: "Dec 12", direction: "North", procedure: "Depar" }, count: 4 }, ... ]
second $group
stage just re-groups the results by date pushing other fields (which are embedded in a document at the _id
field, as result of the previous stage) into an array at the new directions
field, as (direction, procedure, count)
tuples with the same date.
Upvotes: 2