I have the following document structure in MongoDB:
{
// other keys,
tags: [
tagA: "red",
tagB: "green"
]
},
{
// other keys,
tags: [
tagA: "orange",
tagB: "green",
tagC: "car"
]
}
I want to perform a $facets search that gives me the following output (name of each tag + values that occur on that tag + count of these value):
{
[
tagA: {
red: 1,
orange: 1
},
tagB: {
green: 2
},
tagC: {
car: 1
}
]
}
The tricky part is that the facets are unknown upfront (they can vary), and every tutorial I found only works for a predefined set of facets.
Is it possible?
P.S.: how to get the output of this to come alongside with a given query? So that the return is something like:
{
queryResults: [all the results, as in a normal query],
facets: [result showed in accepted answer]
}
If you consider having this as input (i've added bracket around object in your array) :
You could then do an aggregation pipeline as follow :
It would give you this result :
You can see this on mongoplayground : https://mongoplayground.net/p/FZbM-BGJRBm Hope this answer your question.
Detailled explanation :
$unwindon thetagsfield in order to get one object per object in tags array.$objectToArrayto get keys (tagsA,tagsB) as values.$unwindto go from an array to objets.$groupwith$sumaccumulator to calculate the occurence of each unique combination.$groupbytagsA,tagsB, etc with$pushaccumulator to add value in array (will be usufull afterwards)$arrayToObjectto go from array to object$replaceRootto display results better.If you want to understand more each step, consider reading mongo doc of each pipeline aggregator i used. You can also use the mongoplayground link above, delete some code to see what happens after each step.