了解MongoDB在对整个集合执行find()操作期间跳过某些文档的原因

了解MongoDB在对整个集合执行find()操作期间跳过某些文档的原因,mongodb,Mongodb,因此,我们在工作场所使用MongoDB将有关客户的特定信息存储在名为customers的集合中。对于临时任务,我需要遍历整个集合并对每个文档进行一些处理,这意味着扫描集合中的每个文档而不丢失任何文档是至关重要的 这是我正在运行的查询- db.customers.find({},{“cid”:1,“name”:1}) customers集合在cid字段上有一个索引,这是查询执行统计的结果- "executionStages" : { "stage" : "PROJECTIO

因此,我们在工作场所使用MongoDB将有关客户的特定信息存储在名为
customers
的集合中。对于临时任务,我需要遍历整个集合并对每个文档进行一些处理,这意味着扫描集合中的每个文档而不丢失任何文档是至关重要的

这是我正在运行的查询-

db.customers.find({},{“cid”:1,“name”:1})

customers
集合在
cid
字段上有一个索引,这是查询执行统计的结果-

"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
s,这在理想情况下应该是存在的。那些
cid
s,其中查询开始运行之前的部分集合。当我稍后再次运行相同的查询时,这些文档被返回,但其他一些文档丢失

从我在问这个问题之前阅读的内容来看,它看起来像。但是,本文似乎暗示,只有在查询使用索引时才会发生这种情况,而不是在整个集合扫描期间发生这种情况,这就是我正在做的。我的查询似乎没有使用任何索引,所以我希望不会遇到这个问题。然而,我的情况也是如此

因此,有两个问题:

  • 我对这个问题的理解正确吗
  • 如何解决此问题并检索
    客户
    集合中的所有现有文档而不丢失任何文档
  • 谢谢

  • 您引用的文章提到,如果扫描整个集合,writes可能会更改文档,并在文档增长并需要移动时导致集合中文档的重新排序。作者的解决方案是使用一个索引,以确保游标迭代中不会丢失任何文档。因此,在迭代过程中,数据可能是不稳定的

  • 我建议使用一个稳定的索引进行扫描。就你而言,
    
    find({},{“cid”:1,“name”:1}).hint({cid:1})
    
    将导致索引扫描成为查询计划员的获胜计划(用
    db.customers.find({},{“cid”:1,“name”:1})确认)。提示({cid:1})。解释()


  • 当您执行
    db.customers.find({})时得到了什么
    @MarcelDjaman我得到了预期的结果,只是很多结果都丢失了,我在下次运行查询时发现了。您的所有文档都有名称字段吗?您可以尝试
    db.customers.find({},{“cid”:1,“name”:1})。snapshot()
    ?@johnyhk我可以尝试,但因为它是我们的生产系统,我想从你那里了解为什么它可能解决这个问题。文档说明-
    $snapshot操作符防止光标多次返回文档,因为中间的写入操作会导致文档移动。
    ,这对我们来说不是问题。请评论一下为什么您认为它能解决我们面临的问题。