MongoDb背景索引和唯一索引

时间:2017-05-24 01:58:59

标签: mongodb indexing

在MongoDb中创建索引时。有两个选项:

  • 执行前台索引并锁定所有写入操作
  • 进行背景索引,但仍然允许同时写入记录

我的问题是:

如何在后台构建类似唯一索引的内容?如果在进行索引构建时插入重复文档会怎样?

3 个答案:

答案 0 :(得分:2)

参考MongoDB docs -

  

如果在mongod进程终止时正在进行后台索引构建,则当实例重新启动时,索引构建将作为前台索引构建重新启动。如果索引构建遇到任何错误,例如重复键错误,则mongod将退出并显示错误。

所以有两种可能性 -

  1. 如果索引创建已完成,那么您尝试插入的文档将立即显示错误。
  2. 或者如果索引创建正在后台进行,那么您将能够插入文档(因为在插入时索引不是100%)。但是后来当索引创建过程试图将索引放在您的重复文档上时,它将退出并显示错误。这与您有重复文档并尝试创建前景索引的行为相同。

答案 1 :(得分:1)

我相信这是the MongoDB docs中最相关的摘录:

  

背景索引操作在后台运行,以便在创建索引时可以运行其他数据库操作。但是,创建索引的mongo shell会话或连接将阻塞,直到索引构建完成。要继续向数据库发出命令,请打开另一个连接或mongo实例。

     

查询不会使用部分构建的索引:只有在索引构建完成后,索引才可用。

因此,这意味着您在其中发出创建索引的命令的客户端将一直处于阻塞状态,直到完全创建索引为止。如果在构建索引时从另一个客户端执行类似添加重复文档的操作,它将插入文档而不会出现错误,但是最终您的初始客户端将遇到一个错误,因为它无法完成索引,因为唯一索引有一个重复的键。

现在,我实际上在尝试理解MongoID的index(..., {background: true})选项的作用时在这里结束了,因为这似乎暗示每个写入都可能在后台执行该写入的索引部分,但是我现在的理解是此选项仅适用于索引的初始创建。 introduction to the docs for the background option for MongoDB's createIndex method中对此进行了解释(从技术上讲,它与MongoID的background选项并不相同,但它阐明了与该选项相关的功能的概念):

  

MongoDB提供了仅会影响索引创建的几个选项。[...]本节介绍了这些创建选项的用法及其行为。

     

相关:您可以为createIndex()选项指定的某些选项控制索引的属性,这是 not 索引创建选项。例如,唯一选项会影响创建后索引的行为。

答案 2 :(得分:0)

@mltsy

如果从另一个客户端进行的操作(例如在建立索引时添加重复的文档),它将无误地插入文档。

我不确定这是否正确,如Mongodb Doc所述,如下:

在集合上建立索引时,保存该集合的数据库在索引建立完成之前无法进行读取或写入操作。

我用猫鼬来测试:

var uniqueUsernameSchema = new Schema({
    username: {
        index: { unique: true, background: false },
        type: String,
        required: true
    }
})
var U = mongoose.model('U1', uniqueUsernameSchema)
var dup = [{ username: 'Val' }, { username: 'Val' }]
U.create(dup, function (e, d) {
    console.log(e, d)
})

enter image description here

唯一索引建立失败。结果表明,前台选项没有阻止MongoDB中的写操作。