使用稀疏:真仍然得到MongoError:E11000重复键错误

架构(../models/add.js)

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 } 

看到错误信息后,我search了一下,得知在创build文档时,由于没有设置名称,所以将其视为空。 请参阅Mongoose Google Group Thread第一次调用AM.notOwned时,它将工作,因为集合中没有任何文档没有名称键。 AM.notOwned然后将插入带有ID字段和国家字段的文档。

随后的AM.notOwned调用失败,因为已经有一个没有名称字段的文档,所以它被当作name:null处理,而第二个AM.notOwned被调用失败,因为没有设置字段“name”并被视为null ; 因此它不是唯一的。

所以,遵循Mongoose线程的build议并阅读使用sparse:true的mongo文档 。 但是,它仍然抛出同样的错误。 进一步研究它,我认为这可能是相同的问题: 这 ,但设置模式名称:{types:string,指数:{唯一:真,稀疏:真}}也不修复它。

这个问题/答案让我相信这可能是由索引不正确造成的,但我不太清楚如何从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 } ] 

我能做些什么来解决这个错误?

您需要在shell中删除旧的非稀疏索引,以便Mongoose可以在下次运行应用程序时使用sparse: true重新创build它。

 > db.contacts.dropIndex('name_1')