Assuming that your users
have a field of address
as an array, let’s demonstrate the example case:
users: {
name: '...',
age: 20,
// ...
address: [
{
_id: '123',
street: '...'
// ...
},
{
_id: '456',
street: '...'
// ...
}
]
}
For updateAdress
, we understand that you want to update an object of address
specific. In this case its function could be a little more simplified, without the need to loop forEach
and have to use if (adress.id == idAdress) {...}
. Mongodb offers a feature that allows you to update an Object within an array. We use The positional $ Operator. It has a very simple syntax to indicate which object should be updated. In the example of the documentation, we have an example:
We have the document:
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 90, mean: 85, std: 8 }
]
}
And we want to update the object that has the grade
equal to 90
and adjust the std
for 7
. We make use of the $
:
db.collection.updateOne(
{ _id: 4, "grades.grade": 90 }, // filtramos o objeto incluso no array aqui
{ $set: { "grades.$.std" : 7 } } // usamos o "$" aqui
)
Result after update:
{
"_id" : 4,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 8 },
{ "grade" : 85, "mean" : 90, "std" : 6 },
{ "grade" : 90, "mean" : 85, "std" : 7 }
]
}
Now let’s adapt to your code. Let’s use the method findOneAndUpdate
of Mongoose. The ultimate logic would be something like this:
async updateAdress(input) {
const { idUser, idAdress, adressInfo } = input;
let user = await User.findById(idUser);
let counter = 0;
// ↓↓↓ filtramos o objeto no array aqui
return User.findOneAndUpdate({_id: idUser, 'address._id': idAdress },
// ↓↓↓ atualiza o primeiro documento que fez o "match" da query
// e associa um novo valor a ele ("addressInfo")
{ $set: { 'adressInfo.$': addressInfo } }, { new: true }
).catch(
err => console.error(err)
);
}
The positional operator $
identifies an element in an array to update without explicitly specifying the position of the element in the array.
Details:
- the positional operator
$
acts as a marker for the first element that corresponds to the query document, and
- the array field should appear as part of the query document.
Obs:
Note that I used the _id
, Because that’s usually the name of the id’s that Mongoose creates. I don’t know how you structured the code, but I believe if you make the adaptations, this answer may be useful.
In the.log console the values are right, but when entering in the database, the edited object gets all the fields null
and exchange the id
it is difficult to understand without analyzing the logs, but this problem may be because the id
specified user. Mongoose does not change the values of id
, then if a new id
was created, it is because a new element was created, this because of the { new: true }
. Test your code again, substitute findByIdAndUpdate
for findOneAndUpdate
, etc....
From what I understand, you want to update a record that is contained within an array, right? Update a specific element that is a
address
. If it is, why not simplify using the operator$
mongodb?– Cmte Cardeal
I want to update an object that is inside an array, you can tell me the documentation or how to search about that operator $?
– Tiago