【发布时间】:2018-11-29 13:27:25
【问题描述】:
当我尝试更新 upsert 项目时发生此错误:
Updating the path 'x' would create a conflict at 'x'
【问题讨论】:
当我尝试更新 upsert 项目时发生此错误:
Updating the path 'x' would create a conflict at 'x'
【问题讨论】:
字段应出现在$set 或$setOnInsert 中。两者都没有。
【讨论】:
$set 如果找到文档并且如果未找到则发生。因此它在$setOnInsert 和{upsert: true} 的“未找到”状态下发生冲突。似乎 MongoDB 开发人员无法定义一个优先级:)
我在使用 PyMongo 执行 update 查询时遇到了同样的问题。
我正在尝试做:
> db.people.update( {'name':'lmn'}, { $inc : { 'key1' : 2 }, $set: { 'key1' : 5 }})
请注意,这里我尝试从两个 MongoDB 更新运算符 更新 key1 的值。
当您尝试在同一查询中使用多个 MongoDB 更新运算符 更新 same key 的值时,基本上会发生这种情况。
您可以通过here 找到更新运算符列表
【讨论】:
如果您在更新项目时在$set 和$unset 中传递相同的密钥,则会收到该错误。
例如:
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'
【讨论】:
您不能在更新中多次引用同一路径。例如,即使下面会产生一些合乎逻辑的结果,MongoDB 也不会允许它。
db.getCollection("user").updateOne(
{_id: ...},
{$set: {'address': {state: 'CA'}, 'address.city' : 'San Diego'}}
)
你会得到以下错误:
Updating the path 'address.city' would create a conflict at 'address'
【讨论】:
db.products.update(
{ _id: 1 },
{
$set: { item: "apple" },
$setOnInsert: { defaultQty: 100 }
},
{ upsert: true }
)
以下是该问题的关键解释:
MongoDB 创建一个 _id 等于 1 的新文档 条件,然后 将 $set AND $setOnInsert 操作应用于 这份文件。
如果您想设置或更新字段值而不考虑插入或更新,请在 $set 中使用它。如果您希望它仅在插入时设置,请在 $setOnInsert 中使用它。
示例如下:https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/#example
【讨论】:
从 MongoDB 4.2 开始,您可以在更新中使用聚合管道:
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() 也支持
【讨论】:
我最近在使用下面的查询时遇到了同样的问题。
TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.note': req.body.note } }, { upsert: true, new: true })
当我将 'content.note' 更改为 'content.$.note' 时,它已被修复。所以我的最终查询是:
TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.$.note': req.body.note } }, { upsert: true, new: true })
【讨论】: