0

I have below Mongo Collection

{
   "name":"test",
   "work":"BA",
   "contacts":[
      {
         "company":"xyz",
         "email":"http://www.google.com/check/com/2"
      },
      {
         "company":"xyz1",
         "email":"http://www.google.com/verify/com/4"
      }
   ]
}

I want to replace www.google.com from contacts email to www.test.com, Not complete URL only a particular string from email. Any help appreciated!!

2 Answers 2

1

4.4+ :

db.collection.update({
 "contacts.email": {
  $regex: "google"
 }
 },
[
 {
   $addFields: {
     contacts: {
       $map: {
         input: "$contacts",
         as: "c",
         in: {
           $mergeObjects: [
            {
              email: {
              $replaceOne: {
                input: "$$c.email",
                find: "www.google.com",
                replacement: "www.test.com"
              },    
             }
            },
            {
               company: "$$c.company"
            }
           ]
          }
         }
        }
       }
      }
     ])

Explained:

Update via aggregation pipeline using replaceOne via $map/mergeObjects

playground

Sign up to request clarification or add additional context in comments.

2 Comments

according to the documentation, $replaceOne exists only since mongodb 4.4, not 4.2: mongodb.com/docs/manual/reference/operator/aggregation/…
Completely correct remark , fixed immediatelly... :)
0

Query1

  • $indexOfCP MongoDB >=3.6

PlayMongo

aggregate(
[{"$set": {"m": "www.google.com", "r": "www.test.com"}},
 {"$set": 
   {"contacts": 
     {"$map": 
       {"input": "$contacts",
        "in": 
         {"$mergeObjects": 
           ["$$this",
             {"email": 
               {"$let": 
                 {"vars": {"index": {"$indexOfCP": ["$$this.email", "$m"]}},
                  "in": 
                   {"$cond": 
                     [{"$eq": ["$$index", -1]}, "$$this.email",
                       {"$concat": 
                         [{"$substrCP": 
                             ["$$this.email", 0, {"$subtract": ["$$index", 0]}]},
                          "$r",
                           {"$substrCP": 
                             ["$$this.email",
                               {"$add": ["$$index", {"$strLenCP": "$m"}]},
                               {"$subtract": 
                                 [{"$strLenCP": "$$this.email"},
                                   {"$add": 
                                     ["$$index", {"$strLenCP": "$m"}]}]}]}]}]}}}}]}}}}},
 {"$unset": ["m", "r"]}])

Query2

  • $replaceAll MongoDB >= 4.4

PlayMongo

aggregate(
[{"$set": 
   {"contacts": 
     {"$map": 
       {"input": "$contacts",
        "in": 
         {"$mergeObjects": 
           ["$$this",
             {"email": 
               {"$replaceAll": 
                 {"input": "$$this.email",
                  "find": "www.google.com",
                  "replacement": "www.test.com"}}}]}}}}}])

9 Comments

Hi Takis, Does above query 1 code work for below URL: test-test1-test2.ctest.com/ket/set instead of "www.google.com"
the first query that is for 4.2, find the index of first substring and replace it, if you mean this its working. It can fail only if you have that string more than 1 time (in this case only the first occurence will be replaced).
First query is working I am getting result, sorry! I want to update the collection also with first query.
its the same, you can use pipeline update like this
Yes it works, Thanks Takis but it append where we don't have contacts array in collections and it append with null like "contacts: null"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.