marc
marc

Reputation: 179

MongoDB Aggregate - How to use values of previous stage as a field name in next stage?

I have an aggregation query like this:

...
{
    '$unwind': {
      path: '$modifier'
    }
  }, {
    '$group': {
      '_id': {
        'date': {
          '$dateToString': {
            'format': '%d/%m/%Y', 
            'date': '$updatedTime'
          }
        }
      }, 
      '$$modifier': { '$sum': 1 }
    }
  },
...

and I would like to use modifier values, a result of the previous stage ($unwind), as a field in the next stage ($group). The detail is in the picture below. How should I accomplish it?

MongoDB aggregation question detailed picture

Current:

This is the output of $unwind stage:

updatedTime:2020-03-27T11:02:43.608+00:00
modifier:"[email protected]"
updatedTime:2020-03-27T11:02:43.608+00:00
modifier:"[email protected]"

This is the output of $group stage :

_id: { date:"27/03/2020" }
modifier:1

Expected:

the output of $unwind stage:

updatedTime:2020-03-27T11:02:43.608+00:00
modifier:"[email protected]"
updatedTime:2020-03-27T11:02:43.608+00:00
modifier:"[email protected]"

This is the output of $group stage:

_id: { date:"27/03/2022" }
[email protected]:1
[email protected]:1
total:2

Notice that "[email protected]" and "[email protected]" come from $unwind stage which is before $group stage. total is the total of modifier (examples: '[email protected]' and '[email protected]') values. Any suggestion is appreciated.

Upvotes: 2

Views: 1268

Answers (1)

turivishal
turivishal

Reputation: 36114

It's not straight but You need to group by both the properties date, email and do another group by only date and construct the array of modifiers and do replace that in root,

  • $group by updatedTime and modifier and get total count
  • $group by only date property and construct the array of object of modifier and count in key-value pair
  • $arrayToObject convert that key-value pair into object
  • $mergeObject to merge required properties like we added date property and above array to object operation result
  • $replaceRoot to replace above merged object in root of the document
  {
    "$group": {
      "_id": {
        "date": {
          "$dateToString": {
            "format": "%d/%m/%Y",
            "date": "$updatedTime"
          }
        },
        "modifier": "$modifier"
      },
      "count": { "$sum": 1 }
    }
  },
  {
    "$group": {
      "_id": "$_id.date",
      "modifiers": {
        "$push": {
          "k": "$_id.modifier",
          "v": "$count"
        }
      },
      "total": { "$sum": "$count" }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [
          { 
            "date": "$_id",
            "total": "$total"
          },
          { "$arrayToObject": "$modifiers" }
        ]
      }
    }
  }

Upvotes: 4

Related Questions