【问题标题】:Mongo java driver collection.count() returns one extra alwaysMongo java driver collection.count() 总是返回一个额外的
【发布时间】:2017-05-09 08:43:14
【问题描述】:

我有 2 个节点的 MongoDB 副本集。

集合中的典型文档如下所示:

{
    _id: 409,
    status: "active"
    address: [
        { id: 1000012, type: "primary", status: "active" },
        { id: 1000011, type: "primary", status: "inactive" },
        { id: 1000010, type: "primary", status: "inactive" }
    ],
}

当我使用 Java MongoDB Driver 来查找集合的计数时,基于一些简单的过滤器,我总是会得到 1 个额外的(例如,如果实际计数是 1299,则结果是 1300):

db.collection.count({
    "status": "active",
    "address.type": "primary",
    "address.status": "active"
});

我在官方文档中看到collection.count(...)can return incorrect results in case of sharded collections,但是我的没有分片,它只是一个副本集。

但是,当我aggregate 相同的查询并打印总和时,它总是正确的(1299):

db.collection.aggregate([
    { $unwind: "$address" },
    { $match: {
        "status": "active",
        "address.type": "primary",
        "address.status": "active",
    }},
    { $group: { _id: null, count: { $sum: 1 }}},
    { $project: { _id: 0, count: 1 }}
]);

这种行为的原因可能是什么?

这匹配聚合:

db.collection.count({"address": {$elemMatch:{"status": "active", "type": "primary"}}, status: "active"});

【问题讨论】:

    标签: java mongodb aggregation-framework


    【解决方案1】:

    第一个查询:

    db.collection.count({
        "status": "active",
        "address.type": "primary",
        "address.status": "active"
    });
    

    aggregation 的计算方式不同。这是选择所有带有status = "active" 的文档(不是子文档)和带有type = "primary" OR status = "active"ANY 地址。

    根据您的问题和 cmets,我假设您有 1300 个与之匹配的文档,但其中至少有一个与同一子文档中的 address.typeaddress.status 条件不匹配,因此在使用 @987654335 时返回不同的结果@ 与聚合框架,在这种情况下,这两个应该在同一个子文档中匹配。

    WiredTiger 硬崩溃后的问题:

    作为其他人的参考,另一个不常见的问题是使用WiredTiger时出现硬崩溃:

    如果您使用WiredTiger作为您的存储引擎,该问题可能是由于硬崩溃导致恢复时db.stats的状态不一致,启动后不会自动重新计算,即使数据是成功恢复。要重建它们,请运行 db.collection.validate(true)

    有关此问题的更多信息,请参阅:

    【讨论】:

    • 让我马上检查一下。感谢您的快速回复丹齐格
    • 这是一个有趣的观点。我已经检查过了,每个 id 只出现一次。
    • @TeenaGeorge 你在使用 WiredTiger 吗?如果是这样,您可能遇到了硬崩溃,这可能导致db.stats 的状态不一致,启动后不会自动重新计算。尝试运行db.collection.validate(true) 来重建它们。见jira.mongodb.org/browse/SERVER-19052jira.mongodb.org/browse/SERVER-19472
    • 您可以编辑您的问题并添加此查询和代码吗?
    • 很抱歉,java 代码没有文档级状态过滤器。如果有什么安慰的话,我最初并没有写这段代码:S。我接受你的回答,因为它回答了所提出的问题。再次感谢您,@Danziger。我还学到了更多关于聚合的知识,以及一点关于有线老虎的知识。
    猜你喜欢
    • 2015-05-29
    • 1970-01-01
    • 2012-08-17
    • 2017-02-07
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    相关资源
    最近更新 更多