Home > Software design >  How do I turn a comma separated string field into an Array of objects in MongoDB?
How do I turn a comma separated string field into an Array of objects in MongoDB?

Time:06-14

I have three documents that looks like this:

_id: ObjectId('61e1312ad435c7124aa883a1')
name: "Brian"
languages: "English,Spanish,French"

_id: ObjectId('52e1312ad435c7124aa883a2')
name: "Max"
languages: "English"

_id: ObjectId('37e1312ad435c7124aa883a9')
name: "Mike"
languages: ""

As you can see, the languages field can either be empty, have one item, or multiple items separated by commas.

How can I turn the languages field into an Array of objects? The end result should look like this:

_id: ObjectId('61e1312ad435c7124aa883a1')
name: "Brian"
languages: [
    { name: "English", active: false }
    { name: "Spanish", active: false }
    { name: "French", active: false }
]

_id: ObjectId('52e1312ad435c7124aa883a2')
name: "Max"
languages: [
    { name: "English", active: false }
]

_id: ObjectId('37e1312ad435c7124aa883a9')
name: "Mike"
languages: []

The language field should be an array of object with two fields, a "name" field which is the name of the language and an "active" field which is always set to false..

I've managed to turn the comma-separated string into an array of strings, but I'm not sure how to turn it into an array of objects.

db.collection.updateMany(
{},
[
  {
    "$set": {
      "languages": {
        $filter: {
          input: {
            $split: [
              "$languages",
              ","
            ]
          },
          cond: {
            $gt: [
              {
                $strLenCP: "$$this"
              },
              0
            ]
          }
        }
      }
    }
  }
])

CodePudding user response:

All you are missing is the last $map step:

db.collection.update({},
[
  {
    $set: {
      languages: {
        $filter: {
          input: {$split: ["$languages", ","]},
          cond: {$gt: [{$strLenCP: "$$this"}, 0]}
        }
      }
    }
  },
  {
    $set: {
      languages: {
        $map: {
          input: "$languages",
          as: "item",
          in: {name: "$$item", active: false}
        }
      }
    }
  }
],
{multi: true})

See how it works on the playground example

  • Related