Home > Software engineering >  PyMongo get analytics by field for given query
PyMongo get analytics by field for given query

Time:09-10

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.

  • Related