0

I have a simple MongoDB array of objects with this structure:

[
  {
    "_id": {
      "$oid": "6688c2f6b79f2bfefb751d5f"
    },
    "date": "06/07/2024",
    "serviceStatus": [
      {
        "home": "http://www.bbc.co.uk/ontologies/passport/home/Marathi",
        "count": 8
      },
      {
        "home": "http://www.bbc.co.uk/ontologies/passport/home/Indonesia",
        "count": 4
      },
   ]
  },
  {
    "_id": {
      "$oid": "66860a80b79f2bfefb7513cc"
    },
    "date": "04/07/2024",
    "serviceStatus": [
      {
        "home": "http://www.bbc.co.uk/ontologies/passport/home/Pashto",
        "count": 10
      },
      {
        "home": "http://www.bbc.co.uk/ontologies/passport/home/Zhongwen",
        "count": 4
      }
    ]
  }
]

I've tried adding a new field in the serviceStatus arrays, using this aggregation pipeline command, to get an abbreviated version of the serviceStatus.home value in each object:

{
    $addFields: {
      "serviceStatus.homeShort": { $substrCP: [ "$serviceStatus.home", 0, 2 ] },
    }

However this returns an error:

PlanExecutor error during aggregation :: caused by :: can't convert from BSON type array to String The command works fine if it is used to assign a static value, but does not work dinamically.

Is there anyway to add a field in a nested array in a MongoDB collection, using the aggregation pipeline, and populate it based on values already existing within the same array? Or does this require unwinding the arrays in separate objects, adding the field to each one, and then re-grouping them?

2
  • Do you want to "$map" with something like this mongoplayground.net example? Commented Jul 6, 2024 at 15:30
  • Great, thank you! Commented Jul 6, 2024 at 21:05

1 Answer 1

0

Since you are working on an array field, you will need to use $map to iterate through the entries and use $mergeObjects to append the new field to the objects. The $merge is for updating back into the collection and you can skip that if you do not need it.

db.collection.aggregate([
  {
    "$set": {
      "serviceStatus": {
        "$map": {
          "input": "$serviceStatus",
          "as": "ss",
          "in": {
            "$mergeObjects": [
              "$$ss",
              {
                "homeShort": {
                  "$substrCP": [
                    "$$ss.home",
                    0,
                    2
                  ]
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    "$merge": {
      "into": "collection"
    }
  }
])

Mongo Playground

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect, thanks, much appreciated!

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.