文档计数
模板 API 提供了多种方法来计算符合给定条件的文档数量。下面将介绍其中一种方法。
template.query(Person.class)
    .matching(query(where("firstname").is("luke")))
    .count();
在 SpringData MongoDB 3.x 之前的版本中,计数操作使用了 MongoDB 的内部集合统计信息。随着 MongoDB 事务 的引入,这不再可能,因为统计信息无法正确反映事务期间可能发生的变化,因此需要基于聚合的计数方法。所以在 2.x 版本中,如果没有事务在进行,MongoOperations.count() 会使用集合统计信息,否则会使用聚合变体。
自 Spring Data MongoDB 3.x 起,任何 count 操作无论是否存在过滤条件,都会通过 MongoDB 的 countDocuments 使用基于聚合的计数方法。如果应用程序能够接受基于集合统计的限制,MongoOperations.estimatedCount() 提供了一个替代方案。
通过将 MongoTemplate#useEstimatedCount(…) 设置为 true,MongoTemplate#count(…) 操作(使用空过滤查询时)将被委托给 estimatedCount,前提是没有活跃的事务且模板未绑定到 session。仍然可以通过 MongoTemplate#exactCount 获取精确的数字,但使用 estimatedCount 可以加快操作速度。
MongoDB 原生的 countDocuments 方法和 $match 聚合操作不支持 $near 和 $nearSphere,而是需要 $geoWithin 与 $center 或 $centerSphere 配合使用,而后者不支持 $minDistance(参见 jira.mongodb.org/browse/SERVER-37043)。
因此,在使用 Reactive-/MongoTemplate 进行 count 操作时,给定的 Query 将被重写以绕过该问题,如下所示。
{ 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的计数源查询。
- 重写后的查询,现在使用 - $geoWithin与- $center。
- 使用 - $near并带有- $minDistance和- $maxDistance的计数源查询。
- 重写后的查询,现在结合了 - $nor和- $geowithin条件,以绕过不支持的- $minDistance。