使用 sparse: true 仍然出现 MongoError: E11000 重复键错误

6

模式(../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);

add-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 }

看到错误消息后,我进行了谷歌搜索,并了解到在创建文档时,由于名称未设置,因此被视为 null。请参阅 Mongoose Google Group 主题第一次调用 AM.notOwned 时,它将正常工作,因为没有任何不带名称键的集合文档。AM.notOwned 然后会插入一个具有 ID 字段和国家字段的文档。

后续的 AM.notOwned 调用失败,因为已经存在一个没有名称字段的文档,所以它被视为 name: null,并且第二个 AM.notOwned 在没有设置字段“name”且被视为 null 的情况下也失败;因此它不是唯一的。

因此,根据 Mongoose 主题的建议并阅读 mongo 文档,我考虑使用 sparse: true。然而,仍然会引发相同的错误。进一步研究后,我认为这可能是与 此问题 相同,但将 schema 设置为 name:{type:String,index:{unique:true,sparse:true}} 也无法解决它。

这个 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
    }
]

我该怎么做才能解决这个错误?
1个回答

8
您需要在Shell中删除旧的、非稀疏索引,以便Mongoose可以在下次应用程序运行时使用重新创建它。

> db.contacts.dropIndex('name_1')

db.contacts.dropIndex() 奏效了。虽然我尝试过使用 db.contacts.reIndex(),但没有解决问题。非常感谢您迅速且清晰的回答。我找遍了所有地方都无法找出错误所在。 - thtsigma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接