在将写操作成功报告给应用程序或在后台运行索引更新之前,是否更新了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有关,但我找不到有关索引更新实际过程的任何文档。
答案 0 :(得分:3)
来自FAQ(强调我的):
写操作如何影响索引?
除了文档本身之外,任何改变索引字段的写入操作都需要更新索引。如果更新导致文档超出分配的记录大小的文档,则MongoDB必须更新包含此文档的所有索引作为更新操作的一部分。
因此,如果您的应用程序写入量大,则创建过多索引可能会影响性能。
答案 1 :(得分:0)
至少在唯一索引的情况下,索引在后台运行而不是。这一事实很明显,当您尝试使用重复键编写一个新文档时,该文档被认为是唯一的,您会收到重复键错误。
如果索引是在后台异步发生的,那么Mongo将无法判断写入是否实际成功。因此索引必须在写序列期间发生。
虽然我没有证据证明这一点(虽然Mongo是开源的,如果你有足够的时间可以查找它),我相信所有索引都是在写序列期间完成的,即使它不是唯一索引。对影响唯一索引的写入使用特殊逻辑是没有意义的。