遵循here和here的回答,尝试使用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,
}
},
]);
型
我做错什么了?
2条答案
按热度按时间a14dhokn1#
我发现问题中提出的问题陈述以及the answer中提到的解决方案非常具有误导性。这个答案将试图澄清一些额外的背景,这对未来读者全面理解这种情况很重要。
暗示所提供的代码没有更新数据库是不正确的。问题描述中提供的来自数据库的回答 * 直接通过以下方式向我们展示了这一点:
字符串
具体地说,这告诉我们,命令处理的第一个文档与查询条件匹配,没有请求的
testVal
,因此被相应地修改。换句话说,updateOne
命令正如预期的那样更新了集合中的一个文档。提到的“答案”是在
url
字段上创建unique
索引。但是这个动作并没有突然使updateOne
或 PackagebulkWrap
本身表现出任何不同。相反,该操作首先约束集合中可以存在哪些数据。该命令仍将尝试更新最多一个文档,但现在最多只有一个文档可能匹配查询条件。综上所述,我们可以推断,最初发生的情况是,集合中有多个文档的值对应于正在测试的
url
字段。测试时更新的是其他文档(一次更新一个),而不是检查不同的文档(使用相同的url
)。从业务逻辑的Angular 来看,强制执行
unique
约束(或不强制执行)是完全可以接受的,但这样做只是改变了当前的数据,而不是“修复”似乎没有执行更新的命令。作为一个旁注,我想提一下,在问题描述中没有任何东西表明这里需要批量操作。如果您没有
unique
约束,并且希望修改所有匹配的文档,那么您可以直接使用updateMany
。类似地,如果你想用不同的url
来修改多个文档(例如设置testVal
字段),那么你也可以使用updateMany
和$in
操作符来指定查询条件。只有当您希望在一个数据库请求中以不同的方式修改具有不同url
值的文档时,才需要使用批量 Package 器。ejk8hzay2#
需要创建一个显式的UNIQUE索引对属性我过滤。