2

Consider the following mongo data:

{ _id: "1",
  names: ["John", "Peter"]
}

What is the correct way to replace a simple element in the array, getting the following result ?

{ _id: "1",
  names: ["John", "Sarah"]
}

In my code I receive a function to exchange "Peter" with "Sarah", like:

substituteItemOnArray = (id, from, to) => {
   MyModel.update({
      id: id
   },
   {
      ??? What is the correct way to substitute one element with another ???
   });

}

substituteItemOnArray("1", "Peter", "Sarah");
5

3 Answers 3

1

Simply use $ positional operator

db.getCollection('test').findOneAndUpdate(
  { names: "Peter" },
  { $set: { 'names.$': "Sarah" }}
)
Sign up to request clarification or add additional context in comments.

2 Comments

Is this gonna work no matter "Sarah"'s positions on the array? ["John", "Sarah"], ["Sarah", "John"], ["John", "Sarah", "Peter"], etc.
Yes you can check
1

I don't know any way to do it with just Mongo operators.

I think you will have to retrive the document by id, find the index of the string you want to replace and only after that update document

Below function should do what I described above

async substituteItemOnArray = (_id, from, to) => {
    const doc = await MyModel.findOne({  _id  });
    if (doc && doc.names && doc.names.indexOf(from) > -1) {

    const index = dox.names.indexOf(from); 
    const keyToUpdate = `names.${index}`;
    MyModel.update({ _id }, { $set: { [keyToUpdate] : to} },)
}

substituteItemOnArray("1", "Peter", "Sarah");

Comments

1

You can do this with mongoDB arrayFilters like this in mongoose:

function substituteItemOnArray = (id, from, to) {
  return MyModel.findOneAndUpdate(
    {id: id}, // where to update
    {$set: {'names.$[element]': to }}, // what to update
    {arrayFilters: [{'element': from}]} // what should match in array.
  )
}

(
  async () => {
    let doc = await substituteItemOnArray(id, "Peter", "Sarah");
    console.log(doc);
  }
)()

Comments

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.