这听起来很奇怪,我希望我做错了什么,但我的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倍的时间来完成。
答案 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()
的包装),它使用集合的元数据。
因此,这几乎是瞬时的,但在上述特定情况下可能会产生近似结果。