【问题标题】:Using sparse: true still getting MongoError: E11000 duplicate key error使用 sparse: true 仍然得到 MongoError: E11000 duplicate key 错误
【发布时间】:2013-02-08 08:45:09
【问题描述】:

架构 (../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。 See Mongoose Google Group Thread 第一次调用 AM.notOwned 时它将起作用,因为集合中没有任何文档没有名称键。然后 AM.notOwned 将插入一个包含 ID 字段和国家/地区字段的文档。

随后的 AM.notOwned 调用失败,因为已经有一个没有 name 字段的文档,因此将其视为 name: null,并且第二个 AM.notOwned 调用失败,因为未设置字段“name”并被视为也为空;因此它不是唯一的。

所以,按照 Mongoose 线程的建议并阅读 mongo docs 我查看了使用 sparse: true。但是,它仍然抛出相同的错误。进一步研究它,我认为它可能与以下问题相同:this,但将架构设置为名称:{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
    }
]

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

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

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

    > db.contacts.dropIndex('name_1')
    

    【讨论】:

    • db.contacts.dropIndex() 工作。虽然,我尝试使用 db.contacts.reIndex() 并没有解决它。感谢您的及时和简洁的回答。我终其一生都无法弄清楚我做错了什么并到处搜索。
    猜你喜欢
    • 2018-10-02
    • 2020-10-19
    • 2022-11-02
    • 2017-08-27
    • 2017-03-02
    • 2021-09-19
    • 2021-03-04
    • 2012-06-07
    • 2016-04-10
    相关资源
    最近更新 更多