MongoDB返回的计数不正确(WiredTiger)

时间:2015-06-08 17:26:49

标签: mongodb wiredtiger

这听起来很奇怪,我希望我做错了什么,但我的MongoDB集合正在我的收藏中将Count关闭一个。

我有一个(我相信)359671文件的集合。但是count()命令返回359670个文档。

我正在使用mongo shell执行count()命令:

rs0:PRIMARY> db.COLLECTION.count()
359670

这是不正确的。

我找不到我的收藏中的每一个文件。

如果我提供以下查询来计算,我会得到正确的结果:

rs0:PRIMARY> db.COLLECTION.count({_id: {$exists: true}})
359671

我相信这是WiredTiger中的一个错误。据我所知,每个文档都有相同的定义,一个整数的_id字段,范围从0到359670,以及一个BinData字段。我没有旧版存储引擎(或Mongo 2,这可能导致问题)的问题。

这是我做错了吗?我不想使用{_id: {$exists: true}}查询,因为这需要花费100倍的时间来完成。

2 个答案:

答案 0 :(得分:18)

根据此issue,如果mongodb遇到硬崩溃并且未正常关闭,则会发生此行为。如果不发出任何查询,mongodb可能会回退到收集的统计信息。

根据该文章,调用db.COLLECTION.validate(true)应重置计数器。

答案 1 :(得分:1)

如文档db.collection.count()中所述,在不使用查询参数的情况下,将基于集合的元数据返回结果:

  

这可能会导致近似计数。特别是:

     
      
  • 在分片群集上,结果计数将无法正确过滤出孤立的文档。

  •   
  • 不正常关机后,计数可能不正确。

  •   

使用查询参数时,就像在第二个查询(echo substr($key, 0, -1);中所做的那样),然后它强制{_id: {$exists: true}}不使用集合的元数据,而是扫描集合。


count 开始,Mongo 4.0.3被认为已过时,建议使用以下替代方法:

count()

实际上是执行以下“昂贵”的操作,但准确的汇总(由于扫描整个集合以对记录进行计数,因此比较昂贵):

db.collection.countDocuments({})
db.collection.aggregate([{ $group: { _id: null, n: { $sum: 1 } } }])

完全执行db.collection.estimatedDocumentCount() 做/做的事情(实际上是db.collection.count()的包装),它使用集合的元数据。

因此,这几乎是瞬时的,但在上述特定情况下可能会产生近似结果。