I have one db like this:
{
_id: ObjectId('637bbfd595f55f2f4673ec41'),
uuid: '63068d38c172ccfc2c5bc86e',
title: 'Test Board1',
description: 'cddsvsdv',
icon: 'mat_outline:groups',
lists: [{
title: 'Monday',
boardId: '637bbfd595f55f2f4673ec41',
position: 65536,
cards: [],
_id: ObjectId('637cbfcac1dfe0fb0841d0f3'),
createdAt: ISODate('2022-11-22T12:25:46.953Z'),
updatedAt: ISODate('2022-11-22T12:25:46.953Z')
},
{
title: 'Tuesday',
boardId: '637bbfd595f55f2f4673ec41',
position: 65536,
cards: [],
_id: ObjectId('637cbfcac1dfe0fb0841d0f8'),
createdAt: ISODate('2022-11-22T12:25:46.966Z'),
updatedAt: ISODate('2022-11-22T15:36:26.625Z')
}
],
labels: [],
updatedAt: ISODate('2022-11-22T15:36:26.625Z'),
createdAt: ISODate('2022-11-21T18:13:41.041Z'),
__v: 0
}
and I would like to modify one item inside the array LISTS by the ID reference. I write this:
const BoardUpdate = await context.di.model.BoardsUser.findOneAndUpdate(
{
lists: {
$elemMatch:
{
_id: mongoose.Types.ObjectId(input.id),
}
},
},
{
$set: {
'lists.$[el].title': input.title
}
},
{
arrayFilters:[{
'el._id': mongoose.Types.ObjectId(input.id)
}]
}
);
in the input I have the data passed by http:
"vInput": {
"id": "637cbfcac1dfe0fb0841d0f8",
"boardId": "637bbfd595f55f2f4673ec41",
"title": "Tuesday111",
"position": 65536,
"cards": []
}
so after the update I'm able to modify the title, but the question is: How can pass all the data of the object VInput? because inside the array CARDS the are more data and I think is possible to pass all the object. when I try to modify the $set line like this:
$set: {
'lists.$[el]': input
}
I receive this error:
"Updating the path 'lists.$[el].updatedAt' would create a conflict at 'lists.$[el]
I don't know how to solve this.
CodePudding user response:
The issue is that mongoose cannot replace an element in an array when { timestamps: true }
is set in the mongoose schema.
There are a few workarounds:
- Get rid of
{ timestamps: true }
in the lists array in the mongoose schema. - Set the update operator to update each field:
$set: {
'lists.$[el].title': input.title,
'lists.$[el].position': input.position,
'lists.$[el].cards': input.cards,
...
}
- Depending on the use case, you may be creating large documents, which should be avoided. In this case you should create a lists collection. This would make the updating lists much simpler