什么时候mongodb索引更新?

时间:2015-11-25 16:04:03

标签: mongodb mongoose database

问题

在将写操作成功报告给应用程序或在后台运行索引更新之前,是否更新了mongodb索引?如果它们在后台运行:是否有办法等待索引更新完成?

背景

我有一份文件

person1obj = {
  email: 'user@domain.tld',
  [...]
}

people集合中,唯一索引应用于email字段。现在我想插入另一个文件

person2obj = {
  email: 'user@domain.tld',
  [...]
}

显然,在插入email之前,我必须更改person1的{​​{1}}字段。使用mongoose,代码看起来像

person2

我看到我的单元测试随机失败并出现错误mongoose.model('Person').create(person1obj, function (err, person1) { // person1 has been saved to the db and 'user@domain.tld' is // added to the *unique* email field index // change email for person1 and save person1.email = 'otheruser@domain.tld'; person1.save(function(err, person1) { // person1 has been updated in the db // QUESTION: is it guaranteed that 'user@domain.tld' has been removed from // the index? // inserting person2 could fail if the index has not yet been updated mongoose.model('Person').create(person2obj, function (err, person2) { // ... }); }); }); ,这让我想知道索引更新是否在后台运行。

这个问题可能与mongodb的write concern有关,但我找不到有关索引更新实际过程的任何文档。

2 个答案:

答案 0 :(得分:3)

来自FAQ(强调我的):

  

写操作如何影响索引?

     

除了文档本身之外,任何改变索引字段的写入操作都需要更新索引。如果更新导致文档超出分配的记录大小的文档,则MongoDB必须更新包含此文档的所有索引作为更新操作的一部分

     

因此,如果您的应用程序写入量大,则创建过多索引可能会影响性能。

答案 1 :(得分:0)

至少在唯一索引的情况下,索引在后台运行而不是。这一事实很明显,当您尝试使用重复键编写一个新文档时,该文档被认为是唯一的,您会收到重复键错误。

如果索引是在后台异步发生的,那么Mongo将无法判断写入是否实际成功。因此索引必须在写序列期间发生。

虽然我没有证据证明这一点(虽然Mongo是开源的,如果你有足够的时间可以查找它),我相信所有索引都是在写序列期间完成的,即使它不是唯一索引。对影响唯一索引的写入使用特殊逻辑是没有意义的。