2013-04-02 40 views
0

所以我有一個嵌套輪廓屬性的用戶模式,我想確保所有個人資料的ID都是唯一的,當配置文件屬性是否存在:使用「唯一」與貓鼬嵌套對象

UserSchema = new Schema { 
    ... 
    ... 
    profile : { 
     id : { 
      type : String 
      unique : true 
      sparse : true 
     } 
     ... 
     ... 
    } 
} 

但是,在運行我的測試時,我可以使用相同的profile.id值保存兩個不同的用戶。是否在嵌套文檔上強制執行唯一屬性?我錯過了什麼嗎?

打開日誌記錄後,我能看到像這樣的輸出(我已刪除大多數領域):正在插入

Mongoose: users.ensureIndex({ email: 1 }) { safe: undefined, background: true, unique: true } 
Mongoose: users.insert({ profile: { id: '31056' }) {} 
Mongoose: users.ensureIndex({ 'profile.id': 1 }) { safe: undefined, background: true, sparse: true, unique: true } 
Mongoose: users.insert({ profile: { id: '31056' }) {} 

重複的值。

+1

是,對嵌套文檔執行唯一索引。可能發生的事情是,它不能創建索引,因爲你已經有重複。請參閱[這個答案](http://stackoverflow.com/a/12453041/1259510)關於調試的一些技巧。 – JohnnyHK

+0

感謝Johnny的建議,但我一直在測試之間丟棄數據庫,所以我不認爲這是事實。我將使用您提供的鏈接中的步驟來進行一些調試。 –

+1

索引創建也是異步的。這可能是一種競爭條件。嘗試在插入前等待索引事件。 – aaronheckmann

回答

0

Aaron的建議修正了索引創建異步引起的競爭條件。我等待執行我的用戶架構的單元測試,直到發生索引事件:

User.on('index', function (err) { ... }) 
2

也許它只在嵌套屬性內驗證爲唯一。我從來沒有信任unique我自己,總是去手動驗證,這樣我可以有更多的控制:

從來沒有在Mongoose自己與nestes文件工作,並不十分確定它是否會工作,但至少爲你有一個想法:

User.schema.path('profile.id').validate(function(value, respond) { 
    mongoose.models["User"].findOne({ profile.id: value }, function(err, exists) { 
    respond(!!exists); 
    }); 
}, 'Profile ID already exists'); 
+0

感謝您的解決方案,如果嵌套文檔上的唯一內容不符合我的預期,我將使用它。 –