【问题标题】:Mongoose Not Creating IndexesMongoose 不创建索引
【发布时间】:2012-09-09 07:00:19
【问题描述】:

尝试创建 MongoDB 索引。使用 Mongoose ODM 并在下面的模式定义中,我将用户名字段设置为唯一索引。集合和文档都已正确创建,只是索引不起作用。所有文档都说 ensureIndex 命令应该在启动时运行以创建任何索引,但没有创建任何索引。如果这很重要,我正在使用 MongoLab 进行托管。我也多次放弃收藏。怎么了。

var schemaUser = new mongoose.Schema({
    username: {type: String, index: { unique: true }, required: true},
    hash: String,
    created: {type: Date, default: Date.now}
}, { collection:'Users' });

var User = mongoose.model('Users', schemaUser);
var newUser = new Users({username:'wintzer'})
newUser.save(function(err) {
    if (err) console.log(err);
});

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    正如您在猫鼬文档https://mongoosejs.com/docs/guide.html#indexes 中看到的,我们需要定义 schema.index 来创建索引。看看下面的代码进行测试:

    • 注意,更新架构后重启服务器进行检查。
    const schemaUser = new mongoose.Schema(
      {
        username: {
          type: String,
          required: true,
          index: true,
          unique: true,
          dropDups: true,
        },
        hash: String,
        created: {
          type: Date,
          default: Date.now,
        },
      },
      {
        autoCreate: true, // auto create collection
        autoIndex: true, // auto create indexes
      }
    )
    // define indexes to be create
    schemaUser.index({ username: 1 })
    
    const User = mongoose.model('Users', schemaUser)
    const newUser = new Users({ username: 'wintzer' })
    newUser.save(function (err) {
      if (err) console.log(err)
    })
    

    【讨论】:

      【解决方案2】:

      我在编写数据导入命令行实用程序时遇到了这个问题。执行结束后,有的索引被创建,有的没有。

      解决方案是在终止脚本之前调用await model.ensureIndexes()。无论autoIndex 选项值如何,它都能正常工作。

      【讨论】:

        【解决方案3】:

        就我而言,我必须明确指定autoIndex: true

        const User = new mongoose.Schema({
            name: String,
            email: String,
            password: String
         },
         {autoIndex: true}
        )
        

        【讨论】:

          【解决方案4】:

          Сheck mongoose 连接选项没有指定:

          autoIndex: false
          

          【讨论】:

            【解决方案5】:

            Mongoose 声明 "if the index already exists on the db, it will not be replaced" (credit)。

            例如,如果您之前定义了索引{unique: true},但您想将其更改为{unique: true, sparse: true},那么不幸的是,Mongoose 根本不会这样做,因为数据库中已经存在该字段的索引。

            在这种情况下,您可以删除现有索引,然后 mongoose 会从新创建一个新索引:

            $ mongo
            > use MyDB
            > db.myCollection.dropIndexes();
            > exit
            $ restart node app
            

            注意这是heavy operation,所以在生产系统上要小心!


            在另一种情况下,我的索引没有被创建,所以我使用了 JohnnyHK 推荐的错误报告技术。当我这样做时,我得到了以下响应:

            E11000 duplicate key error collection
            

            这是因为我的新索引添加了约束unique: true,但集合中存在不唯一的现有文档,因此 Mongo 无法创建索引。

            在这种情况下,我需要修复或删除具有重复字段的文档,然后再尝试创建索引。

            【讨论】:

              【解决方案6】:

              或许能解决你的问题

              var schema = mongoose.Schema({
              speed: Number,
              watchDate: Number,
              meterReading: Number,
              status: Number,
              openTrack: Boolean,
               });
              schema.index({ openTrack: 1 });
              

              【讨论】:

              • 这会在 mongodb 上自动创建索引吗?我已经像上面那样定义了模型架构和索引,但是在mongodb中,它不创建索引,只有_id索引在那里,我需要执行一些其他步骤才能创建吗?
              • 是的,如果你使用猫鼬,它会自动创建
              【解决方案7】:

              当我在不起作用的模型上挂钩索引事件时,我开始在控制台上收到错误消息,指出“字段 'retryWrites' 对索引规范无效。”我的应用程序中唯一引用“retryWrites”的地方是我的连接字符串的末尾。我删除了这个,重新启动了应用程序,索引重建成功。我把 retryWrites 放回原处,重新启动应用程序,错误就消失了。我的用户集合(一直给我带来问题)是空的,所以当我使用 Postman 创建新记录时,我看到(通过 Mongo Compass 社区)创建了新记录并且现在出现了索引。我不知道 retryWrites 做了什么——今天是我使用它的第一天——但它似乎是我问题的根源。

              哦,我为什么要使用它?它被添加到我从 Mongo 的 Atlas Cloud 站点中提取的连接字符串上。看起来很重要。嗯。

              【讨论】:

                【解决方案8】:

                在模型上钩住'index'事件,看看异步创建索引时是否出现错误:

                User.on('index', function(err) {
                    if (err) {
                        console.error('User index error: %s', err);
                    } else {
                        console.info('User indexing complete');
                    }
                });
                

                另外,通过调用启用 Mongoose 的调试日志记录:

                mongoose.set('debug', true);
                

                调试日志将显示ensureIndex 调用它为您创建索引。

                【讨论】:

                • 谢谢约翰尼,我尝试了你的建议,虽然它没有显示错误,但我看到的只是插入函数,没有确保索引。这使我认为,尽管文档说明 autoIndex 默认设置为 true,但 autoIndex 并未打开。我在我的收藏设置中添加了autoIndex:true,它起作用了。现在我已经手动设置了autoIndex:true 并在调试时显示了 ensureIndex 操作。
                • 感谢 wintzer,这对我有帮助。我也在 MongoHQ。
                • 很有用但无法解决问题,即使在不调用确保索引的字段上设置索引和唯一性也是如此
                猜你喜欢
                • 2015-01-09
                • 2023-03-26
                • 2015-03-17
                • 2021-10-25
                • 2019-12-18
                • 1970-01-01
                • 2020-05-12
                • 2019-03-10
                • 2014-08-08
                相关资源
                最近更新 更多