Search code examples
mongodbmongodb-querypymongo

How can I update all documents in a collection to create a new field that replaces certain characters in an existing field?


I want to add a new field called searchname to all documents based on the currently existing name but taking the string inside name and replacing all é with regular e. How can I do this in either the shell or a driver. I'm trying this in pymongo but I'm getting the error ```Invalid $set :: caused by :: An object representing an expression must have exactly one field``

Here is the code I'm trying to run

test_collection.update_many({},
    [{
        "$set": {
            "searchName": {
                "$reduce": {
                    "input": [
                        ["é", "e"],
                        ["à", "a"],
                        ["í", "i"],
                        ["ó", "o"],
                        ["ú", "u"],
                        ["ñ", "n"],
                    ],
                    "initialValue": {
                        "$toLower": "$name"
                    },
                    "in": {
                        "$replaceAll": {
                            "input": "$$value",
                            "find": {
                                "$arrayElemAt": [
                                    "$$this",
                                    0
                                ]
                            }
                        },
                        "replacement": {
                            "$arrayElemAt": [
                                "$$this",
                                1
                            ]
                        }
        }}}}}])

Solution

  • Query1

    • pipeline update requires MongoDB >= 4.2
    • you can use $replaceAll aggregate opertor
    • for 1 character only

    PlayMongo

    update({},
    [
      {
        "$set": {
          "searchName": {
            "$replaceAll": {
              "input": "$name",
              "find": "é",
              "replacement": "e"
            }
          }
        }
      }
    ],
    {"multi": true})
    

    Query2

    • use this to replace many characters
    • put your characters/replacements in the "input"

    PlayMongo

    update({},
    [{"$set": 
       {"searchName": 
         {"$reduce": 
           {"input": [["é", "e"], ["l", "k"]],
            "initialValue": "$name",
            "in": 
             {"$replaceAll": 
               {"input": "$$value",
                "find": {"$arrayElemAt": ["$$this", 0]},
                "replacement": {"$arrayElemAt": ["$$this", 1]}}}}}}}],
    {"multi": true})