Concat a string prefix to the field of an object in an array in MongoDb

Viewed 136

I have many mongoDb documents like so

{
store:"Jacks Pizza",
storeNumbers:[
  {
    "chef":"Giovanni",
    "number":"7203305544"
  }
]
},
store:"Felicias Kitchen",
storeNumbers:[
  {
    "chef":"Gina",
    "number":"+19161214594"
  }
]

I would like to append a "+1" prefix to all such numbers that don't have a +1 country code attached to them.

Here's what I have tried-

db.users.updateMany({ 
    "storeNumbers.number" :  { 
        $exists: true, 
        $ne:"", 
        $regex: /^(?!\+)^(?![a-zA-Z])/ 
      } 
    }, 
    [ { 
        $set : { 
            "storeNumbers.$.number" : { 
                "$concat": [ "+1" , "$storeNumbers.$.number"]
                }
            }
        } 
    ] 
);

This gives me an error saying that I cannot perform concat on elements in an array.

How would you do this?

1 Answers

There is no straight way to do this, you can use update with aggregation pipeline starting from MongoDB 4.2,

  • match query if regex does not match "+1" string at the start of the number
  • $map to iterate loop of storeNumbers
  • $cond check condition if number does not match "+1" string at the start of the number and number field is not string and string type then concat "+1" before number using $concat otherwise do nothing
  • $mergeObjects to merge current object with new update number field
db.users.updateMany({
  "storeNumbers.number": {
    $exists: true,
    $ne: "",
    $not: {
      $regex: "^\\+1"
    }
  }
},
[
  {
    $set: {
      storeNumbers: {
        $map: {
          input: "$storeNumbers",
          in: {
            $mergeObjects: [
              "$$this",
              {
                $cond: [
                  {
                    $and: [
                      {
                        $not: {
                          $regexMatch: {
                            input: "$$this.number",
                            regex: "^\\+1"
                          }
                        }
                      },
                      {
                        $ne: ["$$this.number", ""]
                      },
                      {
                        $eq: [{ $type: "$$this.number" }, "string"]
                      }
                    ]
                  },
                  {
                    number: {
                      $concat: ["+1", "$$this.number"]
                    }
                  },
                  {}
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Playground

Related