Mongo Aggregation Help: Facets Breakdown
Closed this issue · 0 comments
Currently, you can search for e.g. the age range distribution of survey respondents and get data that looks like this:
{
"data": {
"survey": {
"demographics": {
"age": {
"year": {
"buckets": [
{
"id": "range_less_than_10",
"count": 3,
"percentage": 0
},
{
"id": "range_10_18",
"count": 95,
"percentage": 1.5
},
{
"id": "range_18_24",
"count": 678,
"percentage": 10.4
},
{
"id": "range_25_34",
"count": 3289,
"percentage": 50.6
},
{
"id": "range_35_44",
"count": 1901,
"percentage": 29.2
},
{
"id": "range_45_54",
"count": 433,
"percentage": 6.7
},
{
"id": "range_55_64",
"count": 83,
"percentage": 1.3
},
{
"id": "range_more_than_65",
"count": 18,
"percentage": 0.3
}
]
}
}
}
}
}
}
You can also filter this by e.g. gender to limit the results to women.
But I would like to add an option to group the results by gender (or any other demographic "facet" – not sure if that's the proper term by the way?). So the resulting data would look something like this:
{
"data": {
"survey": {
"demographics": {
"age": {
"year": {
"facets": [
{
"type": "gender", // could be "country", "age", "salary", etc.
"id": "female", // the value we're currently grouping by
"buckets": [
{
"id": "range_less_than_10",
"count": 3,
"percentage": 0
},
{
"id": "range_10_18",
"count": 95,
"percentage": 1.5
},
{
"id": "range_18_24",
"count": 678,
"percentage": 10.4
},
{
"id": "range_25_34",
"count": 3289,
"percentage": 50.6
},
{
"id": "range_35_44",
"count": 1901,
"percentage": 29.2
},
{
"id": "range_45_54",
"count": 433,
"percentage": 6.7
},
{
"id": "range_55_64",
"count": 83,
"percentage": 1.3
},
{
"id": "range_more_than_65",
"count": 18,
"percentage": 0.3
}
]
},
{
"type": "gender",
"id": "male",
"buckets": [
{
"id": "range_less_than_10",
"count": 3,
"percentage": 0
},
{
"id": "range_10_18",
"count": 95,
"percentage": 1.5
}
// etc.
]
},
{
"type": "gender",
"id": "non_binary",
"buckets": [
// ...
]
}
]
}
}
}
}
}
}
The current Mongo aggregation pipeline is fairly simple:
const pipeline = [
{
$match: match
},
{
$unwind: {
path: `$${key}`
}
},
{
$group: {
_id: {
id: `$${key}`,
year: '$year'
},
count: { $sum: 1 }
}
},
{
$project: {
_id: 0,
id: '$_id.id',
year: '$_id.year',
count: 1
}
},
{ $sort: { [sort]: order } }
]
I'm guessing I need to add a second $group
stage, but I'm not quite sure how to do it…
Also note that the facet that items are grouped by will be set dynamically (or can be empty, in which case the facets
array would just contain a single element with "type": "default"
and "id": "default"
).