ドキュメントの数を数える

テンプレート API は、指定された条件に一致するドキュメントの数をカウントするためのさまざまなメソッドを提供します。そのうちの 1 つを以下に概説します。

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 に委譲されます。MongoTemplate#exactCount 経由で正確な数値を取得することは引き続き可能ですが、処理速度が向上する可能性があります。

MongoDB のネイティブ countDocuments メソッドと $match 集約は、$near と $nearSphere をサポートしませんが、$minDistance をサポートしない $center または $centerSphere とともに $geoWithin を必要とします ( 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)
1$near を使用してソースクエリをカウントします。
2$geoWithin と $center を使用してクエリを書き換えました。
3$near と $minDistance および $maxDistance を使用したカウントソースクエリ。
4 サポートされていない $minDistance を回避するために、クエリが $nor$geowithin 基準の組み合わせに書き直されました。