MongoDB/Mongoose索引使查询更快或更慢?

OMG*_*POP 6 mongoose mongodb node.js

我有一个这样的文章模型:

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})
Run Code Online (Sandbox Code Playgroud)

当用户创建或修改时article,我将创建主题标签

ArticleSchema.pre('save', true, function(next, done) {
    var self = this
    if (self.isModified('content')) {
        self.hashtags = helper.listHashtagsInText(self.content)
    }
    done()
    return next()
})
Run Code Online (Sandbox Code Playgroud)

例如,如果用户写"Hi, #greeting, i love #friday",我将存储['greeting', 'friday']在hashtags列表中.

我正在考虑为hashtags创建一个索引,以便更快地对hashtags进行查询.但是从猫鼬手册中,我发现了这个:

当您的应用程序启动时,Mongoose会自动为架构中的每个已定义索引调用ensureIndex.Mongoose将按顺序为每个索引调用ensureIndex,并在所有ensureIndex调用成功或出现错误时在模型上发出'index'事件.虽然很适合开发,但建议在生产中禁用此行为,因为创建索引会对性能产生重大影响.通过将架构的autoIndex选项设置为false来禁用该行为.

http://mongoosejs.com/docs/guide.html

那么mongoDB/Mongoose的索引更快还是更慢?

此外,即使我创建索引像

  hashtags: { type: [String], index: true }
Run Code Online (Sandbox Code Playgroud)

如何在查询中使用索引?或者对于普通查询来说它会变得更加神奇:

   Article.find({hashtags: 'friday'})
Run Code Online (Sandbox Code Playgroud)

Bla*_*ven 5

您读错了

您会误解那里引用的块的意图.ensureIndex()(现在已弃用,但仍由猫鼬代码调用)在上下文中实际执行的操作。

在猫鼬中,您可以在架构或模型级别定义适合您的设计的索引。猫鼬“自动”为您执行的操作是在连接时检查每个注册的模型,然后.ensureIndex()为提供的索引定义调用适当的方法。

这实际上是做什么的?

好吧,在大多数情况下,在您已经启动应用程序且.ensureIndexes()方法运行之前,绝对没有。这有点夸大其词,但这或多或少是正确的。

因为已经在服务器集合上创建了索引定义,所以后续调用不会执行任何操作。即,它不会删除索引并“重新创建”。因此,一旦创建了索引本身,实际成本就基本为零。

创建索引

因此,由于猫鼬只是标准API之上的一层,因此该createIndex()方法包含正在发生的所有详细信息。

这里有一些细节需要考虑,例如索引构建可以在“后台”发生,尽管这对您的应用程序的干扰较小,但它的确是自费的。值得注意的是,“后台”生成的索引大小将大于在前台生成索引的大小,从而阻止了其他操作。

同样,所有索引都是有代价的,特别是在磁盘使用方面,以及在收集数据本身之外写入其他信息的额外费用。

索引的优势在于,“搜索”索引中包含的值要比遍历整个集合并匹配可能的条件快得多。

这些是与索引关联的基本“权衡”。

部署模式

回到文档中引用的方框,此建议背后有一个真正的意图。

在部署模式中,尤其是在数据迁移中,通常按以下顺序执行操作:

  1. 将数据填充到相关的集合/表中
  2. 在与您的需求相关的集合/表数据上启用索引

这是因为创建索引会涉及成本,并且如前所述,希望从索引构建中获得最佳大小,同时还要避免在插入每个文档时也需要编写索引条目的开销批量执行此“加载”。

这就是索引的目的,即成本和收益,并解释了猫鼬文档中的消息。

但总的来说,我建议阅读数据库索引,以了解它们的用途。想像一下走进图书馆找书。入口处有卡索引。您在图书馆走来走去找到想要的书吗?还是您在卡索引中查找它的位置?该索引花费了一些时间来创建并保持更新,但是它为“您”节省了遍历整个图书馆的时间,因此您可以找到自己的书。