无法弄清楚如何摆脱MongoDB中的这个重复键错误

时间:2017-12-24 21:40:25

标签: javascript node.js mongodb

我一直坚持这个错误几个小时,我无法弄清楚导致重复键错误的原因。

重复的密钥为null,我不知道这是指什么。这是错误:

{ MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: my_db.schools.$username_1  dup key: { : null }

我有学校模式:

var mongoose = require('mongoose');
var passportLocalMongoose = require('passport-local-mongoose');

var schoolSchema = new mongoose.Schema({
    name: String,
    location: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User"
        },
        username: String
    },
    code: Number,
    members: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User"
        }
    ],
    cluborgs: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "Cluborg"
        }
    ],
    date_joined: {type: Date, default: Date.now}
});

schoolSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model("School", schoolSchema);

与此Schema相关的一些路线:

var express = require('express');
var router = express.Router();
var School = require('../models/school');
var middleware = require('../middleware');

//index
router.get("/", function(req, res) {
    School.find({}, function(err, allSchools) {
        if (err) {
            console.log(err);
        } else {
            res.render("schools/index", {schools: allSchools});
        }
    });
});

//new
router.get("/new", middleware.isLoggedIn, function(req, res) {
    res.render("schools/new");
});

//create
router.post("/", middleware.isLoggedIn, function(req, res) {
    var author = {
        id: req.user._id,
        username: req.user.username
    };
    
    var school = {
        name: req.body.school.name,
        location: req.body.school.location,
        author: author,
        code: req.body.school.code
    };
    School.create(school, function(err, newlyCreated) {
        if (err) {
            console.log(err);
        } else {
            req.flash("success", "Successfully created " + newlyCreated.name);
            res.redirect("/schools");
        }
    });    
});

//show
router.get("/:id", middleware.isLoggedIn, function(req, res) {
    School.findById(req.params.id)
        .populate("cluborgs")
        .exec(function(err, foundSchool) {
            if (err) {
                console.log(err);
            } else {
                res.render("schools/show", {school: foundSchool});
            }
    });  
});

//edit
router.get("/:id/edit", middleware.checkSchoolOwnership, function(req, res) {
    School.findById(req.params.id, function(err, foundSchool) {
        if (err) {
            console.log(err);
        } else {
            res.render("schools/edit", {schools: foundSchool});
        }
    });
});

//update
router.put("/:id", middleware.checkSchoolOwnership, function(req, res) {
    School.findByIdAndUpdate(req.params.id, req.body.school, function(err, updatedSchool) {
        if (err) {
            console.log(err);
        } else {
            req.flash("success", "Successfully updated school.");
            res.redirect("/schools/" + req.params.id);
        }
    });
});

//destroy
router.delete("/:id", middleware.checkSchoolOwnership, function(req, res) {
    School.findByIdAndRemove(req.params.id, function(err) {
        if (err) {
            res.redirect("/schools");
        } else {
            res.redirect("/schools");
        }
    });
});

module.exports = router; //put this in EVERY single one of your routes file to get rid of router errors

当我创建第二所学校时出现错误。 我做错了什么?

1 个答案:

答案 0 :(得分:0)

从Mongoose属性中删除unique: true并不会自动从MongoDB中删除索引。

此外,如果从Mongoose模式中完全删除属性,它也不会自动从MongoDB中删除相关索引。

所以看起来在你的情况下,MongoDB仍然期望你从模式中删除一个唯一的School.username值,因此默认为每个文档的空值 - 触发唯一约束。

我个人使用MongoDB CLI删除这些索引,但我怀疑该属性上的unique: false设置也可以。