mongodb mongoose bulkwrite upsert只适用于创建,不适用于更新

mspsb9vt  于 2023-08-04  发布在  Go
关注(0)|答案(2)|浏览(147)

遵循herehere的回答,尝试使用Mongoose 5.4实现批量upsert操作
有这样的话:

const update = await Company.bulkWrite([
    {
      'updateOne': {
        'filter': { 'url': result.url },
        'update': {
          testVal: 'testinggg'
        },
        'upsert': true,
      }
    },
  ]);

字符串
当我运行此命令时,我看到以下响应:

{
      ok: 1,
      writeErrors: [ ],
      writeConcernErrors: [ ],
      insertedIds: [ ],
      nInserted: 0,
      nUpserted: 0,
      nMatched: 1,
      nModified: 1,
      nRemoved: 0,
      upserted: [ ]
     }


但是,该条目实际上并没有更新。
如果我改变了过滤器,使它检查的东西,因此需要创建一个新的条目,而不是更新,它的工作正常。但是,如果筛选器属性匹配并且需要更新,则不会对匹配的文档进行更新。
也曾尝试过使用$set,但无济于事:

const update = await Company.bulkWrite([
    {
      'updateOne': {
        'filter': { 'url': result.url },
        'update': {
          '$set': {
              testVal: 'testinggg'
          }
        },
        'upsert': true,
      }
    },
  ]);


我做错什么了?

a14dhokn

a14dhokn1#

我发现问题中提出的问题陈述以及the answer中提到的解决方案非常具有误导性。这个答案将试图澄清一些额外的背景,这对未来读者全面理解这种情况很重要。
暗示所提供的代码没有更新数据库是不正确的。问题描述中提供的来自数据库的回答 * 直接通过以下方式向我们展示了这一点:

nMatched: 1,
      nModified: 1,

字符串
具体地说,这告诉我们,命令处理的第一个文档与查询条件匹配,没有请求的testVal,因此被相应地修改。换句话说,updateOne命令正如预期的那样更新了集合中的一个文档。
提到的“答案”是在url字段上创建unique索引。但是这个动作并没有突然使updateOne或 Package bulkWrap本身表现出任何不同。相反,该操作首先约束集合中可以存在哪些数据。该命令仍将尝试更新最多一个文档,但现在最多只有一个文档可能匹配查询条件。
综上所述,我们可以推断,最初发生的情况是,集合中有多个文档的值对应于正在测试的url字段。测试时更新的是其他文档(一次更新一个),而不是检查不同的文档(使用相同的url)。
从业务逻辑的Angular 来看,强制执行unique约束(或不强制执行)是完全可以接受的,但这样做只是改变了当前的数据,而不是“修复”似乎没有执行更新的命令。
作为一个旁注,我想提一下,在问题描述中没有任何东西表明这里需要批量操作。如果您没有unique约束,并且希望修改所有匹配的文档,那么您可以直接使用updateMany。类似地,如果你想用不同的url来修改多个文档(例如设置testVal字段),那么你也可以使用updateMany$in操作符来指定查询条件。只有当您希望在一个数据库请求中以不同的方式修改具有不同url值的文档时,才需要使用批量 Package 器。

ejk8hzay

ejk8hzay2#

需要创建一个显式的UNIQUE索引对属性我过滤。

相关问题