From 076d334b3c20eaeaa1bb1c209b284786373505bd Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 21 Jan 2021 11:11:02 +0100 Subject: [PATCH] Update count vs. estimatedCount documentation. Closes #3055 Original pull request: #3541. --- .../mongodb/core/ExecutableFindOperation.java | 5 ++++ .../data/mongodb/core/MongoOperations.java | 24 +++++++++++++++++++ .../mongodb/core/ReactiveFindOperation.java | 6 +++++ .../mongodb/core/ReactiveMongoOperations.java | 24 +++++++++++++++++++ src/main/asciidoc/reference/mongodb.adoc | 1 + 5 files changed, 60 insertions(+) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java index 28dd7dddc..d67212bdc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java @@ -125,6 +125,11 @@ public interface ExecutableFindOperation { /** * Get the number of matching elements. + *

+ * This method uses an {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) aggregation + * execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees shard, + * session and transaction compliance. In case an inaccurate count satisfies the applications needs use + * {@link MongoOperations#estimatedCount(String)} for empty queries instead. * * @return total number of matching elements. */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index 5a5a3b7fc..ffa301a28 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -1160,6 +1160,12 @@ public interface MongoOperations extends FluentMongoOperations { * influence on the resulting number of documents found as those values are passed on to the server and potentially * limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to * count all matches. + *

+ * This method uses an + * {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) + * aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees + * shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use + * {@link #estimatedCount(Class)} for empty queries instead. * * @param query the {@link Query} class that specifies the criteria used to find documents. Must not be * {@literal null}. @@ -1176,6 +1182,12 @@ public interface MongoOperations extends FluentMongoOperations { * influence on the resulting number of documents found as those values are passed on to the server and potentially * limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to * count all matches. + *

+ * This method uses an + * {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) + * aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees + * shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use + * {@link #estimatedCount(String)} for empty queries instead. * * @param query the {@link Query} class that specifies the criteria used to find documents. * @param collectionName must not be {@literal null} or empty. @@ -1187,6 +1199,9 @@ public interface MongoOperations extends FluentMongoOperations { /** * Estimate the number of documents, in the collection {@link #getCollectionName(Class) identified by the given type}, * based on collection statistics. + *

+ * Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside + * transactions. * * @param entityClass must not be {@literal null}. * @return the estimated number of documents. @@ -1200,6 +1215,9 @@ public interface MongoOperations extends FluentMongoOperations { /** * Estimate the number of documents in the given collection based on collection statistics. + *

+ * Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside + * transactions. * * @param collectionName must not be {@literal null}. * @return the estimated number of documents. @@ -1214,6 +1232,12 @@ public interface MongoOperations extends FluentMongoOperations { * influence on the resulting number of documents found as those values are passed on to the server and potentially * limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to * count all matches. + *

+ * This method uses an + * {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) + * aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees + * shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use + * {@link #estimatedCount(String)} for empty queries instead. * * @param query the {@link Query} class that specifies the criteria used to find documents. Must not be * {@literal null}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperation.java index b66f6e176..9a6509092 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperation.java @@ -106,6 +106,12 @@ public interface ReactiveFindOperation { /** * Get the number of matching elements. + *

+ * This method uses an + * {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) + * aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but + * guarantees shard, session and transaction compliance. In case an inaccurate count satisfies the applications + * needs use {@link ReactiveMongoOperations#estimatedCount(String)} for empty queries instead. * * @return {@link Mono} emitting total number of matching elements. Never {@literal null}. */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java index 2d981fd1b..a1a0925b7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java @@ -940,6 +940,12 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations { * influence on the resulting number of documents found as those values are passed on to the server and potentially * limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to * count all matches. + *

+ * This method uses an + * {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) + * aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees + * shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use + * {@link #estimatedCount(Class)} for empty queries instead. * * @param query the {@link Query} class that specifies the criteria used to find documents. Must not be * {@literal null}. @@ -956,6 +962,12 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations { * influence on the resulting number of documents found as those values are passed on to the server and potentially * limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to * count all matches. + *

+ * This method uses an + * {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) + * aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees + * shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use + * {@link #estimatedCount(String)} for empty queries instead. * * @param query the {@link Query} class that specifies the criteria used to find documents. * @param collectionName must not be {@literal null} or empty. @@ -971,6 +983,12 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations { * influence on the resulting number of documents found as those values are passed on to the server and potentially * limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to * count all matches. + *

+ * This method uses an + * {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) + * aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees + * shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use + * {@link #estimatedCount(String)} for empty queries instead. * * @param query the {@link Query} class that specifies the criteria used to find documents. Must not be * {@literal null}. @@ -983,6 +1001,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations { /** * Estimate the number of documents, in the collection {@link #getCollectionName(Class) identified by the given type}, * based on collection statistics. + *

+ * Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside + * transactions. * * @param entityClass must not be {@literal null}. * @return a {@link Mono} emitting the estimated number of documents. @@ -996,6 +1017,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations { /** * Estimate the number of documents in the given collection based on collection statistics. + *

+ * Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside + * transactions. * * @param collectionName must not be {@literal null}. * @return a {@link Mono} emitting the estimated number of documents. diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc index 71a82f044..2500dc76f 100644 --- a/src/main/asciidoc/reference/mongodb.adoc +++ b/src/main/asciidoc/reference/mongodb.adoc @@ -2221,6 +2221,7 @@ With the introduction of <> this was no longer possible beca So in version 2.x `MongoOperations.count()` would use the collection statistics if no transaction was in progress, and the aggregation variant if so. As of Spring Data MongoDB 3.x any `count` operation uses regardless the existence of filter criteria the aggregation-based count approach via MongoDBs `countDocuments`. +If the application is fine with the limitations of working upon collection statistics `MongoOperations.estimatedCount()` offers an alternative. [NOTE] ====