2017-09-23 137 views
1

当来自我的csv文件的输入具有两个或多个具有相同电子邮件地址的行时,我遇到findOneAndUpdate的一些问题。电子邮件地址在我的模型中设置为唯一,我认为findOneAndUpdate会让我处理我的csv文件中的重复。代码如下。阅读here,这是因为我查询中的字段(在这种情况下是电子邮件)也是我想创建的字段之一,以防记录找不到。我不确定这是否属实。无论如何,电子邮件是我的标识符,所以它必须在那里。Mongoose'findOneAndUpdate和upsert中存在重复键错误

为了解释这一行为更多:

  1. 当CSV文件中包含一个已经存储在MongoDB中之前,我跑我的脚本的电子邮件地址,findOneAndUpdate完美的作品
  2. 然而,当我在两个记录共享相同的电子邮件地址,但没有这个电子邮件地址的记录CSV文件运行脚本之前存储在MongoDB中,我有时会重复键错误,像这样{ MongoError: E11000 duplicate key error collection: db.accounts index: email_1 dup key: { : "[email protected]" }
  3. 我写有时以上,因为有时(虽然LES经常)我不是,一切都按原样运作。

代码:

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(...); 
    ... 
} 

预先感谢您的帮助!

回答

0

This post建议搜索并保存不存在的文档不是原子的,这意味着在搜索和保存之间,另一个查询可能已经为相同的搜索条件产生了未找到的结果。唯一的解决方案似乎是确保处理重复键错误,例如,通过将MongoDB操作重新应用到被抛出的文档。

我现在会遵循这个解决方案。如果任何人有不同的处理方法,请告诉我。谢谢!

+0

我建议你使用[async.js](http://caolan.github.io/async/)进行循环,特别是[async.eachSeries()](http://caolan.github.io/async /docs.html#eachSeries)一次执行一项操作。将同步'for'与异步Mongoose操作混合总是会导致问题。 – Mikey