2017-04-09 80 views
0

我有一個函數,應該從mongo數據庫的「ID」中找到一個問題,並返回它,如果它沒有找到一個它創建一個然後返回它。它是我的代碼中唯一能夠在數據庫中創建新問題實體的功能。這就是: (順便說一句我使用的NodeJS官方MongoDB的驅動程序)MongoDb NodeJS驅動程序findOneAndUpdate無法自動工作

function getQuestionEntity(questionID, cb){ 
    const questions = db.collection('questions') 

    questions.findOneAndUpdate(
     {ID: questionID}, 
     {$setOnInsert: 
      { 
       ID: questionID, 
       rating: 1.5, 
       options: 4, 
       answeredRight: 0, 
       answeredWrong: 0 

      } 
     }, 
     { 
      returnOriginal: false, 
      upsert: true 
     }, 
     (err, r)=>{ 
      if(err){throw new Error(err)} 
      cb(r.value) 
     } 
    ) 
} 

我已閱讀,findOneAndUpdate是一個原子操作,這意味着即使我環路此功能異步到時代的結束,我仍然不會在數據庫中獲得兩個具有相同「ID」字段的問題實體,但這正是發生的情況。

我的代碼有什麼問題嗎?我錯了我的假設?

+1

更新操作是原子操作,但upsert不是。請參閱[這裏](https://stackoverflow.com/questions/37295648/mongoose-duplicate-key-error-with-upsert/37485551#37485551)。因此,您需要爲'ID'添加唯一索引,然後在出現重複鍵時處理重複錯誤。 – JohnnyHK

+0

好的,謝謝! – Fuseques

回答

0

不要設置文件的ID兩次,然後你會用這樣的結尾:

questions.findOneAndUpdate(
    {ID: questionID}, 
    {$set: {rating: 1.5, options: 4, answeredRight: 0, answeredWrong: 0}}, 
    {upsert: true}, 
    (err, r)=>{ 
     if(err){throw new Error(err)} 
     cb(r.value) 
    } 
    ) 

我沒有測試此代碼的NodeJS;不要使用$ setOnInsert,因爲它只在插入時有效,並且在文檔已經存在時它不會更新密鑰。

+0

我插入的ID是一個我從一個不同的數據庫中獲得,我也想不更新,如果它已經存在。 – Fuseques

+0

好的,正如@JohnnyHK所說,ID是唯一的。 – Euclides

相關問題