复合指数不起作用?

时间:2014-03-13 04:01:39

标签: javascript node.js mongodb mongoose

我正在尝试使用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});

之后我将旧数据库放在mongo

db.dropDatabase()

但我仍然可以插入多个具有相同名称和用户ID的文档。为什么呢?

它创建的索引在mongo中显示为

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

4 个答案:

答案 0 :(得分:2)

这是纯粹的mongo控制台功能,它有效, 点击Here 了解更多详情。这不是mongoose的API中的描述。 我认为这可能有用。

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

答案 1 :(得分:2)

实际上您的索引似乎没有创建。您只显示默认主键。您.getIndexes()的输出应该更像是:

> 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
    }
]

您的代码中可能存在某些内容,但这对我有用:

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 });

      });

    });

  });

});

答案 2 :(得分:0)

我遇到了完全相同的问题,this Github issue解释了发生了什么。

首先,复合索引仅在调用ensureIndex()后创建。对我来说问题是我使用的导入脚本会丢弃我的数据库并重新创建它。在重新启动服务器之前不会调用ensureIndex(),因此在此之后不会重新创建复合索引。

我的解决方案是不要将我的数据库放入导入脚本中,而是遍历我的模型并删除所有文档。这样一来,数据就被破坏了,但索引仍然存在,因此复合指数也会起作用。

答案 3 :(得分:0)

我只是遇到了这个问题,复合索引不是在启动时创建的,我正在检查mongo日志,我可以看到它正在启动索引的构建,但是什么也没有创建,没有错误等……

然后,我尝试在mongo控制台中手动创建索引,这时出现错误(我的情况下出现重复错误),因此我删除了重复项,便能够创建索引。我不知道为什么这在我的mongo日志中没有弹出。

Mongo v4