mongoose MongoDB:更新路径“Y”会在“Y”处产生冲突

iqih9akk  于 2023-02-08  发布在  Go
关注(0)|答案(1)|浏览(174)

我正在执行以下查询:

const myData = await this.findOneAndUpdate({
  myId,
  color,
}, {
  $setOnInsert: {
    myId,
    color,
    date: now.format('YYYY-MM-DD'),
    counter: myObj.counter - amount,
  },
  $inc: {
    counter: -amount
  },
}, {
  new: true,
  upsert: true,
});

我得到错误:

"Updating the path 'count' would create a conflict at 'count'"

首先我认为错误是由于mongoose的版本而发生的,但我不认为是这样。
现在我明白了,这是因为我在$setOnInsert$inc中都有color,但我不明白为什么。
另外:此代码可以在MongoDB 3.4.24 Community上运行,但不能在MongoDB 5.0.11 Community上运行
所以我的问题是:

  • 为什么会发生这个错误?这会是BUG吗?
  • 为什么这在旧版本的MongoDB中有效?
  • 什么是重构它的最佳方法?
whhtz7ly

whhtz7ly1#

你从MongoDB得到了上面的错误,因为$inc的工作方式,upsert: truenew: true$inc将插入一个新文档。检查playground
在您的例子中,您有$setOnInsert$inc,如果您的匹配文档没有找到,两个计数器将尝试设置键counter的值,这将创建一个冲突,因此您会看到错误。要修复它,您可以使用管道形式的更新,如下所示:

const myData = await this.findOneAndUpdate({
  myId,
  color,
}, [
   {
     $set: {
        myId,
        color,
        date: {
           $cond: {
             if: {$eq: ["$$ROOT", null]},
             then: now.format('YYYY-MM-DD'),
             else: "$$ROOT.date"
           }
        },
        counter: {
           $cond: {
             if: {$eq: ["$$ROOT", null]},
             then: myObj.counter - amount,
             else: {$substract: ["$$ROOT.counter", amount]}
           }
        }
     }
   }
], {
  new: true,
  upsert: true,
});

相关问题