首页 文章

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

提问于
浏览
11

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

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

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

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

This is incorrect.

它没有找到我的收藏中的每一个文件 .

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

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

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

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

2 回答

  • 18

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

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

  • 1

    正如文档中所述,db.collection.count()不使用查询参数,根据集合的元数据返回结果:

    这可能导致近似计数 . 特别是:在分片群集中,生成的计数将无法正确筛选出孤立的文档 . 在不干净的关闭后,计数可能不正确 .

    使用查询参数时,就像在第二个查询( {_id: {$exists: true}} )中一样,它会强制 count 不使用集合的元数据,而是扫描集合 .


    Starting Mongo 4.0.3count() 被视为已弃用,建议使用以下替代方法:

    • Exact count of douments:
    db.collection.countDocuments({})
    

    在引擎盖下实际上执行以下“昂贵”,但准确的聚合(昂贵,因为整个集合被扫描计数记录):

    db.collection.aggregate([{ $group: { _id: null, n: { $sum: 1 } } }])
    
    • Approximate count of documents:
    db.collection.estimatedDocumentCount()
    

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

    因此,这几乎是瞬时的,但可能导致上述特定情况的近似结果 .

相关问题