尝试创建 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);
});
Hook模型上的
'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
:
const User = new mongoose.Schema({
name: String,
email: String,
password: String
},
{autoIndex: true}
)
Mongoose 声明 “如果索引已存在于数据库中,则不会被替换”(credit)。
例如,如果您之前定义了索引
{unique: true}
但您想将其更改为 {unique: true, sparse: true}
,那么不幸的是 Mongoose 根本不会这样做,因为数据库中该字段已经存在索引。
在这种情况下,您可以删除现有索引,然后 mongoose 将从 fresh 创建一个新索引:
$ mongo
> use MyDB
> db.myCollection.dropIndexes();
> exit
$ restart node app
请注意,这是一个繁重的操作,因此在生产系统上要小心!
在另一种情况下,我的索引没有被创建,所以我使用了 JohnnyHK 推荐的错误报告技术。 当我这样做时,我得到了以下回应:
E11000 duplicate key error collection
这是因为我的新索引添加了约束
unique: true
,但是集合中存在不唯一的现有文档,因此 Mongo 无法创建索引。
在这种情况下,我需要修复或删除具有重复字段的文档,然后再次尝试创建索引。
当我在不起作用的模型上挂接索引事件时,我开始在控制台上收到错误,指示“字段‘retryWrites’对于索引规范无效”。我的应用程序中唯一引用“retryWrites”的位置是在连接字符串的末尾。我删除了它,重新启动应用程序,索引重建成功。我将 retryWrites 放回原位,重新启动应用程序,错误消失了。我的用户集合(一直给我带来问题)是空的,因此当我使用 Postman 创建新记录时,我看到(通过 Mongo Compass Community)创建了新记录,并且索引现在出现了。我不知道 retryWrites 是做什么的 - 今天是我使用它的第一天 - 但它似乎是我问题的根源。
哦,我为什么用它?它被附加到我从 Mongo 的 Atlas Cloud 站点拉出的连接字符串上。它看起来很重要。嗯。
也许可以解决你的问题
var schema = mongoose.Schema({
speed: Number,
watchDate: Number,
meterReading: Number,
status: Number,
openTrack: Boolean,
});
schema.index({ openTrack: 1 });
正如您在 mongoose 文档中看到的那样 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)
})
将“readPreference”设置为“ secondary”或“ secondaryPreferred”的连接可能无法选择以下连接选项:autoCreate、autoIndex。
检查 mongoose 连接中的 readPreference 选项
我在编写数据导入命令行实用程序时遇到了这个问题。执行结束后,有的索引创建了,有的没有创建。
解决方案是在终止脚本之前调用
await model.ensureIndexes()
。无论 autoIndex
选项值如何,它都有效。
С检查 mongoose 连接选项是否未指定:
autoIndex: false
就我而言,我有日志模型,旨在让 Winston 记录器使用它自动将日志存储在数据库中,并且我在应用程序中根本没有手动使用它。
无论我做什么,索引都永远不会被创建。
后来我发现,如果一个模型根本不被使用,它就不会被拾取,也不会建立它的索引。
所以我这样做是为了在服务器启动期间绕过它:
await LogModel.init();