最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

为什么MongoDB为该模式中不存在的字段创建索引?

IT培训 admin 11浏览 0评论

为什么MongoDB为该模式中不存在的字段创建索引?

TL; DR:我的mongo数据库出现问题,似乎是从我的用户集合中的字段为我的电路板集合创建索引,这在我尝试创建新电路板时导致E11000错误。

我正在建立一个看板(如Jira)并拥有董事会,任务和用户集合(实体关系图:)。所有集合都可以在.dropIndexes()之后正常工作。但是,当我在一块板上通过UI处理任务时,当我尝试创建另一块板时,我收到此E11000错误:

{ MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: kanban.boards.$username_1  dup key: { : null }
    at Function.create (/home/ubuntu/workspace/kanban v1.0/node_modules/mongodb-core/lib/error.js:43:12)
    at toError (/home/ubuntu/workspace/kanban v1.0/node_modules/mongodb/lib/utils.js:149:22)
    at coll.s.topology.insert (/home/ubuntu/workspace/kanban v1.0/node_modules/mongodb/lib/operations/collection_ops.js:859:39)
    at /home/ubuntu/workspace/kanban v1.0/node_modules/mongodb-core/lib/connection/pool.js:532:18
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  driver: true,
  name: 'MongoError',
  index: 0,
  code: 11000,
  errmsg: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: kanban.boards.$username_1  dup key: { : null }' }

这似乎是因为电路板架构中的用户名字段中存在空值,但此模型中没有此类字段,如下所示:

// Board Schema

// Config
var mongoose = require("mongoose"),
    passportLocalMongoose = require("passport-local-mongoose");


// Create Board Schema

var BoardSchema = new mongoose.Schema({
    user: {type: mongoose.Schema.Types.ObjectId, ref: "User", unique: true, sparse: true},
    todo: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}],
    inProgress: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}],
    testing: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}],
    completed: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}]
});


// Validation
BoardSchema.plugin(passportLocalMongoose);


// Export Model
module.exports = mongoose.model("Board", BoardSchema);

这是db中的示例板:

{ "_id" : ObjectId("5c65767c8977670a2366ffe5"), 
"todo" : [ ObjectId("5c657a1e451bc80ac315ef35"), ObjectId("5c657a4a451bc80ac315ef37"), ObjectId("5c657a76451bc80ac315ef39") ], 
"inProgress" : [ ObjectId("5c6579e1451bc80ac315ef31"), ObjectId("5c657a03451bc80ac315ef33"), ObjectId("5c657a3a451bc80ac315ef36"), ObjectId("5c657a8a451bc80ac315ef3a") ], 
"testing" : [ ObjectId("5c657a9a451bc80ac315ef3b") ], 
"completed" : [ ObjectId("5c657a60451bc80ac315ef38"), ObjectId("5c65bb8f6f5b731aec27b4a7"), ObjectId("5c65bba06f5b731aec27b4a8"), ObjectId("5c657a11451bc80ac315ef34") ], 
"user" : ObjectId("5c65767b8977670a2366ffe4"), 
"__v" : 51 }

出于某种原因,我认为数据库已为board模式创建了用户名索引。董事会集合的索引如下:

[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "kanban.boards"
        },
        {
                "v" : 1,
                "key" : {
                        "user" : 1
                },
                "name" : "user_1",
                "ns" : "kanban.boards",
                "background" : true
        },
        {
                "v" : 1,
                "unique" : true,
                "key" : {
                        "username" : 1
                },
                "name" : "username_1",
                "ns" : "kanban.boards",
                "background" : true
        }
]

为完整起见,这是用户架构:

// User Schema

// Config

var mongoose = require("mongoose"),
    uniqueValidator = require("mongoose-unique-validator"),
    passportLocalMongoose = require("passport-local-mongoose");


// Create User Schema

var UserSchema = new mongoose.Schema({
    username: {type: String, required: true, unique: true},
    password: String
});


// Validation and Hash/Salt PW
UserSchema.plugin(uniqueValidator, {message: "A user is already registered with that {PATH}."});
UserSchema.plugin(passportLocalMongoose);


// Export Model
module.exports = mongoose.model("User", UserSchema);

导致错误的代码在注册路由中,其中一部分如下所示:

// create new board for user
        var newBoard = {
            user: user._id,
            todo: [],
            inProgress: [],
            testing: [],
            review: [],
            completed: [],
        };


        Board.create(newBoard, function(err, board) {
            if(err) {
                console.log(err);
                req.flash("error", "Uh oh! Something went wrong.");
                return res.redirect("/");
            }

            // authenticate user
            passport.authenticate("local")(req, res, function() {
                req.flash("success", "Welcome to your Kanban board, " + user.username + ".");
                return res.redirect("/board");
            });

        });

我不明白为什么要创建这个索引(或者确实如果这是导致E11000错误的原因,但我很确定它是)。对代码的垃圾邮件道歉,我对使用mongo非常缺乏经验,所以不知道什么是相关的,什么不是。我已经构建了具有多个集合的mongo数据库,但之前没有链接集合,所以我无法弄清楚出了什么问题。如果我错过了任何有用或重要的内容,请告诉我。谢谢。

回答如下:

我不是100%确定这是否是问题,但你应该从BoardSchema.user参数中删除unique: truesparse: true。由于您在UserSchema中声明了那些,因此您不应该在BoardSchema中使用它们。

编辑:您可能还必须在完成第一步后手动删除索引。

为什么MongoDB为该模式中不存在的字段创建索引?

TL; DR:我的mongo数据库出现问题,似乎是从我的用户集合中的字段为我的电路板集合创建索引,这在我尝试创建新电路板时导致E11000错误。

我正在建立一个看板(如Jira)并拥有董事会,任务和用户集合(实体关系图:)。所有集合都可以在.dropIndexes()之后正常工作。但是,当我在一块板上通过UI处理任务时,当我尝试创建另一块板时,我收到此E11000错误:

{ MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: kanban.boards.$username_1  dup key: { : null }
    at Function.create (/home/ubuntu/workspace/kanban v1.0/node_modules/mongodb-core/lib/error.js:43:12)
    at toError (/home/ubuntu/workspace/kanban v1.0/node_modules/mongodb/lib/utils.js:149:22)
    at coll.s.topology.insert (/home/ubuntu/workspace/kanban v1.0/node_modules/mongodb/lib/operations/collection_ops.js:859:39)
    at /home/ubuntu/workspace/kanban v1.0/node_modules/mongodb-core/lib/connection/pool.js:532:18
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  driver: true,
  name: 'MongoError',
  index: 0,
  code: 11000,
  errmsg: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: kanban.boards.$username_1  dup key: { : null }' }

这似乎是因为电路板架构中的用户名字段中存在空值,但此模型中没有此类字段,如下所示:

// Board Schema

// Config
var mongoose = require("mongoose"),
    passportLocalMongoose = require("passport-local-mongoose");


// Create Board Schema

var BoardSchema = new mongoose.Schema({
    user: {type: mongoose.Schema.Types.ObjectId, ref: "User", unique: true, sparse: true},
    todo: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}],
    inProgress: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}],
    testing: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}],
    completed: [{type: mongoose.Schema.Types.ObjectId, ref: "Task"}]
});


// Validation
BoardSchema.plugin(passportLocalMongoose);


// Export Model
module.exports = mongoose.model("Board", BoardSchema);

这是db中的示例板:

{ "_id" : ObjectId("5c65767c8977670a2366ffe5"), 
"todo" : [ ObjectId("5c657a1e451bc80ac315ef35"), ObjectId("5c657a4a451bc80ac315ef37"), ObjectId("5c657a76451bc80ac315ef39") ], 
"inProgress" : [ ObjectId("5c6579e1451bc80ac315ef31"), ObjectId("5c657a03451bc80ac315ef33"), ObjectId("5c657a3a451bc80ac315ef36"), ObjectId("5c657a8a451bc80ac315ef3a") ], 
"testing" : [ ObjectId("5c657a9a451bc80ac315ef3b") ], 
"completed" : [ ObjectId("5c657a60451bc80ac315ef38"), ObjectId("5c65bb8f6f5b731aec27b4a7"), ObjectId("5c65bba06f5b731aec27b4a8"), ObjectId("5c657a11451bc80ac315ef34") ], 
"user" : ObjectId("5c65767b8977670a2366ffe4"), 
"__v" : 51 }

出于某种原因,我认为数据库已为board模式创建了用户名索引。董事会集合的索引如下:

[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "kanban.boards"
        },
        {
                "v" : 1,
                "key" : {
                        "user" : 1
                },
                "name" : "user_1",
                "ns" : "kanban.boards",
                "background" : true
        },
        {
                "v" : 1,
                "unique" : true,
                "key" : {
                        "username" : 1
                },
                "name" : "username_1",
                "ns" : "kanban.boards",
                "background" : true
        }
]

为完整起见,这是用户架构:

// User Schema

// Config

var mongoose = require("mongoose"),
    uniqueValidator = require("mongoose-unique-validator"),
    passportLocalMongoose = require("passport-local-mongoose");


// Create User Schema

var UserSchema = new mongoose.Schema({
    username: {type: String, required: true, unique: true},
    password: String
});


// Validation and Hash/Salt PW
UserSchema.plugin(uniqueValidator, {message: "A user is already registered with that {PATH}."});
UserSchema.plugin(passportLocalMongoose);


// Export Model
module.exports = mongoose.model("User", UserSchema);

导致错误的代码在注册路由中,其中一部分如下所示:

// create new board for user
        var newBoard = {
            user: user._id,
            todo: [],
            inProgress: [],
            testing: [],
            review: [],
            completed: [],
        };


        Board.create(newBoard, function(err, board) {
            if(err) {
                console.log(err);
                req.flash("error", "Uh oh! Something went wrong.");
                return res.redirect("/");
            }

            // authenticate user
            passport.authenticate("local")(req, res, function() {
                req.flash("success", "Welcome to your Kanban board, " + user.username + ".");
                return res.redirect("/board");
            });

        });

我不明白为什么要创建这个索引(或者确实如果这是导致E11000错误的原因,但我很确定它是)。对代码的垃圾邮件道歉,我对使用mongo非常缺乏经验,所以不知道什么是相关的,什么不是。我已经构建了具有多个集合的mongo数据库,但之前没有链接集合,所以我无法弄清楚出了什么问题。如果我错过了任何有用或重要的内容,请告诉我。谢谢。

回答如下:

我不是100%确定这是否是问题,但你应该从BoardSchema.user参数中删除unique: truesparse: true。由于您在UserSchema中声明了那些,因此您不应该在BoardSchema中使用它们。

编辑:您可能还必须在完成第一步后手动删除索引。

发布评论

评论列表 (0)

  1. 暂无评论