1

I'm having a problem in updating an array in my Records table named projects->url.

Records collection

id: 1
status: "failed"
projects: Array
    0: Object
       url: www.facebook.com/testing/myprofile/1234
    1: Object
       url: www.facebook.com/testing/myprofile/12345
    2: Object
       url: www.facebook.com/testing/myprofile/123456
createdAt: Wed Dec 02 2020 16:17:26 GMT+0800
updatedAt: Wed Dec 02 2020 16:17:26 GMT+0800

id: 2
status: "passed"
projects: Array
    0: Object
       url: www.facebook.com/testing/myprofile/5
    1: Object
       url: www.facebook.com/testing/myprofile/6
    2: Object
       url: www.facebook.com/testing/myprofile/7
createdAt: Wed Dec 02 2020 16:17:26 GMT+0800
updatedAt: Wed Dec 02 2020 16:17:26 GMT+0800

This is my aggregate pipeline using map to update the array of the projects field but it doesn't update the url field.

dbo.collection('records').aggregate(
[{
    $project: 
    { 
        projects: 
        {
            $map: 
            {
                $replaceOne: { input: "$projects.url", find: "facebook", replacement: "mywebsite"}
            }
        }
    }
}]

)

I want the records projects url to be from facebook.com -> mywebsite.com

Result

Records

id: 1
status: "failed"
projects: Array
    0: Object
       url: www.mywebsite.com/testing/myprofile/1234
    1: Object
       url: www.mywebsite.com/testing/myprofile/12345
    2: Object
       url: www.mywebsite.com/testing/myprofile/123456
createdAt: Wed Dec 02 2020 16:17:26 GMT+0800
updatedAt: Wed Dec 02 2020 16:17:26 GMT+0800

id: 2
status: "passed"
projects: Array
    0: Object
       url: www.mywebsite.com/testing/myprofile/5
    1: Object
       url: www.mywebsite.com/testing/myprofile/6
    2: Object
       url: www.mywebsite.com/testing/myprofile/7
createdAt: Wed Dec 02 2020 16:17:26 GMT+0800
updatedAt: Wed Dec 02 2020 16:17:26 GMT+0800

1 Answer 1

1

Try this, not totally sure if it's what you look for:

const pipeline= [
  {
    $addFields: {
      projects: {
        $map: {
          input: "$projects",
          as: "p",
          in: {
            "$mergeObjects": [
              "$$p",
              {
                url: {
                  "$replaceOne": {
                    "input": "$$p.url",
                    "find": "facebook",
                    "replacement": "mywebsite"
                  }
                }
              },
              
            ]
          }
        }
      }
    }
  }
]
db.collection.aggregate(pipeline)

Behaviour

  1. If there is no match returns the same string
  2. Returns an error if the URL is a number and not a string.
  3. Returns url:null for missing url fields.
  4. Merges the fields from the old object, overwriting the url.

For permanently updating original data, use

db.collection.updateMany({}, pipeline)

The variable pipeline is defined in the snippet above.

Live version

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

4 Comments

Hi, it is working on the live version. but when I'm applying on my database it's not updating. what seems to be the problem?
It should be outputing the documents with new data. Once that work, you can run update @PinkyPromise. Remember to replace <collection> with the actual name of the collection, and to use <yourDB> first.
oh it deleted the other fields and only retain my projects array.
change $project by $addFields @PinkyPromise

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.