2016-05-14 71 views
0

我認識到這個問題有beenaskedbefore,但沒有任何解決方案似乎對我工作。獨特的驗證不工作在貓鼬

我有我定義這樣一個簡單的模型:

const mongoose = require('mongoose') 
const { Schema } = mongoose 

let subscriberSchema = new Schema({ 
    firstName: { type: String, required: true }, 
    email: { type: String, required: true, unique: true } 
}, { timestamps: true }) 

let Subscriber = mongoose.model('Subscriber', subscriberSchema) 

如果我運行下面的(在REPL,所以沒有異步問題),我希望看到被記錄的錯誤第二次致電create

Subscriber.create({ firstName: "Landon", email: "[email protected]" }) 
Subscriber.create({ firstName: "Landon", email: "[email protected]" }, function(err) { 
    console.log("ERROR", err) 
}) 

取而代之,我看到"ERROR" null

如果我運行count查詢或find查詢,我可以看到兩個模型都已創建。我究竟做錯了什麼?

編輯

這裏有一些我已經嘗試過的事情:

  • 重啓MongoDB中添加索引
  • 刪除所有的現有記錄,所以沒有現有記錄後這可能違反唯一性約束
  • 定義email屬性所有這些方法(我已經看到不同地方的不同實現):{ type: String, required: true, unique: true }{ type: String, required: true, index: true, unique: true }{ type: String, required: true, index: { unique: true } }
+0

你可以編輯你的問題,包括你檢查了鏈接的問題,以便我們不必問這些相同的問題嗎? – JohnnyHK

+0

@JohnnyHK當然,沒問題。更新。 – LandonSchropp

回答

2

這是非常複雜的事情來解決與節點,因爲你知道它的異步。 如果您同時運行兩個查詢,兩者都會檢查doc是否存在同一時間,並且兩者都會嘗試創建記錄。

你可以做兩件事。

創建唯一索引

YourModel.index({ email: 1}, { unique: true }) 

OR
使用更新與$ setOnInsert

var pk = {email : 'your email'}; 
YourModel.update(pk, { 
     $setOnInsert : data 
    }, {upsert : true}) 

,並確保該指數在MongoDB中存在。

Mongoose不會修改鍵集上的索引。首先嚐試從mongo shell中刪除索引。

db.collection.dropIndex({email : 1}) 

重新啓動節點進程和貓鼬現在將創建具有唯一約束的索引。

+0

我不認爲我的問題很清楚。 Subscriber.create'調用的示例在Node REPL中,所以不應該有任何異步問題。我跑了第一個創建,等待它完成,然後跑第二個。如果我稍後運行後續的「創建」,我仍然會看到相同的問題。 – LandonSchropp

+0

無論何時添加索引,都必須重新啓動節點進程,Mongoose autoIndex將嘗試確保索引。你可以看到用貓鼬調試。並確保指數在* getIndexes()集合* – anwerj

+0

我試過重新啓動服務器以及mongod,但不幸的是,似乎沒有幫助。運行'Scheduler.collection.getIndexes()'解決此問題:'{_id_:[['_id',1]],email_1:[['email',1]]}'。我沒有看到有關獨特性的任何內容,但我不確定是否應該這樣做,而且我也不知道如何解決這個問題。 – LandonSchropp