zored
zored

Reputation: 3064

Updating the path 'x' would create a conflict at 'x'

This error happens when I tried to update upsert item:

Updating the path 'x' would create a conflict at 'x'

Upvotes: 111

Views: 48513

Answers (10)

Mahdi Movassagh
Mahdi Movassagh

Reputation: 19

When the upsert parameter is true for updateOne() or findOneAndUpdate:

If no document already exist :

  • creates a new document
  • applies the $set operation
  • applies the $setOnInsert operation

If matches an existing document, MongoDB only applies the $set operation.

Therefore remove the $set operation fields from $setOnInsert object and mongoDb will add them from $set object in time of creating new document

Upvotes: 0

spetsnaz
spetsnaz

Reputation: 391

I observed that there is no direct solution mentioned here for this error. In my case, I was removing an ID from my schema list and also adding a new ID at the same time and got this error.

Earlier code :

const findProject = await ProjectSchema.findOneAndUpdate(
        { projectId },
        { 
          $addToSet: { projectPolicyList: policyId },
          $pull: {projectPolicyList: oldPolicyId} 
        }
    );

So, a simple workaround for this is to update the list one at a time. In my case, I first added new element and then deleted from the list.

Correct Code :

const pushProjectPolicyList = await ProjectSchema.findByIdAndUpdate(projectId,
  { $addToSet: { projectPolicyList: policyId } });

const pullProjectPolicyList = await ProjectSchema.findByIdAndUpdate(projectId,
  { $pull: { projectPolicyList: oldPolicyId } });

Upvotes: 1

hrdwdmrbl
hrdwdmrbl

Reputation: 5289

With the Ruby library at least, it's possible to get this error if you have the same key twice, once as a symbol and once as a string:

db.getCollection("user").updateOne(
  {_id: ...},
  {$set: {'name': "Horse", name: "Horse"}}
)

Upvotes: 2

Enes
Enes

Reputation: 350

I recently had the same issue while using the query below.

TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.note': req.body.note } }, { upsert: true, new: true })

When i have changed 'content.note' to 'content.$.note' it has been fixed. So my final query is :

TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.$.note': req.body.note } }, { upsert: true, new: true })

Upvotes: 1

David
David

Reputation: 646

You cannot have the same path referenced more than once in an update. For example, even though the below would result in something logical, MongoDB will not allow it.

db.getCollection("user").updateOne(
  {_id: ...},
  {$set: {'address': {state: 'CA'}, 'address.city' : 'San Diego'}}
)

You would get the following error:

Updating the path 'address.city' would create a conflict at 'address'

Upvotes: 16

Andrey Hohutkin
Andrey Hohutkin

Reputation: 2919

Starting from MongoDB 4.2 you can use aggregate pipelines in update:

db.your_collection.update({
    _id: 1
}, 
[{
    $set:{
        x_field: {
            $cond: {
                if: {$eq:[{$type:"$_id"} ,  "missing"]},
                then: 'upsert value',   // it's the upsert case
                else: '$x_field'    // it's the update case
            }
        }
    }
}],
{
     upsert: true
})

db.collection.bulkWrite() also supports it

Upvotes: 3

Onur Demir
Onur Demir

Reputation: 748

db.products.update(
  { _id: 1 },
  {
     $set: { item: "apple" },
     $setOnInsert: { defaultQty: 100 }
  },
  { upsert: true }
)

Below is the key explanation to the issue:

MongoDB creates a new document with _id equal to 1 from the condition, and then applies the $set AND $setOnInsert operations to this document.

If you want a field value is set or updated regardless of insertion or update, use it in $set. If you want it to be set only on insertion, use it in $setOnInsert.

Here is the example: https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/#example

Upvotes: 11

saintlyzero
saintlyzero

Reputation: 1852

I had the same problem while performing an update query using PyMongo.
I was trying to do:


> db.people.update( {'name':'lmn'}, { $inc : { 'key1' : 2 }, $set: { 'key1' : 5 }})

Notice that here I'm trying to update the value of key1 from two MongoDB Update Operators.

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.

You can find a list of Update Operators over here

Upvotes: 19

RodrigoNOFX
RodrigoNOFX

Reputation: 143

If you pass the same key in $set and in $unset when updating an item, you will get that error.

For example:

const body = {
   _id: '47b82d36f33ad21b90'
   name: 'John',
   lastName: 'Smith'
}

MyModel.findByIdAndUpdate(body._id, { $set: body, $unset: {name: 1}})

// Updating the path 'name' would create a conflict at 'name'

Upvotes: 13

zored
zored

Reputation: 3064

Field should appear either in $set, or in $setOnInsert. Not in both.

Upvotes: 102

Related Questions