数组中的 MongoDB 更新失败:更新路径“companies.$.updatedAt”会在“companies.$”处产生冲突

2023-11-26

我们(从 MongoDB 3.4)升级到:

MongoDB:4.2.8

猫鼬:5.9.10

现在我们收到了这些错误。对于最小的例子,模型是:

[公司.js]

'use strict';

const Schema = require('mongoose').Schema;

module.exports = new Schema({
  name: {type: String, required: true},
}, {timestamps: true});

and [目标组.js]

'use strict';

const Schema = require('mongoose').Schema;

module.exports = new Schema({
  title: {
    type: String,
    required: true,
    index: true,
  },
  minAge: Number,
  maxAge: Number,
  companies: [Company],
}, {timestamps: true});

当我尝试更新目标组内的公司时

  _updateTargetGroup(companyId, company) {
    return this.targetGroup.update(
      {'companies._id': companyId},
      {$set: {'companies.$': company}},
      {multi: true});
  }

我收到

MongoError:更新路径“companies.$.updatedAt”会在“companies.$”处产生冲突

即使我前置

    delete company.updatedAt;
    delete company.createdAt;

我收到这个错误。

如果我尝试类似的数据库工具(Robo3T),一切正常:

db.getCollection('targetgroups').update(
  {'companies.name': "Test 1"},
  {$set: {'companies.$': {name: "Test 2"}}},
  {multi: true});

当然我可以使用解决方法

  _updateTargetGroup(companyId, company) {
    return this.targetGroup.update(
      {'companies._id': companyId},
      {$set: {'companies.$.name': company.name}},
      {multi: true});
  }

(这确实有效),但我想了解这个问题,并且我们的项目中还有更大的模型也存在同样的问题。

这是一个问题吗{时间戳:true}?我寻找解释但找不到任何东西......:-(


该问题源于使用timestamps正如您所提到的,但我不会将其称为“错误”,因为在这种情况下,我可以说它正在按预期工作。

首先我们来了解一下使用什么timestamps在代码中执行的操作,这里是 mongoose 对数组执行的操作的代码示例(company数组)和时间戳:(source)

  for (let i = 0; i < len; ++i) {
    if (updatedAt != null) {
      arr[i][updatedAt] = now;
    }
    if (createdAt != null) {
      arr[i][createdAt] = now;
    }
  }

这在每次更新/插入时运行。正如你所看到的,它设置了updatedAt and createdAt数组中每个对象的含义意味着更新对象从以下位置更改:

{$set: {'companies.$.name': company.name}}

To:

{
  "$set": {
    "companies.$": company.name,
    "updatedAt": "2020-09-22T06:02:11.228Z", //now
    "companies.$.updatedAt": "2020-09-22T06:02:11.228Z" //now
  },
  "$setOnInsert": {
    "createdAt": "2020-09-22T06:02:11.228Z" //now
  }
}

现在,当您尝试使用两个不同的值/操作更新同一字段时,例如,如果您要$set and $unset同一更新中的同一字段 Mongo 不执行任何操作,因此会引发错误。

在你的情况下,它的发生是由于companies.$.updatedAt场地。因为您正在更新整个对象companies.$,这意味着您基本上将其设置为{name: "Test 2"}这也意味着您正在“删除”updatedAt字段(以及其他),而猫鼬试图将其设置为它自己的值,从而导致错误。这也是您更改为的原因companies.$.name工作原理就像你只需要设置name字段而不是整个对象,因此不会产生冲突。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数组中的 MongoDB 更新失败:更新路径“companies.$.updatedAt”会在“companies.$”处产生冲突 的相关文章

随机推荐