我们(从 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});
Run Code Online (Sandbox Code Playgroud)
和 [target_group.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});
Run Code Online (Sandbox Code Playgroud)
当我尝试更新目标组内的公司时
_updateTargetGroup(companyId, company) {
return this.targetGroup.update(
{'companies._id': companyId},
{$set: {'companies.$': company}},
{multi: true});
}
Run Code Online (Sandbox Code Playgroud)
我收到
MongoError:更新路径“companies.$.updatedAt”会在“companies.$”处产生冲突
即使我前置
delete company.updatedAt;
delete company.createdAt;
Run Code Online (Sandbox Code Playgroud)
我收到这个错误。
如果我尝试类似的数据库工具(Robo3T),一切正常:
db.getCollection('targetgroups').update(
{'companies.name': "Test 1"},
{$set: {'companies.$': {name: "Test 2"}}},
{multi: true});
Run Code Online (Sandbox Code Playgroud)
当然我可以使用解决方法
_updateTargetGroup(companyId, company) {
return this.targetGroup.update(
{'companies._id': companyId},
{$set: {'companies.$.name': company.name}},
{multi: true});
}
Run Code Online (Sandbox Code Playgroud)
(这确实有效),但我想了解这个问题,并且我们的项目中还有更大的模型也存在同样的问题。
这是{timestamps: true}的问题吗?我寻找解释但找不到任何东西......:-(
该问题源于使用timestamps您提到的但我不会将其称为“错误”,因为在这种情况下我可以说它正在按预期工作。
首先让我们了解 usingtimestamps在代码中的作用,下面是 mongoose 对带有时间戳的数组 ( companyarray ) 执行的代码示例:(源代码)
for (let i = 0; i < len; ++i) {
if (updatedAt != null) {
arr[i][updatedAt] = now;
}
if (createdAt != null) {
arr[i][createdAt] = now;
}
}
Run Code Online (Sandbox Code Playgroud)
这在每次更新/插入时运行。正如您所看到的,它设置了数组中每个对象的updatedAt和,这意味着更新对象从以下位置更改:createdAt
{$set: {'companies.$.name': company.name}}
Run Code Online (Sandbox Code Playgroud)
到:
{
"$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
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当您尝试使用两个不同的值/操作更新同一字段时,就会发生错误,例如,如果您要更新同一字段$set,并且$unset同一更新中的同一字段 Mongo 不执行任何操作,因此会引发错误。
在你的情况下,它是由于companies.$.updatedAt场而发生的。因为您正在更新整个对象companies.$,这意味着您基本上将其设置为{name: "Test 2"}这也意味着您正在“删除”该updatedAt字段(以及其他字段),而猫鼬试图将其设置为它自己的值,从而导致错误。这也是为什么您的更改companies.$.name有效,因为您只设置name字段而不是整个对象,因此不会产生冲突。
| 归档时间: |
|
| 查看次数: |
2373 次 |
| 最近记录: |