Mongoose' findOneAndUpdate 和 upsert 中的重复键错误

fab*_*fab 8 javascript asynchronous upsert mongoose mongodb

当来自我的 csv 文件的输入有两行或更多行具有相同的电子邮件地址时,我在使用 findOneAndUpdate 时遇到了一些问题。电子邮件地址在我的模型中设置为唯一,我认为 findOneAndUpdate 可以让我处理 csv 文件中的重复。代码如下。在这里阅读这是因为我的查询中的字段(在本例中为电子邮件)也是我要创建的字段之一,以防找不到记录。我不确定这是否属实。无论如何,电子邮件是我的标识符,所以它必须在那里。

更详细地解释这种行为:

  1. 当 csv 文件包含在我运行脚本之前已经存储在 MongoDB 中的电子邮件地址时, findOneAndUpdate 可以完美运行
  2. 但是,当我在 csv 文件中有两条记录共享相同的电子邮件地址但在运行脚本之前没有该电子邮件地址的记录存储在 MongoDB 中时,我有时会收到像这样的重复键错误 { MongoError: E11000 duplicate key error collection: db.accounts index: email_1 dup key: { : "xxxxx@yahoo.com" }
  3. 有时会在上面写,因为有时(虽然不太频繁)我不这样做,而且一切都按原样进行。

代码:

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( ... );
   ...
}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助!

fab*_*fab 3

这篇文章表明,搜索和保存不存在的文档不是原子的,这意味着在搜索和保存之间,另一个查询可能会针对相同的搜索条件产生未找到的结果。那么,唯一的解决方案似乎是确保处理重复的键错误,例如,通过将 MongoDB 操作重新应用于被抛出的文档。