Mongo giving dup key error for fields with unique:

2020-07-25 09:46发布

问题:

UPDATE:Thanks JohnnyHK for your answer, my issue has been resolved!

Initial Question: Any ideas why I am getting the below error message? Note that everything before the "We are connected" line prints out even when the program runs properly.

DEBUG=cfcwebportal:* ./bin/www
[Error: /home/ben/Code For Chicago/cfcwebportal/node_modules
/mongoose/node_modules/mongodb/node_modules/mongodb-core/node_modules/bson/node_modules/bson-ext/build/Release/bson.node: invalid ELF header]
js-bson: Failed to load c++ bson extension, using pure JS version
[Error: /home/ben/Code For Chicago/cfcwebportal/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/node_modules/bson/node_modules/bson-ext/build/Release/bson.node: invalid ELF header]
js-bson: Failed to load c++ bson extension, using pure JS version
[Error: /home/ben/Code For Chicago/cfcwebportal/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/node_modules/bson/node_modules/bson-ext/build/Release/bson.node: invalid ELF header]
js-bson: Failed to load c++ bson extension, using pure JS version
[Error: /home/ben/Code For Chicago/cfcwebportal/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/node_modules/bson/node_modules/bson-ext/build/Release/bson.node: invalid ELF header]
js-bson: Failed to load c++ bson extension, using pure JS version
We are connected
meBob
{ [MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: cfc.students.$fname_1  dup key: { : "meBob" }]
  name: 'MongoError',
  message: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: cfc.students.$fname_1  dup key: { : "meBob" }',
  index: 0,
  code: 11000,
  errmsg: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: cfc.students.$fname_1  dup key: { : "meBob" }' }
We found students

Here's the file we are trying to run. It works correctly when every field is unique, but doesn't when any field is not unique, even though the "unique" field is set to "false" for all but "uname"

var express = require('express');
var router = express.Router();
var jsSHA = require("jssha"); // see https://github.com/Caligatio/jsSHA
//Checking if mongoose is npm installed
//Requires nmp install mongodb as well
var mongoose = require('mongoose');
//Using database "cfc"; if not creted will create for first time
mongoose.connect('mongodb://localhost/cfc')
var db = mongoose.connection;

function validatePresenceOf (value) {
    if(typeof value === 'string' || typeof value === 'number') {
        value = value.toString().trim();
    }
    return !!(value && value.length);
}

//In case not connected

db.on('error', console.error.bind(console, 'connection error: '));

db.once('open', function(callback) {

    //All prints are for debugging
    //Furthermore, we do not know what needs to be inside of db.once and what could be outside of db.once.
    console.log("We are connected");

    //Creating Schema
    var studentSchema = mongoose.Schema({
        uname: {
              type: String
            , required: true
            , unique: true
            , validate: [validatePresenceOf, 'Username is empty']
            },
        password: {
              type: String
            , required: true
            , unique: false
            , validate: [validatePresenceOf, 'Password is empty']
            },
        fname: {
              type: String
            , required: true
            , unique: false
            , validate: [validatePresenceOf, 'First name is empty']
            },
        lname: {
              type: String
            , required: true
            , unique: false
            , validate: [validatePresenceOf, 'Last name is empty']
            },
        organization: {
              type: String
            , required: true
            , unique: false
            , validate: [validatePresenceOf, 'Organization is empty']
            }
    });

    //Using the schema Student to create model
    var Student = mongoose.model('Student', studentSchema);

    // Creating the student Bob
    var bob = new Student({ uname: 'Sir Bob', password: 'mypass', fname: 'meBob', lname: 's', organization: 'moredeath' });
    console.log(bob.fname);

    //Saving the Student Bob
    bob.save(function (err, bob) {
        if (err) return console.log(err);
        console.log("We saved BOB");
    });

    //Finding all students
    var k = Student.find(function (err, students){
        if (err) return console.log("We did not find anything");
        console.log("We found students");
    });
    //console.log(k);
});

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

Here's my current db:

> db.students.find()
{ "_id" : ObjectId("55637c8f00a648751180f0b1"), "uname" : "UBob", "password" : "AyBob", "fname" : "Bob", "lname" : "Robertson", "organization" : "CFC", "__v" : 0 }
{ "_id" : ObjectId("5563847fadcdb986135440e0"), "uname" : "death", "password" : "death", "fname" : "death", "lname" : "death", "organization" : "death", "__v" : 0 }
{ "_id" : ObjectId("556386ab95a85003141b4733"), "uname" : "Ben", "password" : "mypass", "fname" : "meBob", "lname" : "s", "organization" : "moredeath", "__v" : 0 }

回答1:

Mongoose won't drop or redefine a previously created index based on the current schema, so I'm assuming you previously had a unique index on fname. Manually drop it in the shell and then restart your app:

db.students.dropIndex('fname_1')