I am trying to unset some subdocument keys
const doc = {
"_id" : ObjectId("61548435c2f5315704f1d2c9"),
"description": "some text",
"game" : {
"id" : "63991b8f-083b-4b34-a314-cb64e7487fde",
"description" : "gta",
"image" : undefined,
"isActive" : true
}
}
await this.conn.updateOne({ id: doc._id },
{ ...doc, $unset: { "game.image": "" }
});
Error
MongoServerError: Updating the path ‘game.image’ would create a conflict at ‘game’
This basically happens when you try to update the value of a same key with more than one MongoDB Update Operators within the same query.
If you pass the same key in $set
and in $unset
when updating an item, you will get that error.
How to unset only one subdocument key?
steevej
(Steeve Juneau)
#2
I do not think that you should have …doc at the start of the second parameter.
If you only want to $unset game.image try:
await this.conn.updateOne({ id: doc._id }, { $unset: { "game.image": "" } });
steevej
(Steeve Juneau)
#3
It addition you might want to have _id : doc._id as the query rather than id : doc._id.
yes, I am using DDD, and trying to update all aggregate keys on only one command. my document has id generated by domain.
I fixed that using code bellow
await this.conn.updateOne({ _id: doc._id }, { ...doc } });
await this.conn.updateOne({ _id: doc._id }, { $unset: { "game.image": "" } });
But I have to execute two commands.
Any Idea how to do all on only one command?
steevej
(Steeve Juneau)
#5
So you want to do 2 things. But you wrote:
To do the 2 things you will have to modify doc so it only contains the values you want to update. Try the following:
const id = ObjectId("61548435c2f5315704f1d2c9") ;
const set_fields = {
"description": "some text",
"game.id" : "63991b8f-083b-4b34-a314-cb64e7487fde",
"game.description" : "gta",
"game.isActive" : true
}
} ;
const unset_fields = {
"game.image" : true
}
await this.conn.updateOne({ _id: id },
{ $set : set_fields , $unset: unset_fields });
I tested using the following in mongo shell:
> db.test.find( {} )
{ "_id" : ObjectId("615496a6df01ca14ce140325"), "game" : { "image" : 1 } }
> set_fields = { "d" : 1 , "game.id" : 2 , "game.isActive" : true }
{ "d" : 1, "game.id" : 2, "game.isActive" : true }
> unset_fields = { "game.image" : "" }
{ "game.image" : "" }
> update = { "$set" : set_fields , "$unset" : unset_fields }
{
"$set" : {
"d" : 1,
"game.id" : 2,
"game.isActive" : true
},
"$unset" : {
"game.image" : ""
}
}
> db.test.updateOne( { _id : id } , update )
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.test.find()
{ "_id" : ObjectId("615496a6df01ca14ce140325"), "game" : { "id" : 2, "isActive" : true }, "d" : 1 }
1 Like
Thank-you very much. Based on your answer, I found the following solution
const doc = {
id : "63991b8f-083b-4b34-a314-cb64e7487fde",
description: "some text",
game : {
id : "63991b8f-083b-4b34-a314-cb64e7487fde",
description : "gta",
image: undefined,
isActive: true
}
}
const undefinedKeys = [ "game.image" ]
await conn.updateOne({ id: doc.id }, [
{ $set: { ...doc } }, { $unset: undefinedKeys }
]);
1 Like
system
(system)
Closed
#7
This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.