diff --git a/documentation/src/main/asciidoc/reference/components/deprecated-warning.asciidoc b/documentation/src/main/asciidoc/reference/components/deprecated-warning.asciidoc new file mode 100644 index 00000000000..c196e4fd4fd --- /dev/null +++ b/documentation/src/main/asciidoc/reference/components/deprecated-warning.asciidoc @@ -0,0 +1,10 @@ +[WARNING] +==== +Features detailed in this section are _deprecated_: they should be avoided in favor of non-deprecated alternatives. + +The usual https://hibernate.org/community/compatibility-policy/[compatibility policy] applies, +meaning the features are expected to remain available at least until the next major version of Hibernate Search. +Beyond that, they may be altered in a backward-incompatible way -- or even removed. + +Usage of deprecated features is not recommended. +==== diff --git a/documentation/src/main/asciidoc/reference/search-dsl-projection.asciidoc b/documentation/src/main/asciidoc/reference/search-dsl-projection.asciidoc index 0a516f03e2d..1b3e7eca2c4 100644 --- a/documentation/src/main/asciidoc/reference/search-dsl-projection.asciidoc +++ b/documentation/src/main/asciidoc/reference/search-dsl-projection.asciidoc @@ -289,52 +289,115 @@ include::{sourcedir}/org/hibernate/search/documentation/search/projection/Projec [[search-dsl-projection-composite]] == `composite`: combine projections -The `composite` projection applies multiple projections and combines their results. +The `composite` projection applies multiple projections and combines their results, +either as a `List` or as a single object generated using a custom transformer. -To preserve type-safety, you can provide a custom combining function. -The combining function can be a `Function`, a `BiFunction`, -or a `org.hibernate.search.util.common.function.TriFunction`. +To preserve type-safety, you can provide a custom transformer. +The transformer can be a `Function`, a `BiFunction`, +or a `org.hibernate.search.util.common.function.TriFunction`, +depending on the number of inner projections. It will receive values returned by inner projections and return an object combining these values. -Depending on the type of function, -either one, two, or three additional arguments are expected, -one for each inner projection. - -.Returning custom objects created from multiple projected values +.Returning custom objects created from multiple projected values with `.composite().add(...).transform(...)` ==== [source, JAVA, indent=0, subs="+callouts"] ---- include::{sourcedir}/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java[tags=composite-customObject] ---- -<1> Call `.composite(...)`. -<2> Use the constructor of a custom object, `MyPair`, as the combining function. -<3> Define the first projection to combine as a projection on the `title` field, -meaning the constructor of `MyPair` will be called for each matched document -with the value of the `title` field as its first argument. -<4> Define the second projection to combine as a projection on the `genre` field, -meaning the constructor of `MyPair` will be called for each matched document -with the value of the `genre` field as its second argument. -<5> The hits will be the result of calling the combining function for each matched document, +<1> Call `.composite()`. +<2> Define the first projection to combine as a projection on the `title` field. +<3> Define the second projection to combine as a projection on the `genre` field. +<4> Define the transformer as the constructor of a custom object, `MyPair`. +The constructor of `MyPair` will be called for each matched document, +with the value of the `title` field as its first argument, +and the value of the `genre` field as its second argument. +<5> The hits will be the result of calling the transformer for each matched document, in this case `MyPair` instances. ==== -If you need more inner projections, or simply if you don't mind receiving the result of inner projections as a `List`, -you can use the variant of `.composite(...)` that doesn't expect a function argument: +If you pass more than 3 projections as arguments, +then the transform function will have to take a `List` as an argument, +and will be set using `transformList(...)` instead of `transform(..,)`: + +.Returning custom objects created from multiple projected values with `.composite().add(...).transformList(...)` +==== +[source, JAVA, indent=0, subs="+callouts"] +---- +include::{sourcedir}/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java[tags=composite-customObject-fromList] +---- +<1> Call `.composite()`. +<2> Define the first projection to combine as a projection on the `title` field. +<3> Define the second projection to combine as a projection on the `genre` field. +<4> Define the third projection to combine as a projection on the `pageCount` field. +<5> Define the fourth projection to combine as a projection on the `description` field. +<6> Define the transformer as a lambda that will take elements of the list (the projections defined above, in order), +cast them, and pass them to the constructor of a custom class, `MyTuple4`. +<7> The hits will be the result of calling the transformer for each matched document, +in this case `MyTuple4` instances. +==== + +If you don't mind receiving the result of inner projections as a `List`, +you can do without the transformer by calling `asList()`: -.Returning a `List` of projected values +.Returning a `List` of projected values with `.composite().add(...).asList()` ==== [source, JAVA, indent=0, subs="+callouts"] ---- include::{sourcedir}/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java[tags=composite-list] ---- +<1> Call `.composite()`. +<2> Define the first projection to combine as a projection on the `title` field. +<3> Define the second projection to combine as a projection on the `genre` field. +<4> Define the result of the projection as a list, +meaning the hits will be `List` instances with the value of the `title` field of the matched document at index `0`, +and the value of the `genre` field of the matched document at index `1`. +<5> The hits will be `List` instances holding the result of the given projections, in the given order, for each matched document. +==== + +Alternatively, to get the result as a `List`, +you can use the shorter variant of `.composite(...)` that directly takes projections as arguments: + +.Returning a `List` of projected values with `.composite(...)` +==== +[source, JAVA, indent=0, subs="+callouts"] +---- +include::{sourcedir}/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java[tags=composite-list-singlestep] +---- +<1> Call `.composite(...)`. +<2> Define the first projection to combine as a projection on the `title` field. +<3> Define the second projection to combine as a projection on the `genre` field. +<4> The hits will be `List` instances holding the result of the given projections, in the given order, for each matched document, +meaning the hits will be `List` instances with the value of the `title` field of the matched document at index `0`, +and the value of the `genre` field of the matched document at index `1`. +==== + +[[search-dsl-projection-composite-deprecated-variants]] +=== Deprecated variants + +include::components/deprecated-warning.asciidoc[] + +A few `.composite(...)` methods accepting both a function and a list of projections +are available on `SearchProjectionFactory`, but they are deprecated. + +.Deprecated variant of `composite` +==== +[source, JAVA, indent=0, subs="+callouts"] +---- +include::{sourcedir}/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java[tags=composite-customObject-singlestep] +---- <1> Call `.composite(...)`. -<2> Define the first projection to combine as a projection on the `title` field, -meaning the hits will be `List` instances with the value of the `title` field of the matched document at index `0`. -<3> Define the second projection to combine as a projection on the `genre` field, -meaning the hits will be `List` instances with the value of the `genre` field of the matched document at index `1`. -<4> The hits will be `List` instances holding the result of the given projections, in the given order, for each matched document. +<2> Define the transformer as the constructor of a custom object, `MyPair`. +<3> Define the first projection to combine as a projection on the `title` field, +meaning the constructor of `MyPair` will be called for each matched document +with the value of the `title` field as its first argument. +<4> Define the second projection to combine as a projection on the `genre` field, +meaning the constructor of `MyPair` will be called for each matched document +with the value of the `genre` field as its second argument. +<5> The hits will be the result of calling the transformer for each matched document, +in this case `MyPair` instances. ==== + [[search-dsl-projection-extensions]] == Backend-specific extensions diff --git a/documentation/src/test/java/org/hibernate/search/documentation/backend/lucene/type/asnative/LuceneNativeTypeIT.java b/documentation/src/test/java/org/hibernate/search/documentation/backend/lucene/type/asnative/LuceneNativeTypeIT.java index b61a1e4ff70..ebcbc6ddc1b 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/backend/lucene/type/asnative/LuceneNativeTypeIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/backend/lucene/type/asnative/LuceneNativeTypeIT.java @@ -58,11 +58,9 @@ public void smoke() { List result = searchSession.search( WebPage.class ) .extension( LuceneExtension.get() ) - .select( f -> f.composite( - Result::new, - f.entity(), - f.field( "pageRank", Float.class ) - ) ) + .select( f -> f.composite() + .add( f.entity(), f.field( "pageRank", Float.class ) ) + .transform( Result::new ) ) .where( f -> f.fromLuceneQuery( // This affects the document score based on the pageRank FeatureField.newSaturationQuery( "pageRank", "pageRank" ) diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/projection/Book.java b/documentation/src/test/java/org/hibernate/search/documentation/search/projection/Book.java index f59b8254385..a944214b7d5 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/projection/Book.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/projection/Book.java @@ -15,6 +15,7 @@ import org.hibernate.search.engine.backend.types.ObjectStructure; import org.hibernate.search.engine.backend.types.Projectable; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; @@ -34,6 +35,12 @@ public class Book { @KeywordField(projectable = Projectable.YES) private Genre genre; + @GenericField(projectable = Projectable.YES) + private Integer pageCount; + + @FullTextField(analyzer = "english", projectable = Projectable.YES) + private String description; + @ManyToMany @IndexedEmbedded(structure = ObjectStructure.NESTED) private List authors = new ArrayList<>(); @@ -65,6 +72,22 @@ public void setGenre(Genre genre) { this.genre = genre; } + public Integer getPageCount() { + return pageCount; + } + + public void setPageCount(Integer pageCount) { + this.pageCount = pageCount; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + public List getAuthors() { return authors; } diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java b/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java index e54ee648472..c967dc08845 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java @@ -331,6 +331,115 @@ public void distance() { public void composite() { withinSearchSession( searchSession -> { // tag::composite-customObject[] + List> hits = searchSession.search( Book.class ) + .select( f -> f.composite() // <1> + .add( f.field( "title", String.class ), // <2> + f.field( "genre", Genre.class ) ) // <3> + .transform( MyPair::new ) )// <4> + .where( f -> f.matchAll() ) + .fetchHits( 20 ); // <5> + // end::composite-customObject[] + Session session = searchSession.toOrmSession(); + assertThat( hits ).containsExactlyInAnyOrder( + new MyPair<>( + session.getReference( Book.class, BOOK1_ID ).getTitle(), + session.getReference( Book.class, BOOK1_ID ).getGenre() + ), + new MyPair<>( + session.getReference( Book.class, BOOK2_ID ).getTitle(), + session.getReference( Book.class, BOOK2_ID ).getGenre() + ), + new MyPair<>( + session.getReference( Book.class, BOOK3_ID ).getTitle(), + session.getReference( Book.class, BOOK3_ID ).getGenre() + ), + new MyPair<>( + session.getReference( Book.class, BOOK4_ID ).getTitle(), + session.getReference( Book.class, BOOK4_ID ).getGenre() + ) + ); + } ); + + withinSearchSession( searchSession -> { + // tag::composite-customObject-fromList[] + List> hits = searchSession.search( Book.class ) + .select( f -> f.composite() // <1> + .add( f.field( "title", String.class ), // <2> + f.field( "genre", Genre.class ), // <3> + f.field( "pageCount", Integer.class ), // <4> + f.field( "description", String.class ) ) // <5> + .transformList( list -> // <6> + new MyTuple4<>( (String) list.get( 0 ), (Genre) list.get( 1 ), + (Integer) list.get( 2 ), (String) list.get( 3 ) ) ) ) + .where( f -> f.matchAll() ) + .fetchHits( 20 ); // <7> + // end::composite-customObject-fromList[] + Session session = searchSession.toOrmSession(); + assertThat( hits ).containsExactlyInAnyOrder( + new MyTuple4<>( + session.getReference( Book.class, BOOK1_ID ).getTitle(), + session.getReference( Book.class, BOOK1_ID ).getGenre(), + session.getReference( Book.class, BOOK1_ID ).getPageCount(), + session.getReference( Book.class, BOOK1_ID ).getDescription() + ), + new MyTuple4<>( + session.getReference( Book.class, BOOK2_ID ).getTitle(), + session.getReference( Book.class, BOOK2_ID ).getGenre(), + session.getReference( Book.class, BOOK2_ID ).getPageCount(), + session.getReference( Book.class, BOOK2_ID ).getDescription() + ), + new MyTuple4<>( + session.getReference( Book.class, BOOK3_ID ).getTitle(), + session.getReference( Book.class, BOOK3_ID ).getGenre(), + session.getReference( Book.class, BOOK3_ID ).getPageCount(), + session.getReference( Book.class, BOOK3_ID ).getDescription() + ), + new MyTuple4<>( + session.getReference( Book.class, BOOK4_ID ).getTitle(), + session.getReference( Book.class, BOOK4_ID ).getGenre(), + session.getReference( Book.class, BOOK4_ID ).getPageCount(), + session.getReference( Book.class, BOOK4_ID ).getDescription() + ) + ); + } ); + + withinSearchSession( searchSession -> { + // tag::composite-list[] + List> hits = searchSession.search( Book.class ) + .select( f -> f.composite() // <1> + .add( f.field( "title", String.class ), // <2> + f.field( "genre", Genre.class ) ) // <3> + .asList() ) // <4> + .where( f -> f.matchAll() ) + .fetchHits( 20 ); // <5> + // end::composite-list[] + Session session = searchSession.toOrmSession(); + assertThat( hits ).containsExactlyInAnyOrder( + Arrays.asList( + session.getReference( Book.class, BOOK1_ID ).getTitle(), + session.getReference( Book.class, BOOK1_ID ).getGenre() + ), + Arrays.asList( + session.getReference( Book.class, BOOK2_ID ).getTitle(), + session.getReference( Book.class, BOOK2_ID ).getGenre() + ), + Arrays.asList( + session.getReference( Book.class, BOOK3_ID ).getTitle(), + session.getReference( Book.class, BOOK3_ID ).getGenre() + ), + Arrays.asList( + session.getReference( Book.class, BOOK4_ID ).getTitle(), + session.getReference( Book.class, BOOK4_ID ).getGenre() + ) + ); + } ); + } + + @Test + @SuppressWarnings("deprecation") + public void composite_singleStep() { + withinSearchSession( searchSession -> { + // tag::composite-customObject-singlestep[] List> hits = searchSession.search( Book.class ) .select( f -> f.composite( // <1> MyPair::new, // <2> @@ -339,7 +448,7 @@ public void composite() { ) ) .where( f -> f.matchAll() ) .fetchHits( 20 ); // <5> - // end::composite-customObject[] + // end::composite-customObject-singlestep[] Session session = searchSession.toOrmSession(); assertThat( hits ).containsExactlyInAnyOrder( new MyPair<>( @@ -362,7 +471,7 @@ public void composite() { } ); withinSearchSession( searchSession -> { - // tag::composite-list[] + // tag::composite-list-singlestep[] List> hits = searchSession.search( Book.class ) .select( f -> f.composite( // <1> f.field( "title", String.class ), // <2> @@ -370,7 +479,7 @@ public void composite() { ) ) .where( f -> f.matchAll() ) .fetchHits( 20 ); // <4> - // end::composite-list[] + // end::composite-list-singlestep[] Session session = searchSession.toOrmSession(); assertThat( hits ).containsExactlyInAnyOrder( Arrays.asList( @@ -417,6 +526,8 @@ private void initData() { Book book1 = new Book(); book1.setId( BOOK1_ID ); book1.setTitle( "I, Robot" ); + book1.setDescription( "A robot becomes self-aware." ); + book1.setPageCount( 250 ); book1.setGenre( Genre.SCIENCE_FICTION ); book1.getAuthors().add( isaacAsimov ); isaacAsimov.getBooks().add( book1 ); @@ -424,6 +535,8 @@ private void initData() { Book book2 = new Book(); book2.setId( BOOK2_ID ); book2.setTitle( "The Caves of Steel" ); + book2.setDescription( "A robot helps investigate a murder on an extrasolar colony." ); + book2.setPageCount( 206 ); book2.setGenre( Genre.SCIENCE_FICTION ); book2.getAuthors().add( isaacAsimov ); isaacAsimov.getBooks().add( book2 ); @@ -431,6 +544,8 @@ private void initData() { Book book3 = new Book(); book3.setId( BOOK3_ID ); book3.setTitle( "The Robots of Dawn" ); + book3.setDescription( "A crime story about the first \"roboticide\"." ); + book3.setPageCount( 435 ); book3.setGenre( Genre.SCIENCE_FICTION ); book3.getAuthors().add( isaacAsimov ); isaacAsimov.getBooks().add( book3 ); @@ -438,10 +553,11 @@ private void initData() { Book book4 = new Book(); book4.setId( BOOK4_ID ); book4.setTitle( "The Automatic Detective" ); + book4.setDescription( "A robot cab driver turns PI after the disappearance of a neighboring family." ); + book4.setPageCount( 222 ); book4.setGenre( Genre.CRIME_FICTION ); book4.getAuthors().add( aLeeMartinez ); aLeeMartinez.getBooks().add( book3 ); - entityManager.persist( isaacAsimov ); entityManager.persist( aLeeMartinez ); @@ -475,4 +591,33 @@ public int hashCode() { return Objects.hash( first, second ); } } + + private static class MyTuple4 { + private final T1 first; + private final T2 second; + private final T3 third; + private final T4 fourth; + + MyTuple4(T1 first, T2 second, T3 third, T4 fourth) { + this.first = first; + this.second = second; + this.third = third; + this.fourth = fourth; + } + + @Override + public boolean equals(Object obj) { + if ( obj == null || !MyTuple4.class.equals( obj.getClass() ) ) { + return false; + } + MyTuple4 other = (MyTuple4) obj; + return Objects.equals( first, other.first ) && Objects.equals( second, other.second ) + && Objects.equals( third, other.third ) && Objects.equals( fourth, other.fourth ); + } + + @Override + public int hashCode() { + return Objects.hash( first, second, third, fourth ); + } + } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent1Step.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent1Step.java new file mode 100644 index 00000000000..9b44adfdd07 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent1Step.java @@ -0,0 +1,46 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl; + +import org.hibernate.search.engine.search.projection.SearchProjection; + +/** + * The initial step in a "multi-step" composite projection definition, + * where no components have been added yet and the first component can be added. + */ +public interface CompositeProjectionComponent1Step + extends CompositeProjectionComponentsAddStep { + + @Override + CompositeProjectionComponent2Step add(SearchProjection projection); + + @Override + default CompositeProjectionComponent2Step add(ProjectionFinalStep dslFinalStep) { + return add( dslFinalStep.toProjection() ); + } + + @Override + CompositeProjectionComponent3Step add(SearchProjection projection1, + SearchProjection projection2); + + @Override + default CompositeProjectionComponent3Step add(ProjectionFinalStep dslFinalStep1, + ProjectionFinalStep dslFinalStep2) { + return add( dslFinalStep1.toProjection(), dslFinalStep2.toProjection() ); + } + + @Override + CompositeProjectionComponent4Step add(SearchProjection projection1, + SearchProjection projection2, SearchProjection projection3); + + @Override + default CompositeProjectionComponent4Step add(ProjectionFinalStep dslFinalStep1, + ProjectionFinalStep dslFinalStep2, ProjectionFinalStep dslFinalStep3) { + return add( dslFinalStep1.toProjection(), dslFinalStep2.toProjection(), dslFinalStep3.toProjection() ); + } + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent2Step.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent2Step.java new file mode 100644 index 00000000000..75ad033127b --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent2Step.java @@ -0,0 +1,50 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl; + +import java.util.function.Function; + +import org.hibernate.search.engine.search.projection.SearchProjection; + +/** + * The second step in a "multi-step" composite projection definition, + * where 1 projection component has been added and the second component can be added, + * or the projection can be used as-is. + * + * @param The type of values returned by the first projection component. + */ +public interface CompositeProjectionComponent2Step + extends CompositeProjectionComponentsAtLeast1AddedStep { + + @Override + CompositeProjectionComponent3Step add(SearchProjection projection); + + @Override + default CompositeProjectionComponent3Step add(ProjectionFinalStep dslFinalStep) { + return add( dslFinalStep.toProjection() ); + } + + @Override + CompositeProjectionComponent4Step add(SearchProjection projection1, + SearchProjection projection2); + + @Override + default CompositeProjectionComponent4Step add(ProjectionFinalStep dslFinalStep1, + ProjectionFinalStep dslFinalStep2) { + return add( dslFinalStep1.toProjection(), dslFinalStep2.toProjection() ); + } + + /** + * Sets the given function as the way to transform the value of the single projection component added so far. + * + * @param transformer A function to transform the values of projection components added so far. + * @return The final step, where the projection can be retrieved. + * @param The type of values returned by the transformer. + */ + CompositeProjectionOptionsStep transform(Function transformer); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent3Step.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent3Step.java new file mode 100644 index 00000000000..73ee5cfa1fd --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent3Step.java @@ -0,0 +1,42 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl; + +import java.util.function.BiFunction; + +import org.hibernate.search.engine.search.projection.SearchProjection; + +/** + * The third step in a "multi-step" composite projection definition, + * where 2 projection components have been added and the third component can be added, + * or the projection can be used as-is. + * + * @param The type of values returned by the first projection component. + * @param The type of values returned by the second projection component. + */ +public interface CompositeProjectionComponent3Step + extends CompositeProjectionComponentsAtLeast1AddedStep { + + @Override + CompositeProjectionComponent4Step add(SearchProjection projection); + + @Override + default CompositeProjectionComponent4Step add(ProjectionFinalStep dslFinalStep) { + return add( dslFinalStep.toProjection() ); + } + + /** + * Sets the given function as the way to transform the values of projection components added so far, + * combining them into a single value. + * + * @param transformer A function to transform the values of projection components added so far. + * @return The final step, where the projection can be retrieved. + * @param The type of values returned by the transformer. + */ + CompositeProjectionOptionsStep transform(BiFunction transformer); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent4Step.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent4Step.java new file mode 100644 index 00000000000..4d37e16c963 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponent4Step.java @@ -0,0 +1,33 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl; + +import org.hibernate.search.util.common.function.TriFunction; + +/** + * The fourth step in a "multi-step" composite projection definition, + * where 3 projection components have been added and the fourth component can be added, + * or the projection can be used as-is. + * + * @param The type of values returned by the first projection component. + * @param The type of values returned by the second projection component. + * @param The type of values returned by the third projection component. + */ +public interface CompositeProjectionComponent4Step + extends CompositeProjectionComponentsAtLeast1AddedStep { + + /** + * Sets the given function as the way to transform the values of projection components added so far, + * combining them into a single value. + * + * @param transformer A function to transform the values of projection components added so far. + * @return The final step, where the projection can be retrieved. + * @param The type of values returned by the transformer. + */ + CompositeProjectionOptionsStep transform(TriFunction transformer); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponentsAddStep.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponentsAddStep.java new file mode 100644 index 00000000000..6a762b2afdf --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponentsAddStep.java @@ -0,0 +1,108 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl; + +import org.hibernate.search.engine.search.projection.SearchProjection; + +/** + * A step in a "multi-step" composite projection definition where more components can be added. + */ +public interface CompositeProjectionComponentsAddStep { + + /** + * Adds an element to the composite projection based on a previously-built {@link SearchProjection}. + * + * @param projection The projection to add. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + * @param The type of values returned by the projection to add. + */ + CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection projection); + + /** + * Adds an element to the composite projection based on an almost-built {@link SearchProjection}. + * + * @param dslFinalStep A final step in the projection DSL allowing the retrieval of a {@link SearchProjection}. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + * @param The type of values returned by the projection to add. + */ + default CompositeProjectionComponentsAtLeast1AddedStep add(ProjectionFinalStep dslFinalStep) { + return add( dslFinalStep.toProjection() ); + } + + /** + * Adds two elements to the composite projection based on previously-built {@link SearchProjection}s. + * + * @param projection1 The first projection to add. + * @param projection2 The second projection to add. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + * @param The type of values returned by the first projection to add. + * @param The type of values returned by the second projection to add. + */ + CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection projection1, + SearchProjection projection2); + + /** + * Adds two elements to the composite projection based on almost-built {@link SearchProjection}s. + * + * @param dslFinalStep1 A final step in the projection DSL allowing the retrieval of the first {@link SearchProjection}. + * @param dslFinalStep2 A final step in the projection DSL allowing the retrieval of the second {@link SearchProjection}. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + * @param The type of values returned by the first projection to add. + * @param The type of values returned by the second projection to add. + */ + default CompositeProjectionComponentsAtLeast1AddedStep add(ProjectionFinalStep dslFinalStep1, + ProjectionFinalStep dslFinalStep2) { + return add( dslFinalStep1.toProjection(), dslFinalStep2.toProjection() ); + } + + /** + * Adds three elements to the composite projection based on previously-built {@link SearchProjection}s. + * + * @param projection1 The first projection to add. + * @param projection2 The second projection to add. + * @param projection3 The third projection to add. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + * @param The type of values returned by the first projection to add. + * @param The type of values returned by the second projection to add. + * @param The type of values returned by the third projection to add. + */ + CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection projection1, + SearchProjection projection2, SearchProjection projection3); + + /** + * Adds three elements to the composite projection based on almost-built {@link SearchProjection}s. + * + * @param dslFinalStep1 A final step in the projection DSL allowing the retrieval of the first {@link SearchProjection}. + * @param dslFinalStep2 A final step in the projection DSL allowing the retrieval of the second {@link SearchProjection}. + * @param dslFinalStep3 A final step in the projection DSL allowing the retrieval of the third {@link SearchProjection}. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + * @param The type of values returned by the first projection to add. + * @param The type of values returned by the second projection to add. + * @param The type of values returned by the third projection to add. + */ + default CompositeProjectionComponentsAtLeast1AddedStep add(ProjectionFinalStep dslFinalStep1, + ProjectionFinalStep dslFinalStep2, ProjectionFinalStep dslFinalStep3) { + return add( dslFinalStep1.toProjection(), dslFinalStep2.toProjection(), dslFinalStep3.toProjection() ); + } + + /** + * Adds multiple elements to the composite projection based on previously-built {@link SearchProjection}s. + * + * @param projections The projection to add, in order. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + */ + CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection... projections); + + /** + * Adds multiple elements to the composite projection based on the given almost-built {@link SearchProjection}s. + * + * @param dslFinalSteps The final steps in the projection DSL allowing the retrieval of {@link SearchProjection}s. + * @return A DSL step that can be used to add more values, or to retrieve the projection as-is. + */ + CompositeProjectionComponentsAtLeast1AddedStep add(ProjectionFinalStep... dslFinalSteps); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponentsAtLeast1AddedStep.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponentsAtLeast1AddedStep.java new file mode 100644 index 00000000000..988f27efd0c --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionComponentsAtLeast1AddedStep.java @@ -0,0 +1,38 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl; + +import java.util.List; +import java.util.function.Function; + +/** + * A step in a "multi-step" composite projection definition where 1 component or more have been added, + * and more components can be added, + * or the projection can be used as-is to project to a {@link List}. + */ +public interface CompositeProjectionComponentsAtLeast1AddedStep + extends CompositeProjectionComponentsAddStep { + + /** + * Sets the projection to project to a {@link List} + * that will contain values for the projection components added so far, in order. + * + * @return The final step, where the projection can be retrieved. + */ + CompositeProjectionOptionsStep> asList(); + + /** + * Sets the given function as the way to transform the values of the projection components added so far, + * passed as a {@code List}. + * + * @param transformer A function to transform the values of projection components added so far. + * @return The final step, where the projection can be retrieved. + * @param The type of values returned by the transformer. + */ + CompositeProjectionOptionsStep transformList(Function, V> transformer); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionOptionsStep.java index e64e182c897..16f06a0702a 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/CompositeProjectionOptionsStep.java @@ -7,7 +7,8 @@ package org.hibernate.search.engine.search.projection.dsl; /** - * The initial and final step in a composite projection definition, where optional parameters can be set. + * The final step in a composite projection definition + * where optional parameters can be set. * * @param The "self" type (the actual exposed type of this step). * @param The type of composed projections. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactory.java index 5182c692f87..82df230c12a 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactory.java @@ -158,15 +158,21 @@ default FieldProjectionValueStep field(String fieldPath) { */ DistanceToFieldProjectionValueStep distance(String fieldPath, GeoPoint center); + /** + * Starts the definition of a composite projection, + * which will combine multiple given projections. + * + * @return A DSL step where the "composite" projection can be defined in more details. + */ + CompositeProjectionComponent1Step composite(); + /** * Create a projection that will compose a {@link List} based on the given projections. * * @param projections The projections used to populate the list, in order. * @return A DSL step where the "composite" projection can be defined in more details. */ - default CompositeProjectionOptionsStep> composite(SearchProjection... projections) { - return composite( Function.identity(), projections ); - } + CompositeProjectionOptionsStep> composite(SearchProjection... projections); /** * Create a projection that will compose a {@link List} based on the given almost-built projections. @@ -175,7 +181,11 @@ default CompositeProjectionOptionsStep> composite(SearchProjection * @return A DSL step where the "composite" projection can be defined in more details. */ default CompositeProjectionOptionsStep> composite(ProjectionFinalStep... dslFinalSteps) { - return composite( Function.identity(), dslFinalSteps ); + SearchProjection[] projections = new SearchProjection[dslFinalSteps.length]; + for ( int i = 0; i < dslFinalSteps.length; i++ ) { + projections[i] = dslFinalSteps[i].toProjection(); + } + return composite( projections ); } /** @@ -185,8 +195,12 @@ default CompositeProjectionOptionsStep> composite(ProjectionFinalStep * @param projections The projections used to populate the list, in order. * @param The type of the custom object composing the projected elements. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( projections ).transformList( transformer )} instead. */ - CompositeProjectionOptionsStep composite(Function, T> transformer, SearchProjection... projections); + @Deprecated + default CompositeProjectionOptionsStep composite(Function, T> transformer, SearchProjection... projections) { + return composite().add( projections ).transformList( transformer ); + } /** * Create a projection that will compose a custom object based on the given almost-built projections. @@ -195,14 +209,12 @@ default CompositeProjectionOptionsStep> composite(ProjectionFinalStep * @param dslFinalSteps The final steps in the projection DSL allowing the retrieval of {@link SearchProjection}s. * @param The type of the custom object composing the projected elements. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( dslFinalSteps ).transformList( transformer )} instead. */ + @Deprecated default CompositeProjectionOptionsStep composite(Function, T> transformer, ProjectionFinalStep... dslFinalSteps) { - SearchProjection[] projections = new SearchProjection[dslFinalSteps.length]; - for ( int i = 0; i < dslFinalSteps.length; i++ ) { - projections[i] = dslFinalSteps[i].toProjection(); - } - return composite( transformer, projections ); + return composite().add( dslFinalSteps ).transformList( transformer ); } /** @@ -213,8 +225,12 @@ default CompositeProjectionOptionsStep composite(Function, T> * @param

The type of the element passed to the transformer. * @param The type of the custom object composing the projected element. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( projection ).transform( transformer )} instead. */ - CompositeProjectionOptionsStep composite(Function transformer, SearchProjection

projection); + @Deprecated + default CompositeProjectionOptionsStep composite(Function transformer, SearchProjection

projection) { + return composite().add( projection ).transform( transformer ); + } /** * Create a projection that will compose a custom object based on one almost-built projection. @@ -225,9 +241,11 @@ default CompositeProjectionOptionsStep composite(Function, T> * @param

The type of the element passed to the transformer. * @param The type of the custom object composing the projected element. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( dslFinalStep ).transform( transformer )} instead. */ + @Deprecated default CompositeProjectionOptionsStep composite(Function transformer, ProjectionFinalStep

dslFinalStep) { - return composite( transformer, dslFinalStep.toProjection() ); + return composite().add( dslFinalStep ).transform( transformer ); } /** @@ -240,9 +258,14 @@ default CompositeProjectionOptionsStep composite(Function tra * @param The type of the second element passed to the transformer. * @param The type of the custom object composing the projected elements. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( projection1, projection2 ).transform( transformer )} + * instead. */ - CompositeProjectionOptionsStep composite(BiFunction transformer, - SearchProjection projection1, SearchProjection projection2); + @Deprecated + default CompositeProjectionOptionsStep composite(BiFunction transformer, + SearchProjection projection1, SearchProjection projection2) { + return composite().add( projection1, projection2 ).transform( transformer ); + } /** * Create a projection that will compose a custom object based on two almost-built projections. @@ -256,13 +279,13 @@ CompositeProjectionOptionsStep composite(BiFunction * @param The type of the second element passed to the transformer. * @param The type of the custom object composing the projected elements. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( dslFinalStep1, dslFinalStep2 ).transform( transformer )} + * instead. */ + @Deprecated default CompositeProjectionOptionsStep composite(BiFunction transformer, ProjectionFinalStep dslFinalStep1, ProjectionFinalStep dslFinalStep2) { - return composite( - transformer, - dslFinalStep1.toProjection(), dslFinalStep2.toProjection() - ); + return composite().add( dslFinalStep1, dslFinalStep2 ).transform( transformer ); } /** @@ -277,9 +300,14 @@ default CompositeProjectionOptionsStep composite(BiFunction The type of the third element passed to the transformer. * @param The type of the custom object composing the projected elements. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( projection1, projection2, projection3 ).transform( transformer )} + * instead. */ - CompositeProjectionOptionsStep composite(TriFunction transformer, - SearchProjection projection1, SearchProjection projection2, SearchProjection projection3); + @Deprecated + default CompositeProjectionOptionsStep composite(TriFunction transformer, + SearchProjection projection1, SearchProjection projection2, SearchProjection projection3) { + return composite().add( projection1, projection2, projection3 ).transform( transformer ); + } /** * Create a projection that will compose a custom object based on three almost-built projections. @@ -296,14 +324,14 @@ CompositeProjectionOptionsStep composite(TriFunction The type of the third element passed to the transformer. * @param The type of the custom object composing the projected elements. * @return A DSL step where the "composite" projection can be defined in more details. + * @deprecated Use {@code .composite().add( dslFinalStep1, dslFinalStep2, dslFinalStep3 ).transform( transformer )} + * instead. */ + @Deprecated default CompositeProjectionOptionsStep composite(TriFunction transformer, ProjectionFinalStep dslFinalStep1, ProjectionFinalStep dslFinalStep2, ProjectionFinalStep dslFinalStep3) { - return composite( - transformer, - dslFinalStep1.toProjection(), dslFinalStep2.toProjection(), dslFinalStep3.toProjection() - ); + return composite().add( dslFinalStep1, dslFinalStep2, dslFinalStep3 ).transform( transformer ); } /** diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/AbstractCompositeProjectionComponentsAddStep.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/AbstractCompositeProjectionComponentsAddStep.java new file mode 100644 index 00000000000..773272c9c44 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/AbstractCompositeProjectionComponentsAddStep.java @@ -0,0 +1,60 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponentsAddStep; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponentsAtLeast1AddedStep; +import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; +import org.hibernate.search.util.common.impl.Contracts; + +abstract class AbstractCompositeProjectionComponentsAddStep + implements CompositeProjectionComponentsAddStep { + + final SearchProjectionDslContext dslContext; + + public AbstractCompositeProjectionComponentsAddStep(SearchProjectionDslContext dslContext) { + this.dslContext = dslContext; + } + + @Override + public CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection projection) { + return add( new SearchProjection[]{ projection } ); + } + + @Override + public CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection projection1, + SearchProjection projection2) { + return add( new SearchProjection[]{ projection1, projection2 } ); + } + + @Override + public CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection projection1, + SearchProjection projection2, SearchProjection projection3) { + return add( new SearchProjection[]{ projection1, projection2, projection3 } ); + } + + @Override + public CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection... projections) { + Contracts.assertNotNullNorEmpty( projections, "projections" ); + return new CompositeProjectionComponentUnknownNumberAddedStep( dslContext, toProjectionArray( projections ) ); + } + + @Override + public final CompositeProjectionComponentsAtLeast1AddedStep add(ProjectionFinalStep... dslFinalSteps) { + Contracts.assertNotNullNorEmpty( dslFinalSteps, "dslFinalSteps" ); + SearchProjection[] projections = new SearchProjection[dslFinalSteps.length]; + for ( int i = 0; i < dslFinalSteps.length; i++ ) { + projections[i] = dslFinalSteps[i].toProjection(); + } + return add( projections ); + } + + abstract SearchProjection[] toProjectionArray(SearchProjection... otherProjections); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/AbstractCompositeProjectionComponentsAtLeastOneAddedStep.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/AbstractCompositeProjectionComponentsAtLeastOneAddedStep.java new file mode 100644 index 00000000000..7b08beb459d --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/AbstractCompositeProjectionComponentsAtLeastOneAddedStep.java @@ -0,0 +1,43 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import java.util.List; +import java.util.function.Function; + +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponentsAtLeast1AddedStep; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; + +abstract class AbstractCompositeProjectionComponentsAtLeastOneAddedStep + extends AbstractCompositeProjectionComponentsAddStep + implements CompositeProjectionComponentsAtLeast1AddedStep { + + public AbstractCompositeProjectionComponentsAtLeastOneAddedStep(SearchProjectionDslContext dslContext) { + super( dslContext ); + } + + @Override + public CompositeProjectionComponentsAtLeast1AddedStep add(SearchProjection projection) { + return new CompositeProjectionComponentUnknownNumberAddedStep( + dslContext, toProjectionArray( projection ) ); + } + + @Override + public final CompositeProjectionOptionsStep> asList() { + return transformList( Function.identity() ); + } + + @Override + public final CompositeProjectionOptionsStep transformList(Function, V> transformer) { + return new CompositeProjectionFinalStep<>( dslContext, transformer, toProjectionArray() ); + } + + abstract SearchProjection[] toProjectionArray(); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent1StepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent1StepImpl.java new file mode 100644 index 00000000000..35ef1e8c5a4 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent1StepImpl.java @@ -0,0 +1,44 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent1Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent2Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent3Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent4Step; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; + +public class CompositeProjectionComponent1StepImpl extends AbstractCompositeProjectionComponentsAddStep + implements CompositeProjectionComponent1Step { + + public CompositeProjectionComponent1StepImpl(SearchProjectionDslContext dslContext) { + super( dslContext ); + } + + @Override + public CompositeProjectionComponent2Step add(SearchProjection projection) { + return new CompositeProjectionComponent2StepImpl<>( dslContext, projection ); + } + + @Override + public CompositeProjectionComponent3Step add(SearchProjection projection1, + SearchProjection projection2) { + return new CompositeProjectionComponent3StepImpl<>( dslContext, projection1, projection2 ); + } + + @Override + public CompositeProjectionComponent4Step add(SearchProjection projection1, + SearchProjection projection2, SearchProjection projection3) { + return new CompositeProjectionComponent4StepImpl<>( dslContext, projection1, projection2, projection3 ); + } + + @Override + SearchProjection[] toProjectionArray(SearchProjection... otherProjections) { + return otherProjections; + } +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent2StepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent2StepImpl.java new file mode 100644 index 00000000000..e127c4d6eb3 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent2StepImpl.java @@ -0,0 +1,57 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import java.util.function.Function; + +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent2Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent3Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent4Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; + +class CompositeProjectionComponent2StepImpl extends AbstractCompositeProjectionComponentsAtLeastOneAddedStep + implements CompositeProjectionComponent2Step { + + final SearchProjection component1; + + public CompositeProjectionComponent2StepImpl(SearchProjectionDslContext dslContext, + SearchProjection component1) { + super( dslContext ); + this.component1 = component1; + } + + @Override + public CompositeProjectionComponent3Step add(SearchProjection projection) { + return new CompositeProjectionComponent3StepImpl<>( dslContext, component1, projection ); + } + + @Override + public CompositeProjectionComponent4Step add(SearchProjection projection1, + SearchProjection projection2) { + return new CompositeProjectionComponent4StepImpl<>( dslContext, component1, projection1, projection2 ); + } + + @Override + public CompositeProjectionOptionsStep transform(Function transformer) { + return new CompositeProjectionFinalStep<>( dslContext, transformer, component1 ); + } + + @Override + SearchProjection[] toProjectionArray(SearchProjection... otherProjections) { + SearchProjection[] array = new SearchProjection[1 + otherProjections.length]; + array[0] = component1; + System.arraycopy( otherProjections, 0, array, 1, otherProjections.length ); + return array; + } + + @Override + SearchProjection[] toProjectionArray() { + return new SearchProjection[] { component1 }; + } +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent3StepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent3StepImpl.java new file mode 100644 index 00000000000..7fbbe45acc9 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent3StepImpl.java @@ -0,0 +1,55 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import java.util.function.BiFunction; + +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent3Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent4Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; + +class CompositeProjectionComponent3StepImpl + extends AbstractCompositeProjectionComponentsAtLeastOneAddedStep + implements CompositeProjectionComponent3Step { + + final SearchProjection component1; + final SearchProjection component2; + + public CompositeProjectionComponent3StepImpl(SearchProjectionDslContext dslContext, + SearchProjection component1, SearchProjection component2) { + super( dslContext ); + this.component1 = component1; + this.component2 = component2; + } + + @Override + public CompositeProjectionComponent4Step add(SearchProjection projection) { + return new CompositeProjectionComponent4StepImpl<>( dslContext, component1, component2, projection ); + } + + @Override + public CompositeProjectionOptionsStep transform(BiFunction transformer) { + return new CompositeProjectionFinalStep<>( dslContext, transformer, component1, component2 ); + } + + @Override + SearchProjection[] toProjectionArray(SearchProjection... otherProjections) { + SearchProjection[] array = new SearchProjection[2 + otherProjections.length]; + array[0] = component1; + array[1] = component2; + System.arraycopy( otherProjections, 0, array, 2, otherProjections.length ); + return array; + } + + @Override + SearchProjection[] toProjectionArray() { + return new SearchProjection[] { component1, component2 }; + } + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent4StepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent4StepImpl.java new file mode 100644 index 00000000000..bf82404f088 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponent4StepImpl.java @@ -0,0 +1,51 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent4Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; +import org.hibernate.search.util.common.function.TriFunction; + +class CompositeProjectionComponent4StepImpl + extends AbstractCompositeProjectionComponentsAtLeastOneAddedStep + implements CompositeProjectionComponent4Step { + + final SearchProjection component1; + final SearchProjection component2; + final SearchProjection component3; + + public CompositeProjectionComponent4StepImpl(SearchProjectionDslContext dslContext, + SearchProjection component1, SearchProjection component2, SearchProjection component3) { + super( dslContext ); + this.component1 = component1; + this.component2 = component2; + this.component3 = component3; + } + + @Override + public CompositeProjectionOptionsStep transform(TriFunction transformer) { + return new CompositeProjectionFinalStep<>( dslContext, transformer, component1, component2, component3 ); + } + + @Override + SearchProjection[] toProjectionArray(SearchProjection... otherProjections) { + SearchProjection[] array = new SearchProjection[3 + otherProjections.length]; + array[0] = component1; + array[1] = component2; + array[2] = component3; + System.arraycopy( otherProjections, 0, array, 3, otherProjections.length ); + return array; + } + + @Override + SearchProjection[] toProjectionArray() { + return new SearchProjection[] { component1, component2, component3 }; + } + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponentUnknownNumberAddedStep.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponentUnknownNumberAddedStep.java new file mode 100644 index 00000000000..d521aa1a0ea --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionComponentUnknownNumberAddedStep.java @@ -0,0 +1,36 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; + +class CompositeProjectionComponentUnknownNumberAddedStep + extends AbstractCompositeProjectionComponentsAtLeastOneAddedStep { + + final SearchProjection[] components; + + public CompositeProjectionComponentUnknownNumberAddedStep(SearchProjectionDslContext dslContext, + SearchProjection[] components) { + super( dslContext ); + this.components = components; + } + + @Override + SearchProjection[] toProjectionArray(SearchProjection... otherProjections) { + SearchProjection[] array = new SearchProjection[components.length + otherProjections.length]; + System.arraycopy( components, 0, array, 0, components.length ); + System.arraycopy( otherProjections, 0, array, components.length, otherProjections.length ); + return array; + } + + @Override + SearchProjection[] toProjectionArray() { + return components; + } + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionFinalStep.java similarity index 79% rename from engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionOptionsStepImpl.java rename to engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionFinalStep.java index f016857e97c..a47dba56288 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionFinalStep.java @@ -17,24 +17,24 @@ import org.hibernate.search.util.common.function.TriFunction; -public class CompositeProjectionOptionsStepImpl - implements CompositeProjectionOptionsStep, T> { +public class CompositeProjectionFinalStep + implements CompositeProjectionOptionsStep, T> { private final CompositeProjectionBuilder compositeProjectionBuilder; - public CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, + public CompositeProjectionFinalStep(SearchProjectionDslContext dslContext, Function, T> transformer, SearchProjection[] projections) { this.compositeProjectionBuilder = dslContext.scope().projectionBuilders().composite( transformer, projections ); } - public

CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, + public

CompositeProjectionFinalStep(SearchProjectionDslContext dslContext, Function transformer, SearchProjection

projection) { this.compositeProjectionBuilder = dslContext.scope().projectionBuilders().composite( transformer, projection ); } - public CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, + public CompositeProjectionFinalStep(SearchProjectionDslContext dslContext, BiFunction transformer, SearchProjection projection1, SearchProjection projection2) { @@ -42,7 +42,7 @@ public CompositeProjectionOptionsStepImpl(SearchProjectionDslContext .composite( transformer, projection1, projection2 ); } - public CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, + public CompositeProjectionFinalStep(SearchProjectionDslContext dslContext, TriFunction transformer, SearchProjection projection1, SearchProjection projection2, diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/AbstractSearchProjectionFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/AbstractSearchProjectionFactory.java index b2f2933c128..184418623f7 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/AbstractSearchProjectionFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/AbstractSearchProjectionFactory.java @@ -7,12 +7,12 @@ package org.hibernate.search.engine.search.projection.dsl.spi; import java.util.List; -import java.util.function.BiFunction; import java.util.function.Function; import org.hibernate.search.engine.common.dsl.spi.DslExtensionState; import org.hibernate.search.engine.search.common.ValueConvert; import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent1Step; import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionOptionsStep; import org.hibernate.search.engine.search.projection.dsl.DistanceToFieldProjectionValueStep; import org.hibernate.search.engine.search.projection.dsl.DocumentReferenceProjectionOptionsStep; @@ -24,7 +24,8 @@ import org.hibernate.search.engine.search.projection.dsl.ScoreProjectionOptionsStep; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtensionIfSupportedStep; -import org.hibernate.search.engine.search.projection.dsl.impl.CompositeProjectionOptionsStepImpl; +import org.hibernate.search.engine.search.projection.dsl.impl.CompositeProjectionComponent1StepImpl; +import org.hibernate.search.engine.search.projection.dsl.impl.CompositeProjectionFinalStep; import org.hibernate.search.engine.search.projection.dsl.impl.DistanceToFieldProjectionValueStepImpl; import org.hibernate.search.engine.search.projection.dsl.impl.DocumentReferenceProjectionOptionsStepImpl; import org.hibernate.search.engine.search.projection.dsl.impl.EntityProjectionOptionsStepImpl; @@ -35,7 +36,6 @@ import org.hibernate.search.engine.search.projection.dsl.impl.SearchProjectionFactoryExtensionStep; import org.hibernate.search.engine.search.projection.spi.SearchProjectionIndexScope; import org.hibernate.search.engine.spatial.GeoPoint; -import org.hibernate.search.util.common.function.TriFunction; import org.hibernate.search.util.common.impl.Contracts; @@ -97,41 +97,13 @@ public DistanceToFieldProjectionValueStep distance(String fieldPath, } @Override - public CompositeProjectionOptionsStep composite(Function, T> transformer, - SearchProjection... projections) { - Contracts.assertNotNull( transformer, "transformer" ); - Contracts.assertNotNullNorEmpty( projections, "projections" ); - - return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projections ); - } - - @Override - public CompositeProjectionOptionsStep composite(Function transformer, SearchProjection

projection) { - Contracts.assertNotNull( transformer, "transformer" ); - Contracts.assertNotNull( projection, "projection" ); - - return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projection ); - } - - @Override - public CompositeProjectionOptionsStep composite(BiFunction transformer, - SearchProjection projection1, SearchProjection projection2) { - Contracts.assertNotNull( transformer, "transformer" ); - Contracts.assertNotNull( projection1, "projection1" ); - Contracts.assertNotNull( projection2, "projection2" ); - - return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projection1, projection2 ); + public CompositeProjectionComponent1Step composite() { + return new CompositeProjectionComponent1StepImpl( dslContext ); } @Override - public CompositeProjectionOptionsStep composite(TriFunction transformer, - SearchProjection projection1, SearchProjection projection2, SearchProjection projection3) { - Contracts.assertNotNull( transformer, "transformer" ); - Contracts.assertNotNull( projection1, "projection1" ); - Contracts.assertNotNull( projection2, "projection2" ); - Contracts.assertNotNull( projection3, "projection3" ); - - return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projection1, projection2, projection3 ); + public CompositeProjectionOptionsStep> composite(SearchProjection... projections) { + return new CompositeProjectionFinalStep<>( dslContext, Function.identity(), projections ); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/SearchQuerySelectStep.java b/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/SearchQuerySelectStep.java index 87b6d40d814..79c049ea0bb 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/SearchQuerySelectStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/SearchQuerySelectStep.java @@ -7,7 +7,6 @@ package org.hibernate.search.engine.search.query.dsl; import java.util.List; -import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; @@ -98,7 +97,7 @@ public interface SearchQuerySelectStep< * Note that using this method will force you to use casts when consuming the results, * since the returned lists are not typed ({@code List} instead of {@code List}). * You can replace calls to this method advantageously with calls to {@link #select(Function)} - * defining a {@link SearchProjectionFactory#composite(BiFunction, SearchProjection, SearchProjection) composite projection}. + * defining a {@link SearchProjectionFactory#composite() composite projection}. * * @param projections A list of previously-created {@link SearchProjection} objects. * @return The next step. diff --git a/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/ElasticsearchExtensionIT.java b/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/ElasticsearchExtensionIT.java index 13346db8dfb..ffb6be9b028 100644 --- a/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/ElasticsearchExtensionIT.java +++ b/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/ElasticsearchExtensionIT.java @@ -110,11 +110,10 @@ public void queryContext() { ElasticsearchSearchQuerySelectStep context1 = scope.query().extension( ElasticsearchExtension.get() ); ElasticsearchSearchQueryWhereStep context2 = context1.select( - f -> f.composite( + f -> f.composite() + .add( f.documentReference(), f.source() ) // We don't care about the source, it's just to test that the factory context allows ES-specific projection - (docRef, source) -> docRef, - f.documentReference(), f.source() - ) + .transform( (docRef, source) -> docRef ) ); // Note we can use Elasticsearch-specific predicates immediately ElasticsearchSearchQueryOptionsStep context3 = diff --git a/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/LuceneExtensionIT.java b/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/LuceneExtensionIT.java index 1c888f97fe0..bcc390692b7 100644 --- a/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/LuceneExtensionIT.java +++ b/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/LuceneExtensionIT.java @@ -121,11 +121,10 @@ public void queryContext() { LuceneSearchQuerySelectStep context1 = scope.query().extension( LuceneExtension.get() ); LuceneSearchQueryWhereStep context2 = context1.select( - f -> f.composite( + f -> f.composite() + .add( f.documentReference(), f.document() ) // We don't care about the document, it's just to test that the factory context allows Lucene-specific projection - (docRef, document) -> docRef, - f.documentReference(), f.document() - ) + .transform( (docRef, document) -> docRef ) ); // Note we can use Lucene-specific predicates immediately LuceneSearchQueryOptionsStep context3 = diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/bool/BooleanSortAndRangePredicateIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/bool/BooleanSortAndRangePredicateIT.java index 12b15a34953..8a31c37f729 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/bool/BooleanSortAndRangePredicateIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/bool/BooleanSortAndRangePredicateIT.java @@ -23,7 +23,7 @@ import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory; import org.hibernate.search.integrationtest.backend.tck.search.predicate.RangePredicateSpecificsIT; import org.hibernate.search.integrationtest.backend.tck.testsupport.util.rule.SearchSetupHelper; -import org.hibernate.search.integrationtest.backend.tck.search.sort.FieldSearchSortBaseIT; +import org.hibernate.search.integrationtest.backend.tck.search.sort.FieldSortBaseIT; import org.hibernate.search.util.impl.integrationtest.mapper.stub.BulkIndexer; import org.hibernate.search.util.impl.integrationtest.mapper.stub.SimpleMappedIndex; import org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMappingScope; @@ -35,7 +35,7 @@ /** * Tests sorting and ranging behaviour querying a boolean type field * - * @see FieldSearchSortBaseIT + * @see FieldSortBaseIT * @see RangePredicateSpecificsIT */ public class BooleanSortAndRangePredicateIT { diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractSpatialWithinSearchPredicateIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractSpatialWithinPredicateIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractSpatialWithinSearchPredicateIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractSpatialWithinPredicateIT.java index ef5db9ae798..9b989c48003 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractSpatialWithinSearchPredicateIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractSpatialWithinPredicateIT.java @@ -18,7 +18,7 @@ import org.junit.Before; import org.junit.Rule; -public abstract class AbstractSpatialWithinSearchPredicateIT { +public abstract class AbstractSpatialWithinPredicateIT { protected static final String OURSON_QUI_BOIT_ID = "ourson qui boit"; protected static final GeoPoint OURSON_QUI_BOIT_GEO_POINT = GeoPoint.of( 45.7705687,4.835233 ); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinBoundingBoxPredicateSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinBoundingBoxPredicateSpecificsIT.java index ffe2a69b1a1..57834ef5e13 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinBoundingBoxPredicateSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinBoundingBoxPredicateSpecificsIT.java @@ -13,7 +13,7 @@ import org.junit.Test; -public class SpatialWithinBoundingBoxPredicateSpecificsIT extends AbstractSpatialWithinSearchPredicateIT { +public class SpatialWithinBoundingBoxPredicateSpecificsIT extends AbstractSpatialWithinPredicateIT { private static final GeoBoundingBox BOUNDING_BOX_1 = GeoBoundingBox.of( GeoPoint.of( 45.785889, 4.819749 ), diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinCirclePredicateSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinCirclePredicateSpecificsIT.java index b5b600eff09..8702a3b15e1 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinCirclePredicateSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinCirclePredicateSpecificsIT.java @@ -13,7 +13,7 @@ import org.junit.Test; -public class SpatialWithinCirclePredicateSpecificsIT extends AbstractSpatialWithinSearchPredicateIT { +public class SpatialWithinCirclePredicateSpecificsIT extends AbstractSpatialWithinPredicateIT { private static final GeoPoint METRO_HOTEL_DE_VILLE = GeoPoint.of( 45.7673396, 4.833743 ); private static final GeoPoint METRO_GARIBALDI = GeoPoint.of( 45.7515926, 4.8514779 ); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinPolygonPredicateSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinPolygonPredicateSpecificsIT.java index 5fdc45df18c..7da7e98555c 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinPolygonPredicateSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SpatialWithinPolygonPredicateSpecificsIT.java @@ -13,7 +13,7 @@ import org.junit.Test; -public class SpatialWithinPolygonPredicateSpecificsIT extends AbstractSpatialWithinSearchPredicateIT { +public class SpatialWithinPolygonPredicateSpecificsIT extends AbstractSpatialWithinPredicateIT { private static final GeoPolygon POLYGON_1 = GeoPolygon.of( GeoPoint.of( 45.785889, 4.819749 ), diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeProjectionMultiStepIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeProjectionMultiStepIT.java new file mode 100644 index 00000000000..9b8412088c1 --- /dev/null +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeProjectionMultiStepIT.java @@ -0,0 +1,570 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.integrationtest.backend.tck.search.projection; + +import static org.hibernate.search.util.impl.integrationtest.common.assertion.SearchResultAssert.assertThatQuery; + +import java.time.LocalDate; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.hibernate.search.engine.backend.document.DocumentElement; +import org.hibernate.search.engine.backend.document.IndexFieldReference; +import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaElement; +import org.hibernate.search.engine.backend.types.Projectable; +import org.hibernate.search.engine.backend.types.dsl.IndexFieldTypeFactory; +import org.hibernate.search.engine.backend.types.dsl.StandardIndexFieldTypeOptionsStep; +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent1Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent2Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent3Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponent4Step; +import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionComponentsAtLeast1AddedStep; +import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; +import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; +import org.hibernate.search.integrationtest.backend.tck.testsupport.util.StandardFieldMapper; +import org.hibernate.search.integrationtest.backend.tck.testsupport.util.ValueWrapper; +import org.hibernate.search.integrationtest.backend.tck.testsupport.util.rule.SearchSetupHelper; +import org.hibernate.search.util.impl.integrationtest.mapper.stub.SimpleMappedIndex; +import org.hibernate.search.util.impl.test.data.Pair; +import org.hibernate.search.util.impl.test.data.Triplet; + +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +/** + * Tests composite projections created through the multi-step DSL, + * e.g. {@code f.composite().add( otherProjection1 ).add( otherProjection2 ).transform( MyPair::new ) }, + * as opposed to the single-step DSL, + * e.g. {@code f.composite( MyPair::new, otherProjection1, otherProjection2 ) }, + * which is tested in {@link CompositeProjectionSingleStepIT}. + */ +@RunWith(Enclosed.class) +public class CompositeProjectionMultiStepIT { + + private static final String DOCUMENT_1 = "1"; + private static final String DOCUMENT_2 = "2"; + private static final String DOCUMENT_3 = "3"; + + @ClassRule + public static final SearchSetupHelper setupHelper = new SearchSetupHelper(); + + private static final SimpleMappedIndex index = SimpleMappedIndex.of( IndexBinding::new ); + + @BeforeClass + public static void setup() { + setupHelper.start().withIndex( index ).setup(); + + index.bulkIndexer() + .add( DOCUMENT_1, document -> { + index.binding().field1.document1Value.write( document ); + index.binding().field2.document1Value.write( document ); + index.binding().field3.document1Value.write( document ); + index.binding().field4.document1Value.write( document ); + } ) + .add( DOCUMENT_2, document -> { + index.binding().field1.document2Value.write( document ); + index.binding().field2.document2Value.write( document ); + index.binding().field3.document2Value.write( document ); + index.binding().field4.document2Value.write( document ); + } ) + .add( DOCUMENT_3, document -> { + index.binding().field1.document3Value.write( document ); + index.binding().field2.document3Value.write( document ); + index.binding().field3.document3Value.write( document ); + index.binding().field4.document3Value.write( document ); + } ) + .join(); + } + + @Test + public void takariCpSuiteWorkaround() { + // Workaround to get Takari-CPSuite to run this test. + } + + interface AddVariant { + S add(SearchProjectionFactory f, CompositeProjectionComponent1Step step); + } + + private abstract static class AbstractAtLeast1AddedIT { + + @Parameterized.Parameter + public AddVariant addVariant; + + @Test + public void asList() { + assertThatQuery( index.query() + .select( f -> addVariant.add( f, f.composite() ).asList() ) + .where( f -> f.matchAll() ) ) + .hasHitsAnyOrder( expectedLists() ); + } + + @Test + public void transformList() { + assertThatQuery( index.query() + .select( f -> addVariant.add( f, f.composite() ).transformList( ValueWrapper>::new ) ) + .where( f -> f.matchAll() ) ) + .hasHitsAnyOrder( expectedLists().stream().>>map( ValueWrapper::new ).collect( Collectors.toList() ) ); + } + + protected abstract Collection> expectedLists(); + + } + + private abstract static class AbstractKnownNumberAddedIT + extends AbstractAtLeast1AddedIT { + + @Test + public void transform() { + assertThatQuery( index.query() + .select( f -> transform( addVariant.add( f, f.composite() ) ) ) + .where( f -> f.matchAll() ) ) + .hasHitsAnyOrder( expectedTransformed() ); + } + + protected abstract ProjectionFinalStep transform(S step); + + protected abstract Collection expectedTransformed(); + + } + + static Collection> oneComponentExpectedLists() { + return Arrays.asList( + Collections.singletonList( index.binding().field1.document1Value.indexedValue ), + Collections.singletonList( index.binding().field1.document2Value.indexedValue ), + Collections.singletonList( index.binding().field1.document3Value.indexedValue ) + ); + } + + static Collection> oneComponentExpectedTransformed() { + return Arrays.asList( + new ValueWrapper<>( index.binding().field1.document1Value.indexedValue ), + new ValueWrapper<>( index.binding().field1.document2Value.indexedValue ), + new ValueWrapper<>( index.binding().field1.document3Value.indexedValue ) + ); + } + + @RunWith(Parameterized.class) + public static class OneComponentAddIndividuallyIT + extends AbstractKnownNumberAddedIT, ValueWrapper> { + @Parameterized.Parameters + public static List>> adds() { + return Arrays.asList( + (f, step) -> step.add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + ); + } + + @Override + protected Collection> expectedLists() { + return oneComponentExpectedLists(); + } + + @Override + protected ProjectionFinalStep> transform(CompositeProjectionComponent2Step step) { + return step.transform( ValueWrapper::new ); + } + + @Override + protected Collection> expectedTransformed() { + return oneComponentExpectedTransformed(); + } + } + + @RunWith(Parameterized.class) + public static class OneComponentAddArrayIT + extends AbstractAtLeast1AddedIT { + @Parameterized.Parameters + public static List> adds() { + return Arrays.asList( + (f, step) -> step.add( new ProjectionFinalStep[] { f.field( index.binding().field1.relativeFieldName, String.class ) } ), + (f, step) -> step.add( new SearchProjection[] { f.field( index.binding().field1.relativeFieldName, String.class ).toProjection() } ) + ); + } + + @Override + protected Collection> expectedLists() { + return oneComponentExpectedLists(); + } + } + + static Collection> twoComponentExpectedLists() { + return Arrays.asList( + Arrays.asList( index.binding().field1.document1Value.indexedValue, + index.binding().field2.document1Value.indexedValue ), + Arrays.asList( index.binding().field1.document2Value.indexedValue, + index.binding().field2.document2Value.indexedValue ), + Arrays.asList( index.binding().field1.document3Value.indexedValue, + index.binding().field2.document3Value.indexedValue ) + ); + } + + static Collection> twoComponentExpectedTransformed() { + return Arrays.asList( + new Pair<>( index.binding().field1.document1Value.indexedValue, + index.binding().field2.document1Value.indexedValue ), + new Pair<>( index.binding().field1.document2Value.indexedValue, + index.binding().field2.document2Value.indexedValue ), + new Pair<>( index.binding().field1.document3Value.indexedValue, + index.binding().field2.document3Value.indexedValue ) + ); + } + + @RunWith(Parameterized.class) + public static class TwoComponentsAddIndividuallyIT + extends AbstractKnownNumberAddedIT, Pair> { + @Parameterized.Parameters + public static List>> adds() { + return Arrays.asList( + (f, step) -> step.add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ), + f.field( index.binding().field2.relativeFieldName, String.class ) ) + ); + } + + @Override + protected Collection> expectedLists() { + return twoComponentExpectedLists(); + } + + @Override + protected ProjectionFinalStep> transform(CompositeProjectionComponent3Step step) { + return step.transform( Pair::new ); + } + + @Override + protected Collection> expectedTransformed() { + return twoComponentExpectedTransformed(); + } + } + + @RunWith(Parameterized.class) + public static class TwoComponentsAddArrayIT + extends AbstractAtLeast1AddedIT { + @Parameterized.Parameters + public static List> adds() { + return Arrays.asList( + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ), + f.field( index.binding().field2.relativeFieldName, String.class ) ), + (f, step) -> step + .add( new ProjectionFinalStep[] { f.field( index.binding().field1.relativeFieldName, String.class ) } ) + .add( new ProjectionFinalStep[] { f.field( index.binding().field2.relativeFieldName, String.class ) } ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( new ProjectionFinalStep[] { f.field( index.binding().field2.relativeFieldName, String.class ) } ), + (f, step) -> step + .add( new ProjectionFinalStep[] { f.field( index.binding().field1.relativeFieldName, String.class ) } ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ) + ); + } + + @Override + protected Collection> expectedLists() { + return twoComponentExpectedLists(); + } + } + + static Collection> threeComponentExpectedLists() { + return Arrays.asList( + Arrays.asList( index.binding().field1.document1Value.indexedValue, + index.binding().field2.document1Value.indexedValue, + index.binding().field3.document1Value.indexedValue ), + Arrays.asList( index.binding().field1.document2Value.indexedValue, + index.binding().field2.document2Value.indexedValue, + index.binding().field3.document2Value.indexedValue ), + Arrays.asList( index.binding().field1.document3Value.indexedValue, + index.binding().field2.document3Value.indexedValue, + index.binding().field3.document3Value.indexedValue ) + ); + } + + static Collection> threeComponentExpectedTransformed() { + return Arrays.asList( + new Triplet<>( index.binding().field1.document1Value.indexedValue, + index.binding().field2.document1Value.indexedValue, + index.binding().field3.document1Value.indexedValue ), + new Triplet<>( index.binding().field1.document2Value.indexedValue, + index.binding().field2.document2Value.indexedValue, + index.binding().field3.document2Value.indexedValue ), + new Triplet<>( index.binding().field1.document3Value.indexedValue, + index.binding().field2.document3Value.indexedValue, + index.binding().field3.document3Value.indexedValue ) + ); + } + + @RunWith(Parameterized.class) + public static class ThreeComponentsAddIndividuallyIT + extends AbstractKnownNumberAddedIT< + CompositeProjectionComponent4Step, + Triplet + > { + @Parameterized.Parameters + public static List>> adds() { + return Arrays.asList( + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ), + f.field( index.binding().field2.relativeFieldName, String.class ), + f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ), + f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ), + f.field( index.binding().field2.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ) + ); + } + + @Override + protected Collection> expectedLists() { + return threeComponentExpectedLists(); + } + + @Override + protected ProjectionFinalStep> transform( + CompositeProjectionComponent4Step step) { + return step.transform( Triplet::new ); + } + + @Override + protected Collection> expectedTransformed() { + return threeComponentExpectedTransformed(); + } + } + + @RunWith(Parameterized.class) + public static class ThreeComponentsAddArrayIT + extends AbstractAtLeast1AddedIT { + @Parameterized.Parameters + public static List> adds() { + return Arrays.asList( + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ), + f.field( index.binding().field2.relativeFieldName, String.class ), + f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ), + (f, step) -> step + .add( new ProjectionFinalStep[] { f.field( index.binding().field1.relativeFieldName, String.class ) } ) + .add( new ProjectionFinalStep[] { f.field( index.binding().field2.relativeFieldName, String.class ) } ) + .add( new ProjectionFinalStep[] { f.field( index.binding().field3.relativeFieldName, LocalDate.class ) } ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ), + f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ) + .add( new ProjectionFinalStep[] { f.field( index.binding().field3.relativeFieldName, LocalDate.class ) } ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ), + f.field( index.binding().field2.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ) + ); + } + + @Override + protected Collection> expectedLists() { + return threeComponentExpectedLists(); + } + } + + static Collection> fourComponentExpectedLists() { + return Arrays.asList( + Arrays.asList( index.binding().field1.document1Value.indexedValue, + index.binding().field2.document1Value.indexedValue, + index.binding().field3.document1Value.indexedValue, + index.binding().field4.document1Value.indexedValue ), + Arrays.asList( index.binding().field1.document2Value.indexedValue, + index.binding().field2.document2Value.indexedValue, + index.binding().field3.document2Value.indexedValue, + index.binding().field4.document2Value.indexedValue ), + Arrays.asList( index.binding().field1.document3Value.indexedValue, + index.binding().field2.document3Value.indexedValue, + index.binding().field3.document3Value.indexedValue, + index.binding().field4.document3Value.indexedValue ) + ); + } + + @RunWith(Parameterized.class) + public static class FourComponentsAddIndividuallyIT + extends AbstractAtLeast1AddedIT { + @Parameterized.Parameters + public static List> adds() { + return Arrays.asList( + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ) + .add( f.field( index.binding().field4.relativeFieldName, String.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ), + f.field( index.binding().field3.relativeFieldName, LocalDate.class ), + f.field( index.binding().field4.relativeFieldName, String.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field3.relativeFieldName, LocalDate.class ), + f.field( index.binding().field4.relativeFieldName, String.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ) + .add( new ProjectionFinalStep[] { f.field( index.binding().field4.relativeFieldName, String.class ) } ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ), + f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ) + .add( f.field( index.binding().field4.relativeFieldName, String.class ) ), + (f, step) -> step + .add( f.field( index.binding().field1.relativeFieldName, String.class ), + f.field( index.binding().field2.relativeFieldName, String.class ), + f.field( index.binding().field3.relativeFieldName, LocalDate.class ) ) + .add( f.field( index.binding().field4.relativeFieldName, String.class ) ) + ); + } + + @Override + protected Collection> expectedLists() { + return fourComponentExpectedLists(); + } + } + + public static class SpecificsIT { + @Test + public void compositeInComposite() { + assertThatQuery( index.query() + .select( f -> f.composite() + .add( f.composite() + .add( f.field( index.binding().field1.relativeFieldName, String.class ) ) + .add( f.field( index.binding().field2.relativeFieldName, String.class ) ) + .transform( Pair::new ) ) + .add( f.score() ) + .transform( Pair::new ) ) + .where( f -> f.matchAll() ) ) + .hasHitsAnyOrder( + new Pair<>( new Pair<>( index.binding().field1.document1Value.indexedValue, index.binding().field2.document1Value.indexedValue ), 1.0F ), + new Pair<>( new Pair<>( index.binding().field1.document2Value.indexedValue, index.binding().field2.document2Value.indexedValue ), 1.0F ), + new Pair<>( new Pair<>( index.binding().field1.document3Value.indexedValue, index.binding().field2.document3Value.indexedValue ), 1.0F ) + ); + } + } + + + private static class IndexBinding { + final FieldModel field1; + final FieldModel field2; + final FieldModel field3; + final FieldModel field4; + + IndexBinding(IndexSchemaElement root) { + field1 = FieldModel.mapper( String.class, "field1value1", "field1value2", "field1value3" ) + .map( root, "field1" ); + field2 = FieldModel.mapper( String.class, "field2value1", "field2value2", "field2value3" ) + .map( root, "field2" ); + field3 = FieldModel.mapper( LocalDate.class, + LocalDate.of( 2017, 12, 3 ), + LocalDate.of( 2017, 12, 4 ), + LocalDate.of( 2017, 12, 5 ) ) + .map( root, "field3" ); + field4 = FieldModel.mapper( String.class, "field4value1", "field4value2", "field4value3" ) + .map( root, "field4" ); + } + } + + private static class ValueModel { + private final IndexFieldReference reference; + final F indexedValue; + + private ValueModel(IndexFieldReference reference, F indexedValue) { + this.reference = reference; + this.indexedValue = indexedValue; + } + + public void write(DocumentElement target) { + target.addValue( reference, indexedValue ); + } + } + + private static class FieldModel { + static StandardFieldMapper> mapper(Class type, + F document1Value, F document2Value, F document3Value) { + return mapper( + c -> (StandardIndexFieldTypeOptionsStep) c.as( type ), + document1Value, document2Value, document3Value + ); + } + + static StandardFieldMapper> mapper( + Function> configuration, + F document1Value, F document2Value, F document3Value) { + return StandardFieldMapper.of( + configuration, + c -> c.projectable( Projectable.YES ), + (reference, name) -> new FieldModel<>( reference, name, document1Value, document2Value, document3Value ) + ); + } + + final String relativeFieldName; + + final ValueModel document1Value; + final ValueModel document2Value; + final ValueModel document3Value; + + private FieldModel(IndexFieldReference reference, String relativeFieldName, + F document1Value, F document2Value, F document3Value) { + this.relativeFieldName = relativeFieldName; + this.document1Value = new ValueModel<>( reference, document1Value ); + this.document2Value = new ValueModel<>( reference, document2Value ); + this.document3Value = new ValueModel<>( reference, document3Value ); + } + } + + private static class Book { + + private String title; + + public Book(String title) { + this.title = title; + } + + @Override + public boolean equals(Object obj) { + if ( !(obj instanceof Book) ) { + return false; + } + Book other = (Book) obj; + return Objects.equals( title, other.title ); + } + + @Override + public int hashCode() { + return Objects.hash( title ); + } + + @Override + public String toString() { + return title; + } + } + +} diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeSearchProjectionIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeProjectionSingleStepIT.java similarity index 97% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeSearchProjectionIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeProjectionSingleStepIT.java index 6a2153468dc..7facbb33197 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeSearchProjectionIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/CompositeProjectionSingleStepIT.java @@ -29,7 +29,15 @@ import org.junit.Rule; import org.junit.Test; -public class CompositeSearchProjectionIT { +/** + * Tests composite projections created through the single-step DSL, + * e.g. {@code f.composite( MyPair::new, otherProjection1, otherProjection2 ) }, + * as opposed to the multi-step DSL, + * e.g. {@code f.composite().add( otherProjection1 ).add( otherProjection2 ).transform( MyPair::new ) }, + * which is tested in {@link CompositeProjectionMultiStepIT}. + */ +@SuppressWarnings("deprecation") +public class CompositeProjectionSingleStepIT { private static final String DOCUMENT_1 = "1"; private static final String DOCUMENT_2 = "2"; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionMultiValuedBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionMultiValuedBaseIT.java similarity index 96% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionMultiValuedBaseIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionMultiValuedBaseIT.java index b7afaef28be..144bffe4534 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionMultiValuedBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionMultiValuedBaseIT.java @@ -51,7 +51,7 @@ */ @RunWith(Parameterized.class) @TestForIssue(jiraKey = "HSEARCH-3391") -public class DistanceSearchProjectionMultiValuedBaseIT { +public class DistanceProjectionMultiValuedBaseIT { private static final GeoPointFieldTypeDescriptor fieldType = GeoPointFieldTypeDescriptor.INSTANCE; private static final Set> supportedFieldTypes = Collections.singleton( fieldType ); @@ -110,7 +110,7 @@ public static void setup() { private final TestedFieldStructure fieldStructure; private final DataSet dataSet; - public DistanceSearchProjectionMultiValuedBaseIT(TestedFieldStructure fieldStructure, DataSet dataSet) { + public DistanceProjectionMultiValuedBaseIT(TestedFieldStructure fieldStructure, DataSet dataSet) { this.fieldStructure = fieldStructure; this.dataSet = dataSet; } @@ -148,11 +148,10 @@ public void duplicated() { String fieldPath = getFieldPath(); ListAssert, List>> hitsAssert = assertThatQuery( scope.query() - .select( f -> f.composite( - Pair::new, - f.distance( fieldPath, CENTER_POINT_1 ).multi(), - f.distance( fieldPath, CENTER_POINT_1 ).multi() - ) ) + .select( f -> f.composite() + .add( f.distance( fieldPath, CENTER_POINT_1 ).multi(), + f.distance( fieldPath, CENTER_POINT_1 ).multi() ) + .transform( Pair::new ) ) .where( f -> f.matchAll() ) .routing( dataSet.routingKey ) .toQuery() ) @@ -270,12 +269,11 @@ public void several() { StubMappingScope scope = mainIndex.createScope(); ListAssert, List, List>> hitsAssert = assertThatQuery( scope.query() - .select( f -> f.composite( - Triplet::new, - f.distance( getFieldPath(), CENTER_POINT_1 ).multi(), - f.distance( getFieldPath(), CENTER_POINT_2 ).multi(), - f.distance( getFieldPath(), CENTER_POINT_1 ).multi().unit( DistanceUnit.KILOMETERS ) - ) ) + .select( f -> f.composite() + .add( f.distance( getFieldPath(), CENTER_POINT_1 ).multi(), + f.distance( getFieldPath(), CENTER_POINT_2 ).multi(), + f.distance( getFieldPath(), CENTER_POINT_1 ).multi().unit( DistanceUnit.KILOMETERS ) ) + .transform( Triplet::new ) ) .where( f -> f.matchAll() ) .routing( dataSet.routingKey ) .toQuery() ) diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionSingleValuedBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionSingleValuedBaseIT.java similarity index 96% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionSingleValuedBaseIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionSingleValuedBaseIT.java index 152a518f957..1589df7af13 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionSingleValuedBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionSingleValuedBaseIT.java @@ -53,7 +53,7 @@ * Tests basic behavior of projections on the distance between a given point and the value of a single-valued field. */ @RunWith(Parameterized.class) -public class DistanceSearchProjectionSingleValuedBaseIT { +public class DistanceProjectionSingleValuedBaseIT { private static final GeoPointFieldTypeDescriptor fieldType = GeoPointFieldTypeDescriptor.INSTANCE; private static final Set> supportedFieldTypes = Collections.singleton( fieldType ); @@ -105,7 +105,7 @@ public static void setup() { private final TestedFieldStructure fieldStructure; private final DataSet dataSet; - public DistanceSearchProjectionSingleValuedBaseIT(TestedFieldStructure fieldStructure, DataSet dataSet) { + public DistanceProjectionSingleValuedBaseIT(TestedFieldStructure fieldStructure, DataSet dataSet) { this.fieldStructure = fieldStructure; this.dataSet = dataSet; } @@ -170,11 +170,10 @@ public void duplicated() { String fieldPath = getFieldPath(); ListAssert> hitsAssert = assertThatQuery( scope.query() - .select( f -> f.composite( - Pair::new, - f.distance( fieldPath, CENTER_POINT_1 ), - f.distance( fieldPath, CENTER_POINT_1 ) - ) ) + .select( f -> f.composite() + .add( f.distance( fieldPath, CENTER_POINT_1 ), + f.distance( fieldPath, CENTER_POINT_1 ) ) + .transform( Pair::new ) ) .where( f -> f.matchAll() ) .routing( dataSet.routingKey ) .toQuery() ) @@ -292,12 +291,11 @@ public void several() { StubMappingScope scope = mainIndex.createScope(); ListAssert> hitsAssert = assertThatQuery( scope.query() - .select( f -> f.composite( - Triplet::new, - f.distance( getFieldPath(), CENTER_POINT_1 ), - f.distance( getFieldPath(), CENTER_POINT_2 ), - f.distance( getFieldPath(), CENTER_POINT_1 ).unit( DistanceUnit.KILOMETERS ) - ) ) + .select( f -> f.composite() + .add( f.distance( getFieldPath(), CENTER_POINT_1 ), + f.distance( getFieldPath(), CENTER_POINT_2 ), + f.distance( getFieldPath(), CENTER_POINT_1 ).unit( DistanceUnit.KILOMETERS ) ) + .transform( Triplet::new ) ) .where( f -> f.matchAll() ) .routing( dataSet.routingKey ) .toQuery() ) diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionTypeCheckingAndConversionIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionTypeCheckingAndConversionIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionTypeCheckingAndConversionIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionTypeCheckingAndConversionIT.java index 468aedadb9e..4d72fa339df 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionTypeCheckingAndConversionIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionTypeCheckingAndConversionIT.java @@ -44,7 +44,7 @@ * Tests behavior related to type checking and type conversion of * projections on the distance between a field value and a given point. */ -public class DistanceSearchProjectionTypeCheckingAndConversionIT { +public class DistanceProjectionTypeCheckingAndConversionIT { private static final GeoPointFieldTypeDescriptor fieldType = GeoPointFieldTypeDescriptor.INSTANCE; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionTypeIndependentIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionTypeIndependentIT.java similarity index 96% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionTypeIndependentIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionTypeIndependentIT.java index 85c5bbb47ea..e9eea5d9885 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionTypeIndependentIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionTypeIndependentIT.java @@ -30,9 +30,9 @@ * for distance projections. *

* Behavior that is specific to the field type is tested elsewhere, - * e.g. {@link DistanceSearchProjectionSingleValuedBaseIT} and {@link DistanceSearchProjectionTypeCheckingAndConversionIT}. + * e.g. {@link DistanceProjectionSingleValuedBaseIT} and {@link DistanceProjectionTypeCheckingAndConversionIT}. */ -public class DistanceSearchProjectionTypeIndependentIT { +public class DistanceProjectionTypeIndependentIT { private static final GeoPoint SOME_POINT = GeoPoint.of( 45.749828, 4.854172 ); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionUnsupportedTypesIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionUnsupportedTypesIT.java similarity index 95% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionUnsupportedTypesIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionUnsupportedTypesIT.java index 6ceaeb999c2..36176c3876c 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceSearchProjectionUnsupportedTypesIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/DistanceProjectionUnsupportedTypesIT.java @@ -32,7 +32,7 @@ * i.e. error messages. */ @RunWith(Parameterized.class) -public class DistanceSearchProjectionUnsupportedTypesIT { +public class DistanceProjectionUnsupportedTypesIT { private static Stream> unsupportedTypeDescriptors() { return FieldTypeDescriptor.getAll().stream() @@ -60,7 +60,7 @@ public static void setup() { private final FieldTypeDescriptor fieldTypeDescriptor; - public DistanceSearchProjectionUnsupportedTypesIT(FieldTypeDescriptor fieldTypeDescriptor) { + public DistanceProjectionUnsupportedTypesIT(FieldTypeDescriptor fieldTypeDescriptor) { this.fieldTypeDescriptor = fieldTypeDescriptor; } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionMultiValuedBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionMultiValuedBaseIT.java similarity index 97% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionMultiValuedBaseIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionMultiValuedBaseIT.java index c407e44ef2e..6fc375d504b 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionMultiValuedBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionMultiValuedBaseIT.java @@ -35,11 +35,11 @@ /** * Tests basic behavior of projections on a multi-valued field, common to all supported types. *

- * See {@link FieldSearchProjectionSingleValuedBaseIT} for single-valued fields. + * See {@link FieldProjectionSingleValuedBaseIT} for single-valued fields. */ @RunWith(Parameterized.class) @TestForIssue(jiraKey = "HSEARCH-3391") -public class FieldSearchProjectionMultiValuedBaseIT { +public class FieldProjectionMultiValuedBaseIT { private static final List> supportedFieldTypes = FieldTypeDescriptor.getAll(); private static List> dataSets; @@ -84,7 +84,7 @@ public static void setup() { private final FieldTypeDescriptor fieldType; private final DataSet dataSet; - public FieldSearchProjectionMultiValuedBaseIT(TestedFieldStructure fieldStructure, + public FieldProjectionMultiValuedBaseIT(TestedFieldStructure fieldStructure, FieldTypeDescriptor fieldType, DataSet dataSet) { this.fieldStructure = fieldStructure; this.fieldType = fieldType; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionSingleValuedBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionSingleValuedBaseIT.java similarity index 97% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionSingleValuedBaseIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionSingleValuedBaseIT.java index 1d3e6ea967d..9a3a7b733f2 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionSingleValuedBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionSingleValuedBaseIT.java @@ -38,10 +38,10 @@ /** * Tests basic behavior of projections on a single-valued field, common to all supported types. *

- * See {@link FieldSearchProjectionMultiValuedBaseIT} for multi-valued fields. + * See {@link FieldProjectionMultiValuedBaseIT} for multi-valued fields. */ @RunWith(Parameterized.class) -public class FieldSearchProjectionSingleValuedBaseIT { +public class FieldProjectionSingleValuedBaseIT { private static final List> supportedFieldTypes = FieldTypeDescriptor.getAll(); private static List> dataSets; @@ -87,7 +87,7 @@ public static void setup() { private final FieldTypeDescriptor fieldType; private final DataSet dataSet; - public FieldSearchProjectionSingleValuedBaseIT(TestedFieldStructure fieldStructure, + public FieldProjectionSingleValuedBaseIT(TestedFieldStructure fieldStructure, FieldTypeDescriptor fieldType, DataSet dataSet) { this.fieldStructure = fieldStructure; this.fieldType = fieldType; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionTypeCheckingAndConversionIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionTypeCheckingAndConversionIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionTypeCheckingAndConversionIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionTypeCheckingAndConversionIT.java index 7066697bbe0..51b522de772 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionTypeCheckingAndConversionIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionTypeCheckingAndConversionIT.java @@ -47,7 +47,7 @@ * projections on field value. */ @RunWith(Parameterized.class) -public class FieldSearchProjectionTypeCheckingAndConversionIT { +public class FieldProjectionTypeCheckingAndConversionIT { private static final List> supportedFieldTypes = FieldTypeDescriptor.getAll(); @@ -94,7 +94,7 @@ public static void setup() { private final FieldTypeDescriptor fieldType; - public FieldSearchProjectionTypeCheckingAndConversionIT(FieldTypeDescriptor fieldType) { + public FieldProjectionTypeCheckingAndConversionIT(FieldTypeDescriptor fieldType) { this.fieldType = fieldType; } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionTypeIndependentIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionTypeIndependentIT.java similarity index 96% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionTypeIndependentIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionTypeIndependentIT.java index 2936d6cc850..00faedb870a 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldSearchProjectionTypeIndependentIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/FieldProjectionTypeIndependentIT.java @@ -28,9 +28,9 @@ * for projections on field value. *

* Behavior that is specific to the field type is tested elsewhere, - * e.g. {@link FieldSearchProjectionSingleValuedBaseIT} and {@link FieldSearchProjectionTypeCheckingAndConversionIT}. + * e.g. {@link FieldProjectionSingleValuedBaseIT} and {@link FieldProjectionTypeCheckingAndConversionIT}. */ -public class FieldSearchProjectionTypeIndependentIT { +public class FieldProjectionTypeIndependentIT { @ClassRule public static final SearchSetupHelper setupHelper = new SearchSetupHelper(); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/IdentifierSearchProjectionBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/IdentifierProjectionBaseIT.java similarity index 98% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/IdentifierSearchProjectionBaseIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/IdentifierProjectionBaseIT.java index 6f24d314b90..b059adbb7c6 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/IdentifierSearchProjectionBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/IdentifierProjectionBaseIT.java @@ -30,7 +30,7 @@ import org.junit.Rule; import org.junit.Test; -public class IdentifierSearchProjectionBaseIT { +public class IdentifierProjectionBaseIT { @Rule public final SearchSetupHelper setupHelper = new SearchSetupHelper(); @@ -52,7 +52,7 @@ public class IdentifierSearchProjectionBaseIT { private final String[] compatibleIndexIds = new String[3]; private final String[] compatibleIndexNames = new String[3]; - public IdentifierSearchProjectionBaseIT() { + public IdentifierProjectionBaseIT() { initValues(); } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java index 033401bc594..8a75c48e82d 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java @@ -57,7 +57,7 @@ import org.mockito.quality.Strictness; /** - * Generic tests for projections. More specific tests can be found in other classes, such as {@link FieldSearchProjectionSingleValuedBaseIT}. + * Generic tests for projections. More specific tests can be found in other classes, such as {@link FieldProjectionSingleValuedBaseIT}. */ @SuppressWarnings("unchecked") // Mocking parameterized types public class SearchProjectionIT { diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/query/SearchQueryResultLoadingOrTransformingIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/query/SearchQueryResultLoadingOrTransformingIT.java index 3458130dde5..cf6bbb29302 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/query/SearchQueryResultLoadingOrTransformingIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/query/SearchQueryResultLoadingOrTransformingIT.java @@ -366,18 +366,16 @@ public void select_hitTransformer() { StubMappingScope scope = index.createScope(); SearchQuery query = scope.query() - .select( f -> - f.composite( - hitTransformerMock, - f.field( "string", String.class ).toProjection(), - f.field( "string_analyzed", String.class ).toProjection(), - f.field( "integer", Integer.class ).toProjection(), - f.field( "localDate", LocalDate.class ).toProjection(), - f.field( "geoPoint", GeoPoint.class ).toProjection(), - f.documentReference().toProjection(), - f.entityReference().toProjection(), - f.entity().toProjection() - ) + .select( f -> f.composite() + .add( f.field( "string", String.class ), + f.field( "string_analyzed", String.class ), + f.field( "integer", Integer.class ), + f.field( "localDate", LocalDate.class ), + f.field( "geoPoint", GeoPoint.class ), + f.documentReference(), + f.entityReference(), + f.entity() ) + .transformList( hitTransformerMock ) ) .where( f -> f.matchAll() ) .toQuery(); @@ -428,14 +426,12 @@ public void select_hitTransformer_referencesTransformer_entityLoading() { GenericStubMappingScope scope = index.createGenericScope(); SearchQuery query = scope.query( loadingContextMock ) - .select( f -> - f.composite( - hitTransformerMock, - f.field( "string", String.class ).toProjection(), + .select( f -> f.composite() + .add( f.field( "string", String.class ).toProjection(), f.documentReference().toProjection(), f.entityReference().toProjection(), - f.entity().toProjection() - ) + f.entity().toProjection() ) + .transformList( hitTransformerMock ) ) .where( f -> f.matchAll() ) .toQuery(); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/CompositeSearchSortIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/CompositeSortIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/CompositeSearchSortIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/CompositeSortIT.java index 52f50333ab5..4d33b734941 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/CompositeSearchSortIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/CompositeSortIT.java @@ -33,7 +33,7 @@ import org.junit.Rule; import org.junit.Test; -public class CompositeSearchSortIT { +public class CompositeSortIT { private static final String DOCUMENT_1 = "1"; private static final String DOCUMENT_2 = "2"; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortBaseIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortBaseIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortBaseIT.java index 81c90acbfaf..1ab193b646c 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortBaseIT.java @@ -50,7 +50,7 @@ * Tests basic behavior of sorts by distance. */ @RunWith(Parameterized.class) -public class DistanceSearchSortBaseIT { +public class DistanceSortBaseIT { private static final GeoPointFieldTypeDescriptor fieldType = GeoPointFieldTypeDescriptor.INSTANCE; private static final Set> supportedFieldTypes = Collections.singleton( fieldType ); @@ -112,7 +112,7 @@ public static void setup() { private final DataSet dataSetForAsc; private final DataSet dataSetForDesc; - public DistanceSearchSortBaseIT(TestedFieldStructure fieldStructure, SortMode sortMode, + public DistanceSortBaseIT(TestedFieldStructure fieldStructure, SortMode sortMode, DataSet dataSetForAsc, DataSet dataSetForDesc) { this.fieldStructure = fieldStructure; this.sortMode = sortMode; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortFilteringSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortFilteringSpecificsIT.java similarity index 98% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortFilteringSpecificsIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortFilteringSpecificsIT.java index 120a5c43587..26810b1355b 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortFilteringSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortFilteringSpecificsIT.java @@ -33,9 +33,9 @@ /** * Tests behavior related to * {@link org.hibernate.search.engine.search.sort.dsl.SortFilterStep#filter(Function) filtering} - * that is not tested in {@link DistanceSearchSortBaseIT}. + * that is not tested in {@link DistanceSortBaseIT}. */ -public class DistanceSearchSortFilteringSpecificsIT { +public class DistanceSortFilteringSpecificsIT { @ClassRule public static SearchSetupHelper setupHelper = new SearchSetupHelper(); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortTypeCheckingAndConversionIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortTypeCheckingAndConversionIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortTypeCheckingAndConversionIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortTypeCheckingAndConversionIT.java index e25b411945c..025a64cb768 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortTypeCheckingAndConversionIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortTypeCheckingAndConversionIT.java @@ -52,7 +52,7 @@ * Tests behavior related to type checking and type conversion of DSL arguments * for sorts by field value. */ -public class DistanceSearchSortTypeCheckingAndConversionIT { +public class DistanceSortTypeCheckingAndConversionIT { private static final GeoPointFieldTypeDescriptor fieldType = GeoPointFieldTypeDescriptor.INSTANCE; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortUnsupportedTypesIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortUnsupportedTypesIT.java similarity index 95% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortUnsupportedTypesIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortUnsupportedTypesIT.java index 432e6702cc2..6943071a7fc 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSearchSortUnsupportedTypesIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/DistanceSortUnsupportedTypesIT.java @@ -34,7 +34,7 @@ * i.e. error messages. */ @RunWith(Parameterized.class) -public class DistanceSearchSortUnsupportedTypesIT { +public class DistanceSortUnsupportedTypesIT { private static Stream> unsupportedTypeDescriptors() { return FieldTypeDescriptor.getAll().stream() @@ -62,7 +62,7 @@ public static void setup() { private final FieldTypeDescriptor fieldTypeDescriptor; - public DistanceSearchSortUnsupportedTypesIT(FieldTypeDescriptor fieldTypeDescriptor) { + public DistanceSortUnsupportedTypesIT(FieldTypeDescriptor fieldTypeDescriptor) { this.fieldTypeDescriptor = fieldTypeDescriptor; } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortBaseIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortBaseIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortBaseIT.java index f724185d9ef..9388e470f3c 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortBaseIT.java @@ -56,7 +56,7 @@ * Tests basic behavior of sorts by field value common to all supported types. */ @RunWith(Parameterized.class) -public class FieldSearchSortBaseIT { +public class FieldSortBaseIT { private static Set> supportedFieldTypes; private static List> dataSets; @@ -124,7 +124,7 @@ public static void setup() { private final DataSet dataSetForAsc; private final DataSet dataSetForDesc; - public FieldSearchSortBaseIT(TestedFieldStructure fieldStructure, + public FieldSortBaseIT(TestedFieldStructure fieldStructure, FieldTypeDescriptor fieldType, SortMode sortMode, DataSet dataSetForAsc, DataSet dataSetForDesc) { this.fieldStructure = fieldStructure; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortFilteringSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortFilteringSpecificsIT.java similarity index 97% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortFilteringSpecificsIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortFilteringSpecificsIT.java index fd731ea848d..bb612a56ff4 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortFilteringSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortFilteringSpecificsIT.java @@ -38,10 +38,10 @@ /** * Tests behavior related to * {@link org.hibernate.search.engine.search.sort.dsl.SortFilterStep#filter(Function) filtering} - * that is not tested in {@link FieldSearchSortBaseIT}. + * that is not tested in {@link FieldSortBaseIT}. */ @RunWith(Parameterized.class) -public class FieldSearchSortFilteringSpecificsIT { +public class FieldSortFilteringSpecificsIT { private static Stream> supportedTypeDescriptors() { return FieldTypeDescriptor.getAll().stream() @@ -69,7 +69,7 @@ public static void setup() { private final FieldTypeDescriptor fieldTypeDescriptor; - public FieldSearchSortFilteringSpecificsIT(FieldTypeDescriptor fieldTypeDescriptor) { + public FieldSortFilteringSpecificsIT(FieldTypeDescriptor fieldTypeDescriptor) { this.fieldTypeDescriptor = fieldTypeDescriptor; } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortScaledSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortScaledSpecificsIT.java similarity index 98% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortScaledSpecificsIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortScaledSpecificsIT.java index 14a9927656f..f5e2f19a1df 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortScaledSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortScaledSpecificsIT.java @@ -24,7 +24,7 @@ import org.junit.ClassRule; import org.junit.Test; -public class FieldSearchSortScaledSpecificsIT { +public class FieldSortScaledSpecificsIT { @ClassRule public static SearchSetupHelper setupHelper = new SearchSetupHelper(); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortTypeCheckingAndConversionIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortTypeCheckingAndConversionIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortTypeCheckingAndConversionIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortTypeCheckingAndConversionIT.java index e7e8c18fe7a..3847bfe3467 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortTypeCheckingAndConversionIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortTypeCheckingAndConversionIT.java @@ -58,7 +58,7 @@ * for sorts by field value. */ @RunWith(Parameterized.class) -public class FieldSearchSortTypeCheckingAndConversionIT { +public class FieldSortTypeCheckingAndConversionIT { private static final List> supportedFieldTypes = new ArrayList<>(); @@ -117,7 +117,7 @@ public static void setup() { private final FieldTypeDescriptor fieldTypeDescriptor; - public FieldSearchSortTypeCheckingAndConversionIT(FieldTypeDescriptor fieldTypeDescriptor) { + public FieldSortTypeCheckingAndConversionIT(FieldTypeDescriptor fieldTypeDescriptor) { this.fieldTypeDescriptor = fieldTypeDescriptor; } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortTypeIndependentIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortTypeIndependentIT.java similarity index 96% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortTypeIndependentIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortTypeIndependentIT.java index 55fa5032c56..a1205b1c82a 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortTypeIndependentIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortTypeIndependentIT.java @@ -26,9 +26,9 @@ * for sorts by field value. *

* Behavior that is specific to the field type is tested elsewhere, - * e.g. {@link FieldSearchSortBaseIT} and {@link FieldSearchSortUnsupportedTypesIT}. + * e.g. {@link FieldSortBaseIT} and {@link FieldSortUnsupportedTypesIT}. */ -public class FieldSearchSortTypeIndependentIT { +public class FieldSortTypeIndependentIT { @Rule public final SearchSetupHelper setupHelper = new SearchSetupHelper(); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortUnsupportedTypesIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortUnsupportedTypesIT.java similarity index 96% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortUnsupportedTypesIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortUnsupportedTypesIT.java index ff83f033cf4..95598b2a740 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSearchSortUnsupportedTypesIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/FieldSortUnsupportedTypesIT.java @@ -35,7 +35,7 @@ * i.e. error messages. */ @RunWith(Parameterized.class) -public class FieldSearchSortUnsupportedTypesIT { +public class FieldSortUnsupportedTypesIT { private static Stream> unsupportedTypeDescriptors() { return FieldTypeDescriptor.getAll().stream() @@ -63,7 +63,7 @@ public static void setup() { private final FieldTypeDescriptor fieldTypeDescriptor; - public FieldSearchSortUnsupportedTypesIT(FieldTypeDescriptor fieldTypeDescriptor) { + public FieldSortUnsupportedTypesIT(FieldTypeDescriptor fieldTypeDescriptor) { this.fieldTypeDescriptor = fieldTypeDescriptor; } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/SearchSortIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/SearchSortIT.java index ef95c1c7933..45fcc2d889a 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/SearchSortIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/sort/SearchSortIT.java @@ -45,7 +45,7 @@ /** * Generic tests for sorts. More specific tests can be found in other classes, - * such as {@link FieldSearchSortBaseIT} or {@link DistanceSearchSortBaseIT}. + * such as {@link FieldSortBaseIT} or {@link DistanceSortBaseIT}. */ public class SearchSortIT { diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchProjectionComplexCasesIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceProjectionComplexCasesIT.java similarity index 91% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchProjectionComplexCasesIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceProjectionComplexCasesIT.java index 7249c7b7574..8a14c57bad8 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchProjectionComplexCasesIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceProjectionComplexCasesIT.java @@ -13,8 +13,8 @@ import org.hibernate.search.engine.spatial.DistanceUnit; import org.hibernate.search.engine.spatial.GeoPoint; -import org.hibernate.search.integrationtest.backend.tck.search.predicate.AbstractSpatialWithinSearchPredicateIT; -import org.hibernate.search.integrationtest.backend.tck.search.projection.DistanceSearchProjectionSingleValuedBaseIT; +import org.hibernate.search.integrationtest.backend.tck.search.predicate.AbstractSpatialWithinPredicateIT; +import org.hibernate.search.integrationtest.backend.tck.search.projection.DistanceProjectionSingleValuedBaseIT; import org.hibernate.search.util.impl.integrationtest.common.assertion.TestComparators; import org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMappingScope; @@ -22,13 +22,13 @@ import org.assertj.core.api.ListAssert; -public class DistanceSearchProjectionComplexCasesIT extends AbstractSpatialWithinSearchPredicateIT { +public class DistanceProjectionComplexCasesIT extends AbstractSpatialWithinPredicateIT { private static final Comparator APPROX_M_COMPARATOR = TestComparators.approximateDouble( 10.0 ); private static final Comparator APPROX_KM_COMPARATOR = TestComparators.approximateDouble( 0.010 ); /** - * See also {@link DistanceSearchProjectionSingleValuedBaseIT#several()}. + * See also {@link DistanceProjectionSingleValuedBaseIT#several()}. *

* The main difference is that we're targeting multiple fields here. */ @@ -75,7 +75,7 @@ public void several() { } /** - * See also {@link DistanceSearchProjectionSingleValuedBaseIT#sortable_withSort()}. + * See also {@link DistanceProjectionSingleValuedBaseIT#sortable_withSort()}. *

* The main difference is that we're composing multiple sorts here. */ diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchSearchableSortableIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchableSortableIT.java similarity index 99% rename from integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchSearchableSortableIT.java rename to integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchableSortableIT.java index 3a15dfad372..5b3147516a7 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchSearchableSortableIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/spatial/DistanceSearchableSortableIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; -public class DistanceSearchSearchableSortableIT { +public class DistanceSearchableSortableIT { private static final String OURSON_QUI_BOIT_ID = "ourson qui boit"; private static final GeoPoint OURSON_QUI_BOIT_GEO_POINT = GeoPoint.of( 45.7705687, 4.835233 ); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TestedFieldStructure.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TestedFieldStructure.java index cefd476f453..b00ad448a84 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TestedFieldStructure.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TestedFieldStructure.java @@ -11,6 +11,8 @@ import java.util.List; import java.util.Objects; +import org.hibernate.search.integrationtest.backend.tck.search.sort.FieldSortBaseIT; + /** * Represents the structure of a tested field: located at the root or in a nested document, * single-valued or multi-valued, ... @@ -23,7 +25,7 @@ * You need set up your test to create one field per structure, * and then query the "fieldStructure" object in your test instance to target a different field * based on that. - * See for example {@link org.hibernate.search.integrationtest.backend.tck.search.sort.FieldSearchSortBaseIT}. + * See for example {@link FieldSortBaseIT}. */ public class TestedFieldStructure { diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/work/IndexingFieldTypesIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/work/IndexingFieldTypesIT.java index fb29c3c9c6e..6b5949a339f 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/work/IndexingFieldTypesIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/work/IndexingFieldTypesIT.java @@ -92,11 +92,10 @@ public void withReference() { for ( int i = 0; i < values.size(); i++ ) { SearchQuery> query = scope.query() - .select( f -> f.composite( - (id, val) -> new IdAndValue<>( id, val ), - f.id( String.class ), - f.field( absoluteFieldPath, typeDescriptor.getJavaType() ) - ) ) + .select( f -> f.composite() + .add( f.id( String.class ), + f.field( absoluteFieldPath, typeDescriptor.getJavaType() ) ) + .transform( (id, val) -> new IdAndValue<>( id, val ) ) ) .where( f -> f.matchAll() ) .toQuery(); @@ -132,11 +131,10 @@ public void withPath() { for ( int i = 0; i < values.size(); i++ ) { SearchQuery> query = scope.query() - .select( f -> f.composite( - (ref, val) -> new IdAndValue<>( ref.id(), val ), - f.entityReference(), - f.field( absoluteFieldPath, typeDescriptor.getJavaType() ) - ) ) + .select( f -> f.composite() + .add( f.entityReference(), + f.field( absoluteFieldPath, typeDescriptor.getJavaType() ) ) + .transform( (ref, val) -> new IdAndValue<>( ref.id(), val ) ) ) .where( f -> f.matchAll() ) .toQuery(); @@ -179,11 +177,10 @@ public void dynamic_withPath() { for ( int i = 0; i < values.size(); i++ ) { SearchQuery> query = scope.query() - .select( f -> f.composite( - (ref, val) -> new IdAndValue<>( ref.id(), val ), - f.entityReference(), - f.field( absoluteFieldPath, typeDescriptor.getJavaType() ) - ) ) + .select( f -> f.composite() + .add( f.entityReference(), + f.field( absoluteFieldPath, typeDescriptor.getJavaType() ) ) + .transform( (ref, val) -> new IdAndValue<>( ref.id(), val ) ) ) .where( f -> f.matchAll() ) .toQuery(); diff --git a/integrationtest/mapper/orm/src/test/java/org/hibernate/search/integrationtest/mapper/orm/search/SearchQueryBaseIT.java b/integrationtest/mapper/orm/src/test/java/org/hibernate/search/integrationtest/mapper/orm/search/SearchQueryBaseIT.java index 7d014555a99..afbeb84a0f0 100644 --- a/integrationtest/mapper/orm/src/test/java/org/hibernate/search/integrationtest/mapper/orm/search/SearchQueryBaseIT.java +++ b/integrationtest/mapper/orm/src/test/java/org/hibernate/search/integrationtest/mapper/orm/search/SearchQueryBaseIT.java @@ -546,17 +546,12 @@ public void select_lambda() { SearchSession searchSession = Search.session( session ); SearchQuery query = searchSession.search( Book.class ) - .select( f -> - f.composite( - Book_Author_Score::new, - f.composite( - Book_Author::new, - f.entity().toProjection(), - f.field( "author.name", String.class ).toProjection() - ).toProjection(), - f.score().toProjection() - ) - ) + .select( f -> f.composite() + .add( f.composite() + .add( f.entity(), f.field( "author.name", String.class ) ) + .transform( Book_Author::new ), + f.score() ) + .transform( Book_Author_Score::new ) ) .where( f -> f.matchAll() ) .toQuery(); @@ -594,16 +589,12 @@ public void select_compositeAndLoading() { SearchSession searchSession = Search.session( session ); SearchQuery query = searchSession.search( Book.class ) - .select( f -> - f.composite( - Book_Author_Score::new, - f.composite( - Book_Author::new, - f.entity(), - f.field( "author.name", String.class ) - ), - f.score() - ) + .select( f -> f.composite() + .add( f.composite() + .add( f.entity(), f.field( "author.name", String.class ) ) + .transform( Book_Author::new ), + f.score() ) + .transform( Book_Author_Score::new ) ) .where( f -> f.matchAll() ) .toQuery(); diff --git a/integrationtest/v5migrationhelper/engine/src/test/java/org/hibernate/search/testsupport/migration/V5MigrationJavaBeanSearchScopeAdapter.java b/integrationtest/v5migrationhelper/engine/src/test/java/org/hibernate/search/testsupport/migration/V5MigrationJavaBeanSearchScopeAdapter.java index d4475eb19a7..2c0c052adf0 100644 --- a/integrationtest/v5migrationhelper/engine/src/test/java/org/hibernate/search/testsupport/migration/V5MigrationJavaBeanSearchScopeAdapter.java +++ b/integrationtest/v5migrationhelper/engine/src/test/java/org/hibernate/search/testsupport/migration/V5MigrationJavaBeanSearchScopeAdapter.java @@ -56,13 +56,16 @@ public SearchSortFactory sort() { @Override public SearchProjection idProjection() { SearchProjectionFactory factory = delegate.projection(); - return factory.composite( EntityReference::id, factory.entityReference() ).toProjection(); + // Not using factory.id() because that one throws an exception if IDs have inconsistent types. + return factory.composite().add( factory.entityReference() ) + .transform( EntityReference::id ).toProjection(); } @Override public SearchProjection> objectClassProjection() { SearchProjectionFactory factory = delegate.projection(); - return factory.composite( EntityReference::type, factory.entityReference() ).toProjection(); + return factory.composite().add( factory.entityReference() ) + .transform( EntityReference::type ).toProjection(); } @Override diff --git a/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/engine/impl/HSQueryImpl.java b/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/engine/impl/HSQueryImpl.java index 6c919d98200..236812a0402 100644 --- a/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/engine/impl/HSQueryImpl.java +++ b/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/engine/impl/HSQueryImpl.java @@ -250,10 +250,13 @@ private SearchProjection createCompositeProjection() { } if ( tupleTransformer != null ) { - return factory.composite( list -> tupleTransformer.transform( list.toArray(), projectedFields ), projections ).toProjection(); + return factory.composite() + .add( projections ) + .transformList( list -> tupleTransformer.transform( list.toArray(), projectedFields ) ) + .toProjection(); } else { - return factory.composite( List::toArray, projections ).toProjection(); + return factory.composite().add( projections ).transformList( List::toArray ).toProjection(); } } @@ -262,7 +265,7 @@ private SearchProjection createProjection(String field) { if ( field == null ) { // Hack to return null when a null field name is requested, // which is what Search 5 used to do... - return factory.composite( ignored -> null, factory.documentReference() ).toProjection(); + return factory.composite().add( factory.documentReference() ).transform( ignored -> null ).toProjection(); } switch ( field ) { case ProjectionConstants.THIS: diff --git a/v5migrationhelper/orm/src/main/java/org/hibernate/search/FullTextQuery.java b/v5migrationhelper/orm/src/main/java/org/hibernate/search/FullTextQuery.java index 7b2c1e919f8..7719bcaf301 100644 --- a/v5migrationhelper/orm/src/main/java/org/hibernate/search/FullTextQuery.java +++ b/v5migrationhelper/orm/src/main/java/org/hibernate/search/FullTextQuery.java @@ -20,7 +20,6 @@ import org.hibernate.graph.RootGraph; import org.hibernate.query.Query; import org.hibernate.query.spi.QueryImplementor; -import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.engine.search.query.dsl.SearchQueryOptionsStep; @@ -58,7 +57,7 @@ public interface FullTextQuery extends org.hibernate.search.jpa.FullTextQuery, Q * create a search query with {@link SearchSession#search(Class)}, * and define your projections using {@link SearchQuerySelectStep#select(Function)}. * See in particular the composite projection, which allows applying a function to another projection: - * {@link SearchProjectionFactory#composite(Function, ProjectionFinalStep)}. + * {@link SearchProjectionFactory#composite()}. * Refer to the migration guide for more information. */ @Deprecated diff --git a/v5migrationhelper/orm/src/main/java/org/hibernate/search/jpa/FullTextQuery.java b/v5migrationhelper/orm/src/main/java/org/hibernate/search/jpa/FullTextQuery.java index b66007609c9..6af15cf5a7b 100644 --- a/v5migrationhelper/orm/src/main/java/org/hibernate/search/jpa/FullTextQuery.java +++ b/v5migrationhelper/orm/src/main/java/org/hibernate/search/jpa/FullTextQuery.java @@ -20,7 +20,6 @@ import org.hibernate.search.backend.lucene.LuceneExtension; import org.hibernate.search.engine.ProjectionConstants; import org.hibernate.search.engine.search.aggregation.AggregationKey; -import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.engine.search.query.SearchQueryExtension; @@ -169,7 +168,7 @@ public interface FullTextQuery extends Query, ProjectionConstants { * create a search query with {@link SearchSession#search(Class)}, * and define your projections using {@link SearchQuerySelectStep#select(Function)}. * See in particular the composite projection, which allows applying a function to another projection: - * {@link SearchProjectionFactory#composite(Function, ProjectionFinalStep)}. + * {@link SearchProjectionFactory#composite()}. * Refer to the migration guide for more information. */ @Deprecated diff --git a/v5migrationhelper/orm/src/main/java/org/hibernate/search/scope/impl/V5MigrationOrmSearchScopeAdapter.java b/v5migrationhelper/orm/src/main/java/org/hibernate/search/scope/impl/V5MigrationOrmSearchScopeAdapter.java index d5dee290aa1..c6a4f660cd1 100644 --- a/v5migrationhelper/orm/src/main/java/org/hibernate/search/scope/impl/V5MigrationOrmSearchScopeAdapter.java +++ b/v5migrationhelper/orm/src/main/java/org/hibernate/search/scope/impl/V5MigrationOrmSearchScopeAdapter.java @@ -56,13 +56,16 @@ public SearchSortFactory sort() { @Override public SearchProjection idProjection() { SearchProjectionFactory factory = delegate.projection(); - return factory.composite( EntityReference::id, factory.entityReference() ).toProjection(); + // Not using factory.id() because that one throws an exception if IDs have inconsistent types. + return factory.composite().add( factory.entityReference() ) + .transform( EntityReference::id ).toProjection(); } @Override public SearchProjection> objectClassProjection() { SearchProjectionFactory factory = delegate.projection(); - return factory.composite( EntityReference::type, factory.entityReference() ).toProjection(); + return factory.composite().add( factory.entityReference() ) + .transform( EntityReference::type ).toProjection(); } @Override