Mongodb通过计数函数和聚合管道给出不同的计数结果

Mongodb通过计数函数和聚合管道给出不同的计数结果,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我在mongodb中有一个名为users的集合。我正在努力查找集合中所有文档的计数 令人惊讶的是,下面的查询给出了不同的结果。 为了 及 输出为533911,对于 db.users.aggregate( [ { $group: { _id: "$_id" } }, { $group: { _id : null, count : { $sum : 1 } } } ] ) 及 输出为533950 有人能告诉我为什么聚合查询和普通查询返回不同的结果吗?

我在mongodb中有一个名为users的集合。我正在努力查找集合中所有文档的计数

令人惊讶的是,下面的查询给出了不同的结果。 为了

输出为533911,对于

db.users.aggregate(
    [
        { $group: { _id: "$_id" } },
        { $group: { _id : null, count : { $sum : 1 } } }
    ]
)

输出为533950

有人能告诉我为什么聚合查询和普通查询返回不同的结果吗?提前感谢您的帮助

db.users.aggregate(
    [
        { $group: { _id: "$_id" } },
        { $group: { _id : null, count : { $sum : 1 } } }
    ]
) 
也在计算空值

db.users.count()

不计算空值。

我看到两个可能的原因:

  • 如果集合是分片的,则应使用聚合框架对文档进行计数,因为由于区块移动或孤立文档,计数操作可能不准确

  • 如果您使用的是WiredTiger存储引擎(这很可能是自V3.2以来的默认设置),WiredTiger存储的统计数据在未经清理的关机后可能会不准确。您应该对每个集合运行
    db.collection.validate()


  • 注意:您可以通过使用命令删除孤立文档来减少“混乱”,但在分片环境中,您应该始终使用聚合框架。

    聚合查询是对id字段的计数,不能为空。此外,后面的一个步骤是计算文档的数量。在本例中,当谈到不计算空值时,您指的是什么。{$group:{{U id:null,count:{$sum:1}}正在计算所有发生次数问题中的两个聚合示例彼此等效,初始的
    $group
    没有做任何有用的事情:
    \u id
    值已经是唯一的,
    $group
    by
    \u id:null
    将在此基础上累积。真正的区别是快速/估计的
    count()
    与通过聚合计算的结果。是的,它起作用了。我们不使用碎片收集。这是第二个WiredTiger统计数据不准确的案例。对集合运行validate()有效。感谢:-)关于
    count()
    与聚合查询结果的更具体的上下文:在MongoDB 3.6中,没有查询过滤器的
    count()
    是基于收集统计的“快速计数”(或估计计数),由WiredTiger定期保存。等效的聚合查询(按
    \u id
    分组)更准确,但可能需要更长的时间,因为它实际计算匹配值。
    db.users.aggregate(
            [
                { $group: { _id : null, count : { $sum : 1 } } }
            ]
        )
    
    db.users.aggregate(
        [
            { $group: { _id: "$_id" } },
            { $group: { _id : null, count : { $sum : 1 } } }
        ]
    ) 
    
    db.users.count()