Search code examples
arraysmongodbaggregate

How to add value in parent from each child array of object field in mongodb


I cannot add the fields on each element in an array

I use mongodb 3.6, let say that I have a this documents in mongodb

[
  {
    "_id": ObjectId("648fc2857edfa7ee4f1ce31c"),
    "userId": "1",
    "groups": [
      {
        "_id": ObjectId("648fc2857edfa7ee4f1ce31d"),
        "groupId": "1",
        "groupLeads": [
          {
            "userId": "4"
          },
          {
            "userId": "5"
          }
        ]
      },
      {
        "_id": ObjectId("648fc2857edfa7ee4f1ce31d"),
        "groupId": "2",
        "groupLeads": [
          {
            "userId": "2"
          },
          {
            "userId": "3"
          }
        ]
      }
    ]
  },
]

I want to add a field under the groups array lets called gLead so I use the aggregate function to do that like this

db.collection.aggregate([
  {
    "$addFields": {
      "groups.gLead": {
        "$map": {
          "input": "$groups",
          "as": "g",
          "in": "$$g.groupLeads.userId"
        }
      }
    }
  }
])

why the query return like this on first array

{
  "_id": ObjectId("648fc2857edfa7ee4f1ce31d"),
  "gLead": [
    [
      "4",
      "5"
    ],
    [
      "2",
      "3"
    ]
  ],
  "groupId": "1",
  "groupLeads": [
    {
      "userId": "4"
    },
    {
      "userId": "5"
    }
  ]
},

instead of

{
  "_id": ObjectId("648fc2857edfa7ee4f1ce31d"),
  "gLead": [ "4", "5" ],
  "groupId": "1",
  "groupLeads": [
    {
      "userId": "4"
    },
    {
      "userId": "5"
    }
  ]
},

what query of aggregate should I use?

mongodb playground: https://mongoplayground.net/p/xokkBwgRR2s


Solution

  • Are you looking for a pipeline that $mergeObjects the $mapped information together? Something like this:

    db.collection.aggregate([
      {
        "$addFields": {
          groups: {
            "$map": {
              "input": "$groups",
              "as": "g",
              "in": {
                "$mergeObjects": [
                  "$$g",
                  {
                    gLead: "$$g.groupLeads.userId"
                  }
                ]
              }
            }
          }
        }
      }
    ])
    

    Playground demonstration here

    This answer originally used $zip but the output format wasn't quite right