Node.js MongoDB/Mongoose索引使查询更快还是更慢?

Node.js MongoDB/Mongoose索引使查询更快还是更慢?,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有一个这样的文章模型: var ArticleSchema = new Schema({ type: String ,title: String ,content: String ,hashtags: [String] ,comments: [{ type: Schema.ObjectId ,ref: 'Comment' }] ,replies: [{ type: Schema.Obj

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

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})
当用户创建或修改
文章时,我将创建hashtags

ArticleSchema.pre('save', true, function(next, done) {
    var self = this
    if (self.isModified('content')) {
        self.hashtags = helper.listHashtagsInText(self.content)
    }
    done()
    return next()
})
例如,如果用户编写“嗨,问候,我爱星期五”
,我将在hashtags列表中存储
[“问候”,“星期五”]

我正在考虑为hashtags创建一个索引,以便更快地查询hashtags。但在猫鼬手册中,我发现:

当应用程序启动时,Mongoose会自动调用 确保模式中每个已定义索引的索引。猫鼬会打电话来 确保按顺序为每个索引创建索引,并在 当所有ensureIndex调用成功或 一个错误。虽然对于开发来说很好,但建议使用这种行为 在生产中被禁用,因为索引创建可能会导致 性能影响。通过设置自动索引禁用该行为 将模式的选项设置为false

那么mongoDB/Mongoose的索引速度是更快还是更慢呢

而且,即使我创建索引

  hashtags: { type: [String], index: true }
如何在查询中使用索引?或者对于正常的查询,它会神奇地变得更快,比如:

   Article.find({hashtags: 'friday'})
你看错了 您误解了引用的块的意图(现在已弃用,但仍被mongoose代码调用)在上下文中实际做了什么

在mongoose中,您可以根据自己的设计在模式或模型级别定义索引。mongoose“自动”为您做的是在连接时输入每个注册的模型,然后为提供的索引定义调用相应的
.ensureIndex()
方法

这实际上是做什么的

嗯,在大多数情况下,在您之前已经启动了应用程序,并且该方法已经运行之后,这一点都不重要。这有点夸大其词,但多少听起来是对的

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

创建索引 因此,由于mongoose只是标准API之上的一层,因此该方法包含了正在发生的事情的所有细节

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

此外,所有索引都有成本,特别是在磁盘使用方面,以及在收集数据本身之外写入附加信息的额外成本

索引的优点是“搜索”索引中包含的值比搜索整个集合并匹配可能的条件要快得多

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

部署模式 回到文档中,这个建议背后有一个真正的意图

在部署模式中,尤其是在数据迁移中,按以下顺序进行操作是很典型的:

  • 将数据填充到相关集合/表中
  • 对与您的需要相关的集合/表格数据启用索引
  • 这是因为创建索引会带来成本,正如前面提到的,最好从索引构建中获得最佳大小,同时避免在批量执行此“加载”操作时,每次文档插入都会产生编写索引项的开销

    这就是索引的目的,这些是成本和收益,mongoose文档中的信息也得到了解释


    但总的来说,我建议你仔细阅读他们是什么,他们做了什么。想象一下走进图书馆找一本书。入口处有一张卡片索引。你会在图书馆里四处走走寻找你想要的书吗?或者你会在卡片索引中查找它的位置吗?这个索引花了一些时间来创建和更新,但它节省了“你”在整个图书馆里走来走去的时间,这样你就可以找到你的书。

    这可能就是你要找的


    您是否阅读了核心文档?具体地说:“如果您同时使用相同的索引规范调用多个createIndex()方法,则只有第一个操作会成功,所有其他操作都将无效。”。此外,索引的写入成本也很高,但它们加快了读取速度。这是索引的基本概念。有很多文档可以解释索引的作用。也许可以读点书。@BlakesSeven我用的是Mongoose,我想这是mongoDB的包装。官方文档建议在生产中关闭它,这让我感到困惑所谓的性能影响只有在我将现有数据迁移到它时才适用?@OMGPOP正如前面所解释的,“块”的意思是在“生产”中您通常希望在创建或修改索引时能够更好地控制环境,而不仅仅是让应用程序自己启动创建。然而,当索引已经存在时,实际的影响可能什么都没有。这就是上面所解释的,就像索引每次插入/修改都需要花费时间来写入一样,但它加快了读取过程,避免了扫描集合中的匹配项“您通常希望在创建或修改索引时对环境进行更大的控制,而不仅仅是让应用程序自己启动创建。“什么意思?我们保存数据时不总是创建索引吗?另外,我编辑了我的帖子,并在最后添加了一个小问题。为了使用索引,我们需要为查询做额外的工作吗?@OMGPOP No.创建索引和“更新”写入时的索引是不需要的