I have documents in mongo db, like
doc = {
name = MyName,
tags = tag1,tag2,tag3,
...
}
When I search documents by name, I also want to get analytics of tags, for docs with that name, like
{
tag1: 7,
tag2: 5,
...
tagn: 14
}
How can I aggregate it?
CodePudding user response:
The data model complicates the query somewhat and the required output format complicates it even more ... but here's one way to do it.
db.collection.aggregate([
{
"$set": {
"tags": {
"$split": ["$tags", ","]
}
}
},
{"$unwind": "$tags"},
{
"$set": {
"tags": {
"$trim": {"input": "$tags"}
}
}
},
{
"$group": {
"_id": "$tags",
"count": {"$count": {}}
}
},
{
"$sort": {"_id": 1}
},
{
"$group": {
"_id": null,
"newRoot": {
"$mergeObjects": {
"$arrayToObject": [
[
{
"$reduce": {
"input": {"$objectToArray": "$$ROOT"},
"initialValue": {},
"in": {
"$mergeObjects": [
"$$value",
{
"$switch": {
"branches": [
{
"case": {"$eq": ["$$this.k", "_id"]},
"then": {"k": "$$this.v"}
},
{
"case": {"$eq": ["$$this.k", "count"]},
"then": {"v": "$$this.v"}
}
],
"default": "$$value"
}
}
]
}
}
}
]
]
}
}
}
},
{"$replaceWith": "$newRoot"}
])
Example output:
[
{
"tag1": 2,
"tag2": 2,
"tag3": 3,
"tag5": 1,
"tag7": 1
}
]
Try it on mongoplayground.net.