跳到主要内容
版本:5.1.1

文档计数

Doubao 中英对照 Counting Documents

模板 API 提供了多种方法来统计匹配给定条件的文档数量。其中一种如下所述。

template.query(Person.class)
.matching(query(where("firstname").is("luke")))
.count();

在 3.x 之前的 Spring Data MongoDB 版本中,计数操作使用 MongoDB 内部的集合统计信息。随着 MongoDB 事务 的引入,这不再可行,因为统计信息无法正确反映事务期间可能发生的变更,因此需要采用基于聚合的计数方式。所以在 2.x 版本中,MongoOperations.count() 在没有事务进行时使用集合统计信息,而在有事务时使用聚合变体。

自 Spring Data MongoDB 3.x 起,无论是否存在过滤条件,任何 count 操作都通过 MongoDB 的 countDocuments 使用基于聚合的计数方式。如果应用可以接受基于集合统计信息工作所带来的限制,MongoOperations.estimatedCount() 提供了另一种选择。

提示

通过将 MongoTemplate#useEstimatedCount(…​) 设置为 true,使用空过滤查询的 MongoTemplate#count(…​) 操作将被委托给 estimatedCount,前提是没有活动事务且模板未绑定到会话。仍然可以通过 MongoTemplate#exactCount 获取精确数字,但这样可能会加快速度。

备注

MongoDB 原生的 countDocuments 方法和 $match 聚合阶段不支持 $near 和 $nearSphere,而是需要 $geoWithin 配合 $center 或 $centerSphere,但后者不支持 $minDistance(请参阅 jira.mongodb.org/browse/SERVER-37043)。

因此,给定的 Query 在使用 Reactive-/MongoTemplate 进行 count 操作时会被重写,以绕过此问题,如下所示。

{ location : { $near : [-73.99171, 40.738868], $maxDistance : 1.1 } } 1
{ location : { $geoWithin : { $center: [ [-73.99171, 40.738868], 1.1] } } } 2

{ location : { $near : [-73.99171, 40.738868], $minDistance : 0.1, $maxDistance : 1.1 } } 3
{$and :[ { $nor :[ { location :{ $geoWithin :{ $center :[ [-73.99171, 40.738868 ], 0.01] } } } ]}, { location :{ $geoWithin :{ $center :[ [-73.99171, 40.738868 ], 1.1] } } } ] } 4
  • 使用 $near 的计数源查询。

  • 重写后的查询现在使用带 $center 的 $geoWithin。

  • 使用带 $minDistance 和 $maxDistance 的 $near 的计数源查询。

  • 重写后的查询现在组合了 $nor 与 $geowithin 条件,以绕过不支持的 $minDistance。