C# MongoDB 驱动程序 [2.7.0] CountDocumentAsync 意外的本机查询

dja*_*ski 5 .net c# mongodb

我在使用 C# MongoDBCountDocumentAsync函数时遇到了奇怪的事情。我在 MongoDB 上启用了查询日志记录,这就是我得到的:

{
    "op" : "command",
    "ns" : "somenamespace",
    "command" : {
        "aggregate" : "reservations",
        "pipeline" : [
            {
                "some_query_key": "query_value"
            },
            {
                "$group" : {
                    "_id" : null,
                    "n" : {
                        "$sum" : 1
                    }
                }
            }
        ],
        "cursor" : {}
    },
    "keyUpdates" : 0,
    "writeConflicts" : 0,
    "numYield" : 9,
    "locks" : {
        "Global" : {
            "acquireCount" : {
                "r" : NumberLong(24)
            }
        },
        "Database" : {
            "acquireCount" : {
                "r" : NumberLong(12)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "r" : NumberLong(12)
            }
        }
    },
    "responseLength" : 138,
    "protocol" : "op_query",
    "millis" : 2,
    "execStats" : {},
    "ts" : ISODate("2018-09-27T14:08:48.099Z"),
    "client" : "172.17.0.1",
    "allUsers" : [ ],
    "user" : ""
}
Run Code Online (Sandbox Code Playgroud)

简单的计数被转换为聚合

更有趣的是,当我使用CountAsync函数(顺便说一句,我应该使用CountDocumentsAsync它被标记为过时)它会产生:

{
    "op" : "command",
    "ns" : "somenamespace",
    "command" : {
        "count" : "reservations",
        "query" : {
            "query_key": "query_value"
        }
    },
    "keyUpdates" : 0,
    "writeConflicts" : 0,
    "numYield" : 9,
    "locks" : {
        "Global" : {
            "acquireCount" : {
                "r" : NumberLong(20)
            }
        },
        "Database" : {
            "acquireCount" : {
                "r" : NumberLong(10)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "r" : NumberLong(10)
            }
        }
    },
    "responseLength" : 62,
    "protocol" : "op_query",
    "millis" : 2,
    "execStats" : {

    },
    "ts" : ISODate("2018-09-27T13:58:27.758Z"),
    "client" : "172.17.0.1",
    "allUsers" : [ ],
    "user" : ""
}
Run Code Online (Sandbox Code Playgroud)

这是我所期望的。有谁知道这种行为的原因可能是什么?我浏览了文档,但没有发现任何有趣的内容。

Chr*_*ris 5

这是支持 4.0 功能的驱动程序的记录行为。进行更改的原因是为了消除混乱并明确何时使用估计值以及何时不使用估计值。

当基于查询过滤器进行计数时(而不是仅仅对整个集合进行计数),这两种方法都会导致服务器迭代匹配文档以对它们进行计数,因此具有相似的性能。

来自MongoDb 文档:db.collection.count()

笔记:

与 4.0 功能兼容的 MongoDB 驱动程序弃用了各自的游标和集合 count() API,转而使用 countDocuments() 和estimatedDocumentCount() 的新 API。有关给定驱动程序的特定 API 名称,请参阅驱动程序文档。

来自MongoDb 文档:db.collection.countDocuments()

db.collection.countDocuments(查询,选项)

4.0.3 版本中的新增功能。

返回与集合或视图的查询匹配的文档计数。该方法使用 $sum 表达式包装 $group 聚合阶段来执行计数,并且可在 Transactions 中使用。

有关 API 更改的更详细说明可以在MongoDb JIRA 网站上找到:

支持 MongoDB 4.0 的驱动程序必须弃用 count() 帮助程序并添加两个新的帮助程序 -estimatedDocumentCount() 和 countDocuments()。MongoDB 2.6+ 支持这两个助手。

选择新助手的名字是为了清楚地表明他们的行为方式以及他们的具体工作。estimatedDocumentCount 帮助器使用集合元数据返回集合中文档计数的估计值,而不是对文档进行计数或查阅索引。countDocuments 帮助器使用聚合管道对与提供的查询过滤器匹配的文档进行计数。

count() 帮助器已弃用。它始终是使用 count 命令来实现的。count 命令的行为根据传递给它的选项和使用的拓扑而有所不同,并且可能会也可能不会提供准确的计数。当未提供查询过滤器时,count 命令使用集合元数据提供估计。即使提供了查询过滤器,如果存在孤立文档或者正在进行块迁移,count 命令也可能会返回分片集群的不准确结果。当与 MongoDB 3.6+ 一起使用时,以及在较旧的分片集群中使用读取首选项时,countDocuments 帮助程序完全避免了这些分片集群问题Primary