0

I have a MongoDB collection which documents have an array of objects. Like this:

{
  _id: ...,
  a: [
    {
      aa: "foo1"
      bb: "bar1"
    },
    {
      aa: "foo2"
      bb: "bar2"
    },
    {
      aa: "foo3"
      bb: "bar3"
    }
    ...
  ],
  b: ...
}

I want to modify some of the fields of the object and left the rest untouched. I'm using the aggregation framework for that, with three stages: unwind of the array, modification of the objects (now at root level in the document) and finally re-grouping by _id to get the array back.

{
  $unwind: "a"
},
{
  $set: {"a.aa": {$concat: ["prefix-", "$a.aa", "-suffix"]}}
},
{
  $group: {
    _id: "$_id",
    a: {$push: "$a"},
    b: {$first: "$b"}
  }
}

So far so good.

The problem is that I don't have only one field in addition to the array. I have lot of them (~10) so the group stage is actually like this:

{
  $group: {
    _id: "$_id",
    a: {$push: "$a"},
    b: {$first: "$b"},
    c: {$first: "$c"},
    d: {$first: "$d"},
    // a lot of fields here
  }
}

which is error prone to write.

Is there some smarter way of doing this without explicitly include all the attributes in the group stage?

Thanks in advance!

1
  • 1
    Using $unwind followed by {$group: { _id: "$_id", ... is typically a poor approach. Have a look at $filter and $map or $reduce if the operations are more complex. Commented Apr 21, 2023 at 12:39

1 Answer 1

2

Based on your sample data, it could be this one:

db.collection.aggregate([
   {
      $set: {
         a: {
            $map: {
               input: "$a",
               in: {
                  $mergeObjects: [
                     "$$this",
                     { aa: { $concat: ["prefix-", "$$this.aa", "-suffix"] } }
                  ]
               }
            }
         }
      }
   }
])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.