为什么不推荐使用 mongodb 集合计数?

Why is mongodb collection count deprecated?

我正在使用 mongodb 并注意到我们应该通过收到此警告对过滤器查询使用 not count() 函数:

@deprecated Use countDocuments or estimatedDocumentCount

http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#count

建议的替代方案 countDocuments() 使用聚合,在某些情况下证明它对我们来说要慢 20 倍或更多倍(从 10k 过滤文档上的 0.5 秒到 20 秒,这使得响应时间难以忍受)。据称 count() 函数可能不准确,尽管我自己从未亲眼见过。在什么情况下它可能不准确?是否有一篇文章解释了为什么它首先被弃用? count 的幕后发生了什么值得反对使用聚合的替代方案 (countDocuments)?

作为参考,countDocuments 实现如下所示:

class CountDocumentsOperation extends AggregateOperation {
  constructor(collection, query, options) {
    const pipeline = [{ $match: query }];
    if (typeof options.skip === 'number') {
      pipeline.push({ $skip: options.skip });
    }
    if (typeof options.limit === 'number') {
      pipeline.push({ $limit: options.limit });
    }
    pipeline.push({ $group: { _id: 1, n: { $sum: 1 } } });
    super(collection, pipeline, options);
  }

如果你有一个分片集群,并且块正在从一个分片移动到另一个分片,它们可能会被计算两次(导致计数可能是实际值的 2 倍)。

弃用与 MongoDB 4.2 的分片事务工作一起发生,因为无法保证计数 return 事务中的正确结果。选项是使计数实际计数文档(这很慢)或在交易中禁止它。选择了后一个选项,导致 countDocuments 和 estimatedDocumentCount 对。

它已被弃用,因为许多人发现它的行为令人惊讶。

本质上,旧行为是如果将查询传递给计数,使用与 countDocuments 相同的行为,否则,使用与 estimatedDocumentCount 相同的行为。

如果那是您明确想要的行为,您可以使用这些新函数来实现它。