I want to update a nested object inside another nested object in MongoDb that looks like this :
[
{
_id: ObjectId("637c648fb8fcfb2bc3071bb9"),
consultant_name: "Sam letterman",
consultantUsername: "sam",
consultant_Password: "123",
type: "consultant",
clients: [
{
client_name: "john",
client_Username: "mouh",
client_Password: "123",
type: "client",
documents: [
{
name: "Acte de mariage",
description: "copie conforme certifié du certificat de mariage",
doc_upload: "",
_id: ObjectId("637c648fb8fcfb2bc3071bbe")
},
{
name: "Acte de de divorce",
description: "because divorced",
doc_upload: "",
_id: ObjectId("637c648fb8fcfb2bc3071bbf")
}
],
},
{
_id: ObjectId("637c648fb8fcfb2bc3071bb9"),
client_name: "narrakech",
client_Username: "elsa",
client_Password: "123",
type: "client",
documents: [
{
name: "Acte de mariage",
description: "copie conforme certifié du certificat de mariage",
doc_upload: "",
_id: ObjectId("637c648fb8fcfb2bc3071bbe")
},
{
name: "Acte de de divorce",
description: "Parce que qu'on est shizo",
doc_upload: "",
_id: ObjectId("637c648fb8fcfb2bc3071bbf")
}
]
}
],
createdAt: ISODate("2022-11-22T05:56:31.469Z"),
updatedAt: ISODate("2022-11-27T03:40:31.835Z"),
__v: 0
}
]
More specifically, what I want to do is update the "doc_upload" of the client_Username "elsa". Here's my code
router.put('/:id', async (req, res) => {
if (cond) {
try {
const updatedUser = await User.findOneAndUpdate({ 'clients._id': req.params.id }, {
$set: { 'clients.$.client_name': 'narrakech' },
}, { new: true });
res.status(200).json(updatedUser);
} catch (err) {
res.status(500).json(err);
}
} else {
res.status(401).json('You can update only you account.');
}
})
Here I am able to update only the client_name (so one nested object), this is how far as is got. What I want to do is update one of her specific documents (the doc_upload section for example), the idea behind all this is to have access to the second array (documents) which I can't do for now using the $ sign.
Is there any way to do this in MongoDb ?
Thank you
Yes there is a way to do this, in fact several ways.
The simplest will be to use the array filters option, like so:
db.collection.findOneAndUpdate({
"clients._id": req.params.id
},
{
$set: {
"clients.$.client_name": "narrakech",
"clients.$.documents.$[doc].doc_upload": "new doc upload"
}
},
{
arrayFilters: [
{
"doc._id": subDocumentId // this is the "query" to match the sub document in the documents array.
}
]
})