我有一个这样的文章模型:
var ArticleSchema = new Schema({
type: String
,title: String
,content: String
,hashtags: [String]
,comments: [{
type: Schema.ObjectId
,ref: 'Comment'
}]
,replies: [{
type: Schema.ObjectId
,ref: 'Reply'
}]
, status: String
,statusMeta: {
createdBy: {
type: Schema.ObjectId
,ref: 'User'
}
,createdDate: Date
, updatedBy: {
type: Schema.ObjectId
,ref: 'User'
}
,updatedDate: Date
,deletedBy: {
type: Schema.ObjectId,
ref: 'User'
}
,deletedDate: Date
,undeletedBy: {
type: Schema.ObjectId,
ref: 'User'
}
,undeletedDate: Date
,bannedBy: {
type: Schema.ObjectId,
ref: 'User'
}
,bannedDate: Date
,unbannedBy: {
type: Schema.ObjectId,
ref: 'User'
}
,unbannedDate: Date
}
}, {minimize: false})
当用户创建或修改article
时,我将创建主题标签
ArticleSchema.pre('save', true, function(next, done) {
var self = this
if (self.isModified('content')) {
self.hashtags = helper.listHashtagsInText(self.content)
}
done()
return next()
})
例如,如果用户写"Hi, #greeting, i love #friday"
,我会将['greeting', 'friday']
存储在主题标签列表中。
我正在考虑为主题标签创建一个索引,以便更快地对主题标签进行查询。但是从猫鼬手册中,我发现了这个:
当您的应用程序启动时,Mongoose会自动调用 ensureIndex用于架构中的每个已定义索引。猫鼬会打电话 依次为每个索引的ensureIndex,并在其上发出'index'事件 所有ensureIndex调用成功或存在时的模型 一个错误。虽然很适合开发,但建议使用此行为 在生产中被禁用,因为索引创建可能会导致重大问题 绩效影响。通过设置autoIndex禁用该行为 您的架构选项为false。
http://mongoosejs.com/docs/guide.html
mongoDB / Mongoose的索引更快还是更慢?
此外,即使我创建像
这样的索引 hashtags: { type: [String], index: true }
如何在查询中使用索引?或者对于像以下的普通查询来说,它会变得更加神奇:
Article.find({hashtags: 'friday'})
答案 0 :(得分:5)
你错误地引用了那里引用的块的意图,.ensureIndex()
(现在已被弃用,但仍被mongoose代码调用)在上下文中实际执行此操作。
在mongoose中,您可以在架构或模型级别定义适合您的设计的索引。 mongoose“自动”为你做的是在每个注册的模型上连接它,然后为所提供的索引定义调用适当的.ensureIndex()
方法。
这实际上是做什么的?
好吧,在大多数情况下,在您之前已启动应用程序且运行.ensureIndexes()
方法之后绝对没有。这有点夸大其词,但它或多或少都是真的。
由于已在服务器集合上创建了索引定义,因此次要调用不会执行任何操作。即,它不会丢弃索引并“重新创建”。因此,一旦索引本身被创建,实际成本基本上就没有了。
因此,由于mongoose只是标准API之上的一个层,因此createIndex()
方法包含所发生情况的所有细节。
这里要考虑一些细节,例如索引构建可以在“后台”中进行,虽然这对您的应用程序的干扰较小,但它确实需要付出代价。值得注意的是,“background”生成的索引大小将大于在前台构建的索引大小,阻止其他操作。
此外,所有索引都需要付出代价,特别是在磁盘使用方面,以及在集合数据本身之外编写附加信息的额外成本。
索引的优点是“搜索”索引中包含的值比搜索整个集合并匹配可能的条件要快得多。
这些是与索引相关的基本“权衡”。
回到文档中的quoted block,这个建议背后有一个真正的意图。
在部署模式中尤其如此,特别是数据迁移按此顺序执行操作:
这是因为索引创建涉及成本,并且如前所述,希望从索引构建中获得最佳大小,并避免每个文档插入也具有编写索引条目的开销。当你正在批量做这个“负载”时。
这就是索引的用途,这些是成本和收益,并解释了mongoose文档中的信息。
总的来说,我建议在Database Indexes上阅读它们是什么以及它们的作用。想想走进图书馆找书。入口处有一张卡片索引。你走遍图书馆找到你想要的书吗?或者你在卡片索引中查找它以找到它的位置?该索引花了一些时间来创建并保持更新,但它节省了“你”在整个图书馆走动的时间,以便你可以找到你的书。
答案 1 :(得分:2)