1
const string Pattern = @"(?si)<([^\s<]*totalWork[^\s<]*)>.*?</\1>";
var filter = Builders<JobInfoRecord>.Filter.Regex(x => x.SerializedBackgroundJobInfo,
                                            new BsonRegularExpression(Pattern, "i"));

var documents = await records.Find(filter).ToListAsync();

====

After I get documents I working with each document on the my side.

const string EmptyTag = "<$1></$1>";
var updatedJobInfo = Regex.Replace(document.SerializedBackgroundJobInfo, Pattern, EmptyTag);

How can I do Regex.Replace in the mongo side? Or that can only happen in the client?

Is the following Replace works in the Mongo side?

using (var cursor = await jobInfoDocuments.FindAsync<JobInfoRecord>(filter))
{
      while (await cursor.MoveNextAsync())
      {
             var batch = cursor.Current;
             foreach (var document in batch)
             {
                 var newInfo = Regex.Replace(document.SerializedBackgroundJobInfo, regex, EmptyTag);

                  // Applying several operations within the one request.
                  operationList.Add(new UpdateOneModel<JobInfoRecord>(Builders<JobInfoRecord>.Filter.Eq("_id", document.JobId),
                                                                       Builders<JobInfoRecord>.Update.Set("SerializedBackgroundJobInfo", newInfo)));
              }
Anatoly
  • 1,908
  • 4
  • 25
  • 47
  • Ouch! Clearly should have closed this question as a duplicate, before the bounty was posted. See [MongoDB: Updating documents using data from the same document](http://stackoverflow.com/a/3792958/2313887), That means "looping" and not the slight restructure of field renaming in the accepted answer. The only practical thing to do here is the answer you already got to [How to increase performance of the update operation in Mongo?](http://stackoverflow.com/a/36191579/5031275) – Blakes Seven Mar 26 '16 at 07:20
  • 1
    Regex.replace is not supported on MongoDB server side so if you have special needs, it has to be done on client side. – Saleem Mar 26 '16 at 23:57

1 Answers1

1

You can do it with javascript but be sure the fix the filter to work with mongo shell

db.records.find(filter).forEach(function (doc) {
  var pattern = /<([^\s<]*totalWork[^\s<]*)>[\s\S]*?</\1>/i;
  var EmptyTag = "<$1></$1>";
  
  doc.SerializedBackgroundJobInfo = doc.SerializedBackgroundJobInfo.replace(pattern, EmptyTag);
  
  db.records.save(doc);
})
TomG
  • 2,409
  • 4
  • 23
  • 40
  • And what about C#? – Anatoly Mar 21 '16 at 14:14
  • I am not familiar with the C# mongo drivers, but just find a way to send natural `javascript` commands to mongo through C# – TomG Mar 21 '16 at 14:16
  • Please look at my updated question. Do you think it works in the mongo side? – Anatoly Mar 21 '16 at 14:33
  • Again, I'm not familiar with C# mongo driver so I can't answer that. But I'm almost sure you should `save` and not `InsertOneAsync`. Since Insert will probably just insert additional document while you want to edit the document – TomG Mar 21 '16 at 14:35
  • 1
    This regex will not work in JS as is, it should be `var pattern = /<([^\s<]*totalWork[^\s<]*)>[\s\S]*?\1>/i;` – Wiktor Stribiżew Mar 21 '16 at 19:26
  • @WiktorStribiżew You are right. I just took his regex and pasted it, hoping it's clear it should work before running it :). I edited. – TomG Mar 21 '16 at 19:58