diff --git a/driver-core/src/main/com/mongodb/client/model/search/DateSearchFacet.java b/driver-core/src/main/com/mongodb/client/model/search/DateSearchFacet.java index 39d8bb2ddf..958fc5bb2c 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/DateSearchFacet.java +++ b/driver-core/src/main/com/mongodb/client/model/search/DateSearchFacet.java @@ -24,7 +24,7 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface DateSearchFacet extends SearchFacet { /** * Creates a new {@link DateSearchFacet} with the default bucket specified. diff --git a/driver-core/src/main/com/mongodb/client/model/search/FacetSearchCollector.java b/driver-core/src/main/com/mongodb/client/model/search/FacetSearchCollector.java index 0119021663..af2b3aa741 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/FacetSearchCollector.java +++ b/driver-core/src/main/com/mongodb/client/model/search/FacetSearchCollector.java @@ -24,6 +24,6 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface FacetSearchCollector extends SearchCollector { } diff --git a/driver-core/src/main/com/mongodb/client/model/search/LowerBoundSearchCount.java b/driver-core/src/main/com/mongodb/client/model/search/LowerBoundSearchCount.java index 15576d4a5b..c9d1711dac 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/LowerBoundSearchCount.java +++ b/driver-core/src/main/com/mongodb/client/model/search/LowerBoundSearchCount.java @@ -24,7 +24,7 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface LowerBoundSearchCount extends SearchCount { /** * Creates a new {@link LowerBoundSearchCount} that instructs to count documents up to the {@code threshold} exactly, diff --git a/driver-core/src/main/com/mongodb/client/model/search/NumberSearchFacet.java b/driver-core/src/main/com/mongodb/client/model/search/NumberSearchFacet.java index 4587f68809..d2740a6b10 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/NumberSearchFacet.java +++ b/driver-core/src/main/com/mongodb/client/model/search/NumberSearchFacet.java @@ -24,7 +24,7 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface NumberSearchFacet extends SearchFacet { /** * Creates a new {@link NumberSearchFacet} with the default bucket specified. diff --git a/driver-core/src/main/com/mongodb/client/model/search/SearchCollector.java b/driver-core/src/main/com/mongodb/client/model/search/SearchCollector.java index 6f2c45b496..b51d6c4540 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/SearchCollector.java +++ b/driver-core/src/main/com/mongodb/client/model/search/SearchCollector.java @@ -38,15 +38,14 @@ @Beta(Reason.CLIENT) public interface SearchCollector extends Bson { /** - * Returns a {@link SearchCollector} that groups results by values or ranges in the specified faceted fields and returns the count - * for each of those groups. + * Returns a {@link SearchCollector} that groups the results of a search based on the specified operator + * by values or ranges in the specified faceted fields, and returns the count for each of those groups. * * @param operator The search operator to use. * @param facets The non-empty facet definitions. * @return The requested {@link SearchCollector}. * @mongodb.atlas.manual atlas-search/facet/ facet collector */ - @Beta({Reason.CLIENT, Reason.SERVER}) static FacetSearchCollector facet(final SearchOperator operator, final Iterable facets) { notNull("operator", operator); notNull("facets", facets); @@ -54,6 +53,19 @@ static FacetSearchCollector facet(final SearchOperator operator, final Iterable< .append("facets", combineToBson(facets))); } + /** + * Returns a {@link SearchCollector} that groups all the input documents + * by values or ranges in the specified faceted fields, and returns the count for each of those groups. + * + * @param facets The non-empty facet definitions. + * @return The requested {@link SearchCollector}. + * @mongodb.atlas.manual atlas-search/facet/ facet collector + */ + static FacetSearchCollector facet(final Iterable facets) { + notNull("facets", facets); + return new SearchConstructibleBsonElement("facet", new Document("facets", combineToBson(facets))); + } + /** * Creates a {@link SearchCollector} from a {@link Bson} in situations when there is no builder method that better satisfies your needs. * This method cannot be used to validate the syntax. diff --git a/driver-core/src/main/com/mongodb/client/model/search/SearchCount.java b/driver-core/src/main/com/mongodb/client/model/search/SearchCount.java index f9a5917582..eb60fec9de 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/SearchCount.java +++ b/driver-core/src/main/com/mongodb/client/model/search/SearchCount.java @@ -34,7 +34,7 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface SearchCount extends Bson { /** * Returns a {@link SearchCount} that instructs to count documents exactly. diff --git a/driver-core/src/main/com/mongodb/client/model/search/SearchFacet.java b/driver-core/src/main/com/mongodb/client/model/search/SearchFacet.java index 4aac0fef08..2188e06bfb 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/SearchFacet.java +++ b/driver-core/src/main/com/mongodb/client/model/search/SearchFacet.java @@ -44,7 +44,7 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface SearchFacet extends Bson { /** * Returns a {@link SearchFacet} that allows narrowing down search results based on the most frequent diff --git a/driver-core/src/main/com/mongodb/client/model/search/StringSearchFacet.java b/driver-core/src/main/com/mongodb/client/model/search/StringSearchFacet.java index 209eaf9ff4..2d7e21ae63 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/StringSearchFacet.java +++ b/driver-core/src/main/com/mongodb/client/model/search/StringSearchFacet.java @@ -24,7 +24,7 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface StringSearchFacet extends SearchFacet { /** * Creates a new {@link StringSearchFacet} that explicitly limits the number of facet categories. diff --git a/driver-core/src/main/com/mongodb/client/model/search/TotalSearchCount.java b/driver-core/src/main/com/mongodb/client/model/search/TotalSearchCount.java index 2bcbde468f..173322cf8d 100644 --- a/driver-core/src/main/com/mongodb/client/model/search/TotalSearchCount.java +++ b/driver-core/src/main/com/mongodb/client/model/search/TotalSearchCount.java @@ -24,6 +24,6 @@ * @since 4.7 */ @Sealed -@Beta({Reason.CLIENT, Reason.SERVER}) +@Beta(Reason.CLIENT) public interface TotalSearchCount extends SearchCount { } diff --git a/driver-core/src/test/unit/com/mongodb/client/model/search/SearchCollectorTest.java b/driver-core/src/test/unit/com/mongodb/client/model/search/SearchCollectorTest.java index f882655499..3cf9b86507 100644 --- a/driver-core/src/test/unit/com/mongodb/client/model/search/SearchCollectorTest.java +++ b/driver-core/src/test/unit/com/mongodb/client/model/search/SearchCollectorTest.java @@ -62,6 +62,27 @@ void facet() { ); } + @Test + void facetWithoutOperator() { + assertAll( + () -> assertThrows(CodecConfigurationException.class, () -> + // facet names must be unique; `BsonCodec` wraps our `IllegalStateException` into `CodecConfigurationException` + SearchCollector.facet( + asList( + stringFacet("duplicateFacetName", fieldPath("stringFieldName")), + numberFacet("duplicateFacetName", fieldPath("numberFieldName"), asList(10, 20, 30)))) + // we have to render into `BsonDocument` in order to trigger the lazy check + .toBsonDocument() + ), + () -> assertEquals( + documentWithoutOperator() + .toBsonDocument(), + searchCollectorWithoutOperator() + .toBsonDocument() + ) + ); + } + private static SearchCollector docExamplePredefined() { return SearchCollector.facet( exists( @@ -89,4 +110,28 @@ private static Document docExampleCustom() { fieldPath("numberFieldName"), asList(10, 20, 30)))))); } + + private static SearchCollector searchCollectorWithoutOperator() { + return SearchCollector.facet( + asList( + stringFacet( + "stringFacetName", + fieldPath("stringFieldName")), + numberFacet( + "numberFacetName", + fieldPath("numberFieldName"), + asList(10, 20, 30)))); + } + + private static Document documentWithoutOperator() { + return new Document("facet", + new Document("facets", combineToBson(asList( + stringFacet( + "stringFacetName", + fieldPath("stringFieldName")), + numberFacet( + "numberFacetName", + fieldPath("numberFieldName"), + asList(10, 20, 30)))))); + } } diff --git a/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCollector.scala b/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCollector.scala index a651e502b1..24994cda91 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCollector.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCollector.scala @@ -34,18 +34,28 @@ import scala.collection.JavaConverters._ object SearchCollector { /** - * Returns a `SearchCollector` that groups results by values or ranges in the specified faceted fields and returns the count - * for each of those groups. + * Returns a `SearchCollector` that groups the results of a search based on the specified operator + * by values or ranges in the specified faceted fields, and returns the count for each of those groups. * * @param operator The search operator to use. * @param facets The non-empty facet definitions. * @return The requested `SearchCollector`. * @see [[https://www.mongodb.com/docs/atlas/atlas-search/facet/ facet collector]] */ - @Beta(Array(Reason.CLIENT, Reason.SERVER)) def facet(operator: SearchOperator, facets: Iterable[_ <: SearchFacet]): FacetSearchCollector = JSearchCollector.facet(operator, facets.asJava) + /** + * Returns a `SearchCollector` that groups all the input documents + * by values or ranges in the specified faceted fields, and returns the count for each of those groups. + * + * @param facets The non-empty facet definitions. + * @return The requested `SearchCollector`. + * @see [[https://www.mongodb.com/docs/atlas/atlas-search/facet/ facet collector]] + */ + def facet(facets: Iterable[_ <: SearchFacet]): FacetSearchCollector = + JSearchCollector.facet(facets.asJava) + /** * Creates a `SearchCollector` from a `Bson` in situations when there is no builder method that better satisfies your needs. * This method cannot be used to validate the syntax. diff --git a/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCount.scala b/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCount.scala index ecba0ecce0..07220825f3 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCount.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchCount.scala @@ -28,7 +28,7 @@ import org.mongodb.scala.model.Projections * @see [[https://www.mongodb.com/docs/atlas/atlas-search/counting/ Counting]] * @since 4.7 */ -@Beta(Array(Reason.CLIENT, Reason.SERVER)) +@Beta(Array(Reason.CLIENT)) object SearchCount { /** diff --git a/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchFacet.scala b/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchFacet.scala index 3bc27520ea..75b40c3730 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchFacet.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/model/search/SearchFacet.scala @@ -28,7 +28,7 @@ import collection.JavaConverters._ * @see [[https://www.mongodb.com/docs/atlas/atlas-search/facet/#facet-definition Facet definition]] * @since 4.7 */ -@Beta(Array(Reason.CLIENT, Reason.SERVER)) +@Beta(Array(Reason.CLIENT)) object SearchFacet { /** diff --git a/driver-scala/src/main/scala/org/mongodb/scala/model/search/package.scala b/driver-scala/src/main/scala/org/mongodb/scala/model/search/package.scala index 2c919c6f9b..7f04823a41 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/model/search/package.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/model/search/package.scala @@ -269,7 +269,7 @@ package object search { * @see `SearchCollector.facet(SearchOperator, Iterable)` */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type FacetSearchCollector = com.mongodb.client.model.search.FacetSearchCollector /** @@ -375,21 +375,21 @@ package object search { * @see [[https://www.mongodb.com/docs/atlas/atlas-search/counting/ Counting]] */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type SearchCount = com.mongodb.client.model.search.SearchCount /** * @see `SearchCount.total()` */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type TotalSearchCount = com.mongodb.client.model.search.TotalSearchCount /** * @see `SearchCount.lowerBound()` */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type LowerBoundSearchCount = com.mongodb.client.model.search.LowerBoundSearchCount /** @@ -398,28 +398,28 @@ package object search { * @see [[https://www.mongodb.com/docs/atlas/atlas-search/facet/#facet-definition Facet definition]] */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type SearchFacet = com.mongodb.client.model.search.SearchFacet /** * @see `SearchFacet.stringFacet(String, FieldSearchPath)` */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type StringSearchFacet = com.mongodb.client.model.search.StringSearchFacet /** * @see `SearchFacet.numberFacet(String, FieldSearchPath, Iterable)` */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type NumberSearchFacet = com.mongodb.client.model.search.NumberSearchFacet /** * @see `SearchFacet.dateFacet(String, FieldSearchPath, Iterable)` */ @Sealed - @Beta(Array(Reason.CLIENT, Reason.SERVER)) + @Beta(Array(Reason.CLIENT)) type DateSearchFacet = com.mongodb.client.model.search.DateSearchFacet /**