文档计数
模板 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。