因此,我们在工作场所使用 MongoDB 将有关客户的某些信息存储在名为 customers
的集合中。对于一项临时任务,我需要遍历整个集合并对每个文档进行一些处理,这意味着扫描集合中的每个文档而不遗漏任何文档至关重要。
这是我正在运行的查询 -
db.customers.find({}, {"cid":1, "name":1})
customers
集合在 cid
字段上有一个索引,这是查询中 execution-stats 的结果 -
"executionStages" : {
"stage" : "PROJECTION",
"nReturned" : 19841,
"executionTimeMillisEstimate" : 10,
"works" : 19843,
"advanced" : 19841,
"needTime" : 1,
"needYield" : 0,
"saveState" : 155,
"restoreState" : 155,
"isEOF" : 1,
"invalidates" : 0,
"transformBy" : {
"cid" : 1,
"name":1
},
"inputStage" : {
"stage" : "COLLSCAN",
"nReturned" : 19841,
"executionTimeMillisEstimate" : 0,
"works" : 19843,
"advanced" : 19841,
"needTime" : 1,
"needYield" : 0,
"saveState" : 155,
"restoreState" : 155,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 19841
}
}
我面临的问题是,当我运行此查询时,MongoDB 没有在游标中包含一些 cid
,理想情况下它们应该存在。那些 cid
在查询开始运行之前属于集合的一部分。当我稍后再次运行相同的查询时,碰巧返回了这些文档,但丢失了一些其他文档。
根据我在问这个问题之前阅读的内容,它看起来像 Reads may miss matching documents that are updated during the course of the read operation in MongoDB .然而,这篇文章似乎暗示这仅在查询使用索引时发生,而不是在整个集合扫描期间发生,而这正是我正在做的。我的查询似乎没有使用任何索引,所以我希望不会遇到这个问题。但是,这也确实发生在我的情况下。
那么,两个问题:
- 我对问题的理解是否正确?
- 如何解决这个问题并检索
customers
集合中的所有现有文档而不丢失任何文档?
谢谢
最佳答案
您引用的文章提到,如果扫描整个集合,写入可能会更改文档并在文档增长并需要移动时导致集合文档的重新排序。作者的解决方案是使用一个索引,以确保在游标迭代中不会遗漏任何文档。因此,"natural order"在迭代期间可以是易变的。
我建议使用稳定的索引进行扫描。在你的情况下,
db.customers.find({}, {"cid":1, "name":1}).hint({cid: 1})
将导致索引扫描成为查询规划器的获胜计划(确认db.customers.find({}, {"cid":1, "name":1}).hint({cid: 1}) .explain()
).
关于mongodb - 了解为什么 MongoDB 在对整个集合执行 find() 操作期间会跳过某些文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49571179/