0

First of all, I am using Mongo DB Compass and the mongo shell. I want to update for example this field: 1List.Comment

In this Field I want to replace 'ß' with 'ss'

1List is an array. And in this Array I can have several Objects. These Objects contain the 'Comment' field.

Here is one example Doc:

{
   "_id":{
      "$oid":"12345"
   },
   "1List":[
      {
         "Comment": "TEßT Comment",
         "TEXT_VALUE":"Another test string",
         "REASON":"No Reason"
      },
      {
         "Comment": "TEßT Comment the second",
         "TEXT_VALUE":"Another second string",
         "REASON":"No Reason again"
      }
   ]
}

This is what I have tried in mongo db shell:

db.getCollection('TEST_Collection').aggregate(
[{
    $match: {
        '1List.Comment': {
            $exists: true
        }
    }
}, {
    $unwind: {
        path: '$1List',
        includeArrayIndex: '1List.CommentArrayIndex',
        preserveNullAndEmptyArrays: false
    }
}, {
    $project: {
        '1List.Comment': 1
    }
}]
)
.forEach(function(doc,Index) {doc.1List.Comment=doc.1List.Comment.replace(/[ß]/g, 'ss');
db.TEST_Collection.updateMany({ "_id": doc._id },{ "$set": { "1List.Comment": doc.1List.Comment } });})

But I get the error message: Cannot create field 'Comment' in element {1List:.......

Can anybody help to get these Comment fields updated? What am I doing wrong in my statement?

And also, is there an easy solution to also update 'TEXT_VALUE' right after updating Comment?

Thank you!

Swoop
  • 49
  • 1
  • 10

1 Answers1

1

You should replace this line

db.TEST_Collection.updateMany({ "_id": doc._id },{ "$set": { "1List.Comment": doc.1List.Comment } });})

with

db.TEST_Collection.updateMany({ "_id": doc._id },{ "$set": { "1List.$[].Comment": doc.1List.Comment } });})

You can check the docs too.

Rubén Vega
  • 722
  • 6
  • 11
  • Thank you very much. That works! Do you also know something about my second question? Lets say not only replace ß for field Comment but also for text_value ? I mean if i would add this field also to $match I would only get the docs which contain both fields correct? But it could also be in some cases one of them is not filled so also not there in the document. Any suggestions on this? Thanks!! – Swoop Nov 22 '21 at 13:24
  • Hi Ruben Vega, while testing the new line of yours i saw that he is now overwriting the fields. Meaning he will take the comment and replaces ß but then also uses the updated string to update the second object, even though that is a different string – Swoop Nov 22 '21 at 13:39
  • 1
    To the first comment: I would use a different update for each field since you ahve alredy all the work done, you should just change the field. – Rubén Vega Nov 22 '21 at 14:57
  • 1
    To the second one you can use `arrayFilters` to just update what you wanted. I let you an example here, in the arrayFilter query you should put `doc.1List.Comment` without the replacement. https://mongoplayground.net/p/_CgwE8_-eZa – Rubén Vega Nov 22 '21 at 15:00
  • Great! Thank you very much! Now I am facing another problem: After starting my first update, after about 50 minutes I get the error message: MongoServerError: Error on remote shard *****.com:27000 :: caused by :: cursor id 1272890412590646833 not found After this error i checked the field and he did not update them all, so he stopped and threw this error. Any Idea about this and how to solve? I read something about noCursorTimeout() but I am not sure how and where to use it in my statement. – Swoop Nov 22 '21 at 15:05
  • I don't know about that error... however you should have some fileds updates, since you are making one operation for each comment. Maybe you could add some kind of delay between operations so your DB don't collapse... but IDK – Rubén Vega Nov 22 '21 at 15:19