Mongoose 的 findOneAndUpdate 和 upsert 中的重复键错误
Duplicate key error in Mongoose' findOneAndUpdate and upsert
当来自我的 csv 文件的输入有两行或更多行具有相同的电子邮件地址时,我在使用 findOneAndUpdate 时遇到了一些问题。电子邮件地址在我的模型中设置为唯一,我认为 findOneAndUpdate 可以让我处理 csv 文件中的重复。代码如下。阅读 here 这是因为我的查询中的字段(在本例中为电子邮件)也是我想要创建的字段之一,以防找不到记录。我不确定这是不是真的。在任何情况下,电子邮件都是我的标识符,所以它必须在那里。
进一步解释该行为:
- 当 csv 文件包含在我 运行 我的脚本之前已经存储在 MongoDB 中的电子邮件地址时,findOneAndUpdate 完美运行
- 但是,当我在 csv 文件中有两条记录共享相同的电子邮件地址,但在 运行 脚本之前 MongoDB 中没有存储此电子邮件地址的记录时,我有时得到像这样的重复键错误
{ MongoError: E11000 duplicate key error collection: db.accounts index: email_1 dup key: { : "xxxxx@yahoo.com" }
- 我在上面写了有时,因为有时(虽然不太常见)我不这样做,一切都按预期进行。
代码:
for (let i = 0; i < accounts.length; i++) {
let query = {'email': accounts[i].email};
let accountHolderDoc = {
email: accounts[i].email,
name: {
first: accounts[i].accountHolderFName,
last: accounts[i].accountHolderLName,
},
};
promise = AccountHolder
.findOneAndUpdate(
query, {$set: accountHolderDoc}, {upsert: true, new: true})
.then(function(accountHolder) { ... })
.catch( ... );
...
}
表明搜索和保存不存在的文档不是原子的,这意味着在搜索和保存之间,另一个查询可能会针对相同的搜索条件产生未找到的结果。看来,唯一的解决方案是确保是否处理了重复键错误,例如,通过将 MongoDB 操作重新应用到被丢弃的文档。
当来自我的 csv 文件的输入有两行或更多行具有相同的电子邮件地址时,我在使用 findOneAndUpdate 时遇到了一些问题。电子邮件地址在我的模型中设置为唯一,我认为 findOneAndUpdate 可以让我处理 csv 文件中的重复。代码如下。阅读 here 这是因为我的查询中的字段(在本例中为电子邮件)也是我想要创建的字段之一,以防找不到记录。我不确定这是不是真的。在任何情况下,电子邮件都是我的标识符,所以它必须在那里。
进一步解释该行为:
- 当 csv 文件包含在我 运行 我的脚本之前已经存储在 MongoDB 中的电子邮件地址时,findOneAndUpdate 完美运行
- 但是,当我在 csv 文件中有两条记录共享相同的电子邮件地址,但在 运行 脚本之前 MongoDB 中没有存储此电子邮件地址的记录时,我有时得到像这样的重复键错误
{ MongoError: E11000 duplicate key error collection: db.accounts index: email_1 dup key: { : "xxxxx@yahoo.com" }
- 我在上面写了有时,因为有时(虽然不太常见)我不这样做,一切都按预期进行。
代码:
for (let i = 0; i < accounts.length; i++) {
let query = {'email': accounts[i].email};
let accountHolderDoc = {
email: accounts[i].email,
name: {
first: accounts[i].accountHolderFName,
last: accounts[i].accountHolderLName,
},
};
promise = AccountHolder
.findOneAndUpdate(
query, {$set: accountHolderDoc}, {upsert: true, new: true})
.then(function(accountHolder) { ... })
.catch( ... );
...
}