Counting Documents

模板 API 提供多种方法来计算匹配给定条件的文档数目。其中一个概述如下。

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

在 SpringData MongoDB 的 3.x 之前的版本中,计数操作使用 MongoDB 的内部集合统计数据。随着 MongoDB Transactions 的引入,这不再可行,因为统计数据不能正确反映在事务期间的潜在更改,因此需要基于聚合的计数方法。因此在 2.x 版本中,MongoOperations.count() 在没有进行事务时将使用集合统计数据,如果有事务则使用聚合变量。

从 Spring Data MongoDB 3.x 开始,任何 count 操作都会使用基于聚合的计数方法通过 MongoDB 的 countDocuments,而不管是否存在筛选条件。如果应用程序对使用集合统计信息有局限性,MongoOperations.estimatedCount() 提供了一个备选方案。

通过将 MongoTemplate#useEstimatedCount(…​) 设置为 trueMongoTemplate#count(…​) 操作(使用空过滤器查询)将委托给 estimatedCount,只要没有活动事务且模板未绑定到 session 即可。通过 MongoTemplate#exactCount 仍然可以获取确切数字,但可以加快速度。

MongoDB 的本机 countDocuments 方法和 $match 聚合不支持 $near$nearSphere,但需要 $geoWithin 以及 $center$centerSphere,它们都不支持 $minDistance(参见 [role="bare"][role="bare"]https://jira.mongodb.org/browse/SERVER-37043)。 因此,给定的 Query 将针对 count 操作使用 Reactive-/MongoTemplate 重新编写,以绕过以下所示问题。

{ 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
1 使用 $near 对源查询进行计数。
2 现在使用 $center 重写查询,其中 $geoWithin$center 代替。
3 使用 $minDistance$maxDistance 对源查询进行计数,其中 $near$minDistance 代替。
4 重写的查询现在将 $nor $geowithin 条件相结合,以解决不支持 $minDistance 的问题。