akonsu
akonsu

Reputation: 29536

compound index not working?

I am trying to create a compound index using mongoose:

var ProjectSchema = new mongoose.Schema({
    name: {type: String, required: true},
    user: {type: mongoose.Schema.ObjectId, ref: 'User', required: true}
});

ProjectSchema.index({user: 1, name: 1}, {unique: true});

after that I dropped the old database in mongo

db.dropDatabase()

but I still can insert multiple documents with the same name and user id. why?

the index that it created shows in mongo as

> db.projects.getIndexes();
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "mydatabase.projects",
        "name" : "_id_"
    }
]

Upvotes: 3

Views: 3836

Answers (4)

HRK44
HRK44

Reputation: 2762

I just had this problem, the compound index was not created at startup and I was checking the mongo logs, I could see that it was starting the build of the index but nothing was created, no errors etc...

Then I tried to manually create the index - in mongo console - and here I got an error (duplicate error in my case), so I removed the duplicates and I was able to create the index. I don't know why this was not popping up on my mongo logs.

Mongo v4

Upvotes: 0

anthonygore
anthonygore

Reputation: 4967

I had the exact same problem and this Github issue explained what was happening.

Firstly, compound indexes are only created after ensureIndex() is called. The problem for me is that I was using an import script that would drop my database and re-create it. ensureIndex() is not called until the server is restarted, so the compound index was not re-created after this.

The solution for me was to not drop my database in my import script, but instead iterate through my models and remove all the documents. That way the data was destroyed, but the indexes remained and hence the compound index would work.

Upvotes: 1

Neil Lunn
Neil Lunn

Reputation: 151112

Actually your index does not appear to have been created. You are showing just the default primary key. Your output from .getIndexes() should be more like:

> db.projects.getIndexes()
[
    {
            "v" : 1,
            "key" : {
                    "_id" : 1
            },
            "ns" : "project.projects",
            "name" : "_id_"
    },
    {
            "v" : 1,
            "key" : {
                    "user" : 1,
                    "name" : 1
            },
            "unique" : true,
            "ns" : "project.projects",
            "name" : "user_1_name_1",
            "background" : true,
            "safe" : null
    }
]

There might be something up in your code, but this works for me:

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/project');

var db = mongoose.connection;
var Schema = mongoose.Schema;

var UserSchema = new Schema({
  name: { type: String, required: true },
  info: String
});

var ProjectSchema = new Schema({
    name: { type: String, required: true},
    user: { type: Schema.ObjectId, ref: 'User', required: 'true'}
});

ProjectSchema.index({ user: 1, name: 1}, { unique: true });

var User = mongoose.model( "User", UserSchema );
var Project = mongoose.model( "Project", ProjectSchema );

var user = new User({ name: "me" });
user.save(function(){

  var project = new Project({ name: "Project1", user: user._id });
  project.save(function(err, project, numAffected){

    if (err) {            // Should be fine
      console.log(err);
    }

    console.log("First project created");

    User.findOne({}).exec(function(err, user) {

      console.log(user._id);

      var project = new Project({ name: "Project1", user: user._id });
      project.save(function(err, project, numAffected){

        if (err) {
          console.log(err); // Expect a problem here
        }

        console.log({ project: project, num: numAffected });

      });

    });

  });

});

Upvotes: 2

Hardik Barot
Hardik Barot

Reputation: 775

This is the pure mongo console function and it works, Click Here for more detail. This is not descibe in mongoose's API. I think it might be work.

db.collection.ensureIndex( { a: 1 }, { unique: true, dropDups: true } )

Upvotes: 2

Related Questions