2013-02-22 51 views
4

架構(../models/add.js)使用稀疏:真仍然得到MongoError:E11000重複鍵錯誤

var addSchema = new Schema({ 
    name: {type: String, unique: true, sparse: true}, 
    phone: Number, 
    email: String, 
    country: Number 
}); 

module.exports = mongoose.model('Contact', addSchema); 

附加manager.js

var Add = require('../models/add.js'); 
var AM = {}; 
var mongoose = require('mongoose'); 
module.exports = AM; 

AM.notOwned = function(country, callback) 
{ 
    Add.update({country: country}, {country: country}, {upsert: true}, function(err, res){ 
     if (err) callback (err); 
     else callback(null, res); 
    }) 
} 

news.js

// if country # is not in the database 
    AM.notOwned(country, function(error, resp){ 
     if (error) console.log("error: "+error); 
     else 
     { 
      // do stuff 
     } 
    }) 

錯誤:

MongoError: E11000 duplicate key error index: bot.contacts.$name_1 dup key: { : null } 

看到錯誤信息後,我搜索了一下,並瞭解到在創建文檔時,由於未設置名稱,因此將其視爲空。 See Mongoose Google Group Thread第一次調用AM.notOwned時,它將工作,因爲集合中沒有任何文檔沒有名稱鍵。 AM.notOwned將隨後插入帶有ID字段和國家字段的文檔。

隨後的AM.notOwned調用失敗,因爲已經有一個沒有名稱字段的文檔,因此它被視爲name:null,而第二個AM.notOwned被調用失敗,因爲未設置字段「name」並被處理也爲null;因此它不是唯一的。

因此,遵循Mongoose線程的建議並閱讀mongo docs,我使用sparse:true來查看。但是,它仍然拋出同樣的錯誤。進一步研究它,我認爲它可能與以下問題相同:this,但將模式設置爲name:{type:String,index:{unique:true,sparse:true}}也不修復它。

This S.O.問題/答案使我相信這可能是由索引不正確引起的,但我不太清楚如何從Mongo控制檯讀取db.collection.getIndexes()。

db.contacts.getIndexes() 
[ 
    { 
     "v" : 1, 
     "key" : { 
      "_id" : 1 
     }, 
     "ns" : "bot.contacts", 
     "name" : "_id_" 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "name" : 1 
     }, 
     "unique" : true, 
     "ns" : "bot.contacts", 
     "name" : "name_1", 
     "background" : true, 
     "safe" : null 
    } 
] 

我能做些什麼來解決這個錯誤?

回答

5

您需要在shell中刪除舊的非稀疏索引,以便Mongoose可以在您的應用下次運行時使用sparse: true重新創建該索引。

> db.contacts.dropIndex('name_1') 
+0

db.contacts.dropIndex()工作。雖然,我嘗試使用db.contacts.reIndex(),並沒有解決它。感謝您提供的簡明扼要的答案。我不能爲了我的生活找出我做錯了什麼,到處搜尋。 – thtsigma 2013-02-22 17:08:32