Home > database >  MongoDB - aggregation using map within map
MongoDB - aggregation using map within map

Time:06-02

Is it possible map an array, within an array of objects?

I currently have this addFields pipeline stage and the code in question is the second array element for the $setUnion aggregator. It currently returns the arrays in which the values I need are in, so I end up with a 'users' array made up of arrays (from the second map stage), and then string values from the other items in the setUnion array code, but I just need all the string values from the nested array.

Document example output after addField currently:

{   
    _id: '6291f69f811b414175d11b16',
    savesOnComment: [],
    comments: [{
            _id: '6297aa1112c9fe003a32ddeb',
            owner: '61152b692816b44ff246e07b',
            contentId: '6291f69f811b414175d11b16',
            replyId: null,
            saves: ['61152b692816b44ff246e07b']
        }, {
            _id: '6297aa1512c9fe003a32dded',
            owner: '61152b692816b44ff246e07b',
            contentId: '6291f69f811b414175d11b16',
            replyId: null,
            saves: ['61152b692816b44ff246e07b']
        }],
    users: [
        ['61152b692816b44ff246e07b'],
        '61152b692816b44ff246e07b',
        ]
                
}

addFields pipeline stage:

{
      'users': {
        '$setUnion': [{
          '$map': {
            'input': '$comments',
            'as': 'each',
            'in': '$$each.owner'
          }
        }, {
          '$map': {
            'input': '$comments',
            'as': 'each',
            'in': {
              '$map': {
                'input': '$$each.saves',
                'as': 'save',
                'in': '$$save'
              }
            }
          }
        }, 
        '$savesOnComment']
      }
    }

CodePudding user response:

There are many ways to do this. Here's one way using "$reduce" to "extract" the "comments.saves" contents, essentially flattening it so "$setUnion" provides the output you want.

db.collection.aggregate([
  {
    "$set": {
      "users": {
        "$setUnion": [
          "$savesOnComment",
          "$comments.owner",
          {
            "$reduce": {
              "input": "$comments.saves",
              "initialValue": [],
              "in": {
                "$concatArrays": [ "$$value", "$$this" ]
              }
            }
          }
        ]
      }
    }
  }
])

Try it on mongoplayground.net.

  • Related