From 1cc780cc1ea8fd65bbbe2a5069d108eed7dab86a Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 9 May 2024 17:48:57 +0200 Subject: [PATCH] HSEARCH-3319 Add references to the DSL --- ...mmonQueryStringPredicateFieldMoreStep.java | 55 ++- .../CommonQueryStringPredicateFieldStep.java | 58 +++- .../dsl/ExistsPredicateFieldStep.java | 16 +- .../predicate/dsl/KnnPredicateFieldStep.java | 4 + .../dsl/KnnPredicateVectorGenericStep.java | 19 ++ .../MatchPredicateFieldMoreGenericStep.java | 56 ++++ .../dsl/MatchPredicateFieldMoreStep.java | 32 +- .../dsl/MatchPredicateFieldStep.java | 43 ++- .../MatchPredicateMatchingGenericStep.java | 26 ++ .../dsl/MatchPredicateMatchingStep.java | 6 +- .../dsl/NestedPredicateFieldStep.java | 14 + .../dsl/PhrasePredicateFieldMoreStep.java | 51 ++- .../dsl/PhrasePredicateFieldStep.java | 56 +++- .../QueryStringPredicateFieldMoreStep.java | 8 +- .../dsl/QueryStringPredicateFieldStep.java | 6 +- .../RangePredicateFieldMoreGenericStep.java | 60 ++++ .../dsl/RangePredicateFieldMoreStep.java | 8 +- .../dsl/RangePredicateFieldStep.java | 45 ++- .../RangePredicateMatchingGenericStep.java | 117 +++++++ .../dsl/RangePredicateMatchingStep.java | 3 +- .../predicate/dsl/SearchPredicateFactory.java | 29 +- ...mpleQueryStringPredicateFieldMoreStep.java | 8 +- .../SimpleQueryStringPredicateFieldStep.java | 8 +- .../AbstractMatchPredicateFieldMoreStep.java | 312 ++++++++++++++++++ .../AbstractRangePredicateFieldMoreStep.java | 273 +++++++++++++++ .../impl/ExistsPredicateFieldStepImpl.java | 4 +- .../dsl/impl/KnnPredicateFieldStepImpl.java | 27 +- .../impl/MatchPredicateFieldMoreStepImpl.java | 171 ---------- .../dsl/impl/MatchPredicateFieldStepImpl.java | 19 +- .../PhrasePredicateFieldMoreStepImpl.java | 36 +- .../impl/PhrasePredicateFieldStepImpl.java | 11 +- ...QueryStringPredicateFieldMoreStepImpl.java | 10 +- .../QueryStringPredicateFieldStepImpl.java | 8 +- .../impl/RangePredicateFieldMoreStepImpl.java | 116 ------- .../dsl/impl/RangePredicateFieldStepImpl.java | 24 +- ...QueryStringPredicateFieldMoreStepImpl.java | 11 +- ...mpleQueryStringPredicateFieldStepImpl.java | 8 +- .../spi/AbstractSearchPredicateFactory.java | 24 +- .../dsl/ExtendedSearchProjectionFactory.java | 7 + .../dsl/SearchProjectionFactory.java | 76 +++++ .../sort/dsl/ExtendedSearchSortFactory.java | 18 + ...ldSortMissingValueBehaviorGenericStep.java | 70 ++++ .../FieldSortMissingValueBehaviorStep.java | 42 +-- .../sort/dsl/FieldSortOptionsGenericStep.java | 38 +++ .../search/sort/dsl/FieldSortOptionsStep.java | 10 +- .../search/sort/dsl/SearchSortFactory.java | 66 ++++ .../impl/GenericFieldSortOptionsStepImpl.java | 114 +++++++ .../dsl/spi/AbstractSearchSortFactory.java | 9 + ...bstractBaseQueryStringPredicateBaseIT.java | 42 +-- ...ctBaseQueryStringPredicateSpecificsIT.java | 2 +- .../predicate/QueryStringPredicateBaseIT.java | 4 +- .../QueryStringPredicateSpecificsIT.java | 5 +- .../SimpleQueryStringPredicateBaseIT.java | 5 +- ...SimpleQueryStringPredicateSpecificsIT.java | 4 +- .../ObjectProjectionSpecificsIT.java | 2 +- ...tiFieldsSimpleQueryStringQueryBuilder.java | 4 +- 56 files changed, 1795 insertions(+), 505 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateVectorGenericStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreGenericStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingGenericStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreGenericStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingGenericStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractMatchPredicateFieldMoreStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractRangePredicateFieldMoreStep.java delete mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldMoreStepImpl.java delete mode 100644 engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldMoreStepImpl.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorGenericStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsGenericStep.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/impl/GenericFieldSortOptionsStepImpl.java diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldMoreStep.java index f3f1bc2166a..f624396b285 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldMoreStep.java @@ -6,18 +6,25 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.TypedPredicateFieldReference; +import org.hibernate.search.util.common.annotation.Incubating; + /** * The step in a query string predicate definition, where the query string to match can be set * (see the superinterface {@link CommonQueryStringPredicateMatchingStep}), * or optional parameters for the last targeted field(s) can be set, * or more target fields can be added. * + * @param Scope root type. + * @param Type of the field references. * @param The "self" type (the actual exposed type of this step). * @param The type of the next step. */ public interface CommonQueryStringPredicateFieldMoreStep< - S extends CommonQueryStringPredicateFieldMoreStep, - N extends CommonQueryStringPredicateOptionsStep> + SR, + S extends CommonQueryStringPredicateFieldMoreStep, + N extends CommonQueryStringPredicateOptionsStep, + FR extends TypedPredicateFieldReference> extends CommonQueryStringPredicateMatchingStep, MultiFieldPredicateFieldBoostStep { /** @@ -54,4 +61,48 @@ default S field(String fieldPath) { */ S fields(String... fieldPaths); + /** + * Target the given field in the query string predicate, + * as an alternative to the already-targeted fields. + *

+ * Only text fields are supported. + *

+ * See {@link CommonQueryStringPredicateFieldStep#field(String)} for more information on targeted fields. + * + * @param field The field reference representing a path to the index field + * to apply the predicate on. + * @return The next step. + * + * @see CommonQueryStringPredicateFieldStep#field(String) + */ + @Incubating + @SuppressWarnings("unchecked") + default S field(FR field) { + return fields( field ); + } + + /** + * Target the given fields in the query string predicate, + * as an alternative to the already-targeted fields. + *

+ * Only text fields are supported. + *

+ * See {@link CommonQueryStringPredicateFieldStep#fields(String...)} for more information on targeted fields. + * + * @param fields The field reference representing paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see CommonQueryStringPredicateFieldStep#fields(String...) + */ + @Incubating + @SuppressWarnings("unchecked") + default S fields(FR... fields) { + String[] paths = new String[fields.length]; + for ( int i = 0; i < fields.length; i++ ) { + paths[i] = fields[i].absolutePath(); + } + return fields( paths ); + } + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldStep.java index e29d946a3f0..65767af0f87 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/CommonQueryStringPredicateFieldStep.java @@ -6,12 +6,20 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.TypedPredicateFieldReference; +import org.hibernate.search.util.common.annotation.Incubating; + /** * The initial step in a query string predicate definition, where the target field can be set. * + * @param Scope root type. + * @param Type of the field references. * @param The type of the next step. */ -public interface CommonQueryStringPredicateFieldStep> { +public interface CommonQueryStringPredicateFieldStep< + SR, + N extends CommonQueryStringPredicateFieldMoreStep, + FR extends TypedPredicateFieldReference> { /** * Target the given field in the query string predicate. @@ -51,4 +59,52 @@ default N field(String fieldPath) { */ N fields(String... fieldPaths); + + /** + * Target the given field in the query string predicate. + *

+ * Only text fields are supported. + *

+ * Multiple fields may be targeted by the same predicate: + * the predicate will match if any targeted field matches. + *

+ * When targeting multiple fields, those fields must have compatible types. + * Please refer to the reference documentation for more information. + * + * @param field The field reference representing a path to the index field + * to apply the predicate on. + * @return The next step. + */ + @Incubating + @SuppressWarnings("unchecked") + default N field(FR field) { + return fields( field ); + } + + /** + * Target the given fields in the query string predicate. + *

+ * Only text fields are supported. + *

+ * Equivalent to {@link #field(String)} followed by multiple calls to + * {@link #field(String)}, + * the only difference being that calls to {@link CommonQueryStringPredicateFieldMoreStep#boost(float)} + * and other field-specific settings on the returned step will only need to be done once + * and will apply to all the fields passed to this method. + * + * @param fields The field reference representing paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see #field(String) + */ + @Incubating + @SuppressWarnings("unchecked") + default N fields(FR... fields) { + String[] paths = new String[fields.length]; + for ( int i = 0; i < fields.length; i++ ) { + paths[i] = fields[i].absolutePath(); + } + return fields( paths ); + } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExistsPredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExistsPredicateFieldStep.java index b1d1080881c..2d6b5f25781 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExistsPredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExistsPredicateFieldStep.java @@ -6,13 +6,15 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.ExistsPredicateFieldReference; +import org.hibernate.search.util.common.annotation.Incubating; /** * The initial step in an "exists" predicate definition, where the target field can be set. * * @param The type of the next step. */ -public interface ExistsPredicateFieldStep> { +public interface ExistsPredicateFieldStep> { /** * Target the given field in the "exists" predicate. @@ -23,4 +25,16 @@ public interface ExistsPredicateFieldSteppath to the index field + * to apply the predicate on. + * @return The next step. + */ + @Incubating + default N field(ExistsPredicateFieldReference field) { + return field( field.absolutePath() ); + } + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateFieldStep.java index 4cb9a85ece8..1fb575f893f 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateFieldStep.java @@ -6,6 +6,8 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.KnnPredicateFieldReference; + /** * The initial step in a "knn" predicate definition, where the target field can be set. * @param Scope root type. @@ -19,4 +21,6 @@ public interface KnnPredicateFieldStep { * @return The next step in the knn predicate DSL. */ KnnPredicateVectorStep field(String fieldPath); + + KnnPredicateVectorGenericStep field(KnnPredicateFieldReference field); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateVectorGenericStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateVectorGenericStep.java new file mode 100644 index 00000000000..e6b174479b0 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateVectorGenericStep.java @@ -0,0 +1,19 @@ +/* + * 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.predicate.dsl; + +/** + * The step in a "knn" predicate definition where the vector to match is defined. + */ +public interface KnnPredicateVectorGenericStep { + /** + * @param vector The vector from which to compute the distance to vectors in the indexed field. + * @return The next step in the knn predicate DSL. + */ + KnnPredicateOptionsStep matching(T vector); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreGenericStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreGenericStep.java new file mode 100644 index 00000000000..4faf8ec9de3 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreGenericStep.java @@ -0,0 +1,56 @@ +/* + * 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.predicate.dsl; + +/** + * The step in a "match" predicate definition where the value to match can be set + * (see the superinterface {@link MatchPredicateMatchingStep}), + * or optional parameters for the last targeted field(s) can be set, + * or more target fields can be added. + * + * @param The "self" type (the actual exposed type of this step). + * @param The type of the next step. + * @param The type of the match value. + * @param The type representing the fields. + */ +public interface MatchPredicateFieldMoreGenericStep< + S extends MatchPredicateFieldMoreGenericStep, + N extends MatchPredicateOptionsStep, + T, + V> + extends MatchPredicateMatchingGenericStep, MultiFieldPredicateFieldBoostStep { + + /** + * Target the given field in the match predicate, + * as an alternative to the already-targeted fields. + *

+ * See {@link MatchPredicateFieldStep#field(String)} for more information about targeting fields. + * + * @param field The field with a path to the index field + * to apply the predicate on. + * @return The next step. + * + * @see MatchPredicateFieldStep#field(String) + */ + S field(V field); + + /** + * Target the given fields in the match predicate, + * as an alternative to the already-targeted fields. + *

+ * See {@link MatchPredicateFieldStep#fields(String...)} for more information about targeting fields. + * + * @param fieldPaths The fields with paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see MatchPredicateFieldStep#fields(String...) + */ + @SuppressWarnings("unchecked") + S fields(V... fieldPaths); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreStep.java index bad25a3be8d..f958b4db8b5 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldMoreStep.java @@ -18,36 +18,6 @@ public interface MatchPredicateFieldMoreStep< S extends MatchPredicateFieldMoreStep, N extends MatchPredicateOptionsStep> - extends MatchPredicateMatchingStep, MultiFieldPredicateFieldBoostStep { - - /** - * Target the given field in the match predicate, - * as an alternative to the already-targeted fields. - *

- * See {@link MatchPredicateFieldStep#field(String)} for more information about targeting fields. - * - * @param fieldPath The path to the index field - * to apply the predicate on. - * @return The next step. - * - * @see MatchPredicateFieldStep#field(String) - */ - default S field(String fieldPath) { - return fields( fieldPath ); - } - - /** - * Target the given fields in the match predicate, - * as an alternative to the already-targeted fields. - *

- * See {@link MatchPredicateFieldStep#fields(String...)} for more information about targeting fields. - * - * @param fieldPaths The paths to the index fields - * to apply the predicate on. - * @return The next step. - * - * @see MatchPredicateFieldStep#fields(String...) - */ - S fields(String... fieldPaths); + extends MatchPredicateMatchingStep, MatchPredicateFieldMoreGenericStep { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldStep.java index 54f81b944b8..a4891b17c45 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateFieldStep.java @@ -6,11 +6,12 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.MatchPredicateFieldReference; /** * The initial step in a "match" predicate definition, where the target field can be set. */ -public interface MatchPredicateFieldStep> { +public interface MatchPredicateFieldStep> { /** * Target the given field in the match predicate. @@ -33,7 +34,7 @@ default N field(String fieldPath) { * Target the given fields in the match predicate. *

* Equivalent to {@link #field(String)} followed by multiple calls to - * {@link MatchPredicateFieldMoreStep#field(String)}, + * {@link MatchPredicateFieldMoreStep#field(Object)}, * the only difference being that calls to {@link MatchPredicateFieldMoreStep#boost(float)} * and other field-specific settings on the returned step will only need to be done once * and will apply to all the fields passed to this method. @@ -45,4 +46,42 @@ default N field(String fieldPath) { * @see #field(String) */ N fields(String... fieldPaths); + + /** + * Target the given field in the match predicate. + *

+ * Multiple fields may be targeted by the same predicate: + * the predicate will match if any targeted field matches. + *

+ * When targeting multiple fields, those fields must have compatible types. + * Please refer to the reference documentation for more information. + * + * @param fieldReference The field reference representing a path to the index field + * to apply the predicate on. + * @return The next step. + */ + @SuppressWarnings("unchecked") + default MatchPredicateFieldMoreGenericStep> field( + MatchPredicateFieldReference fieldReference) { + return fields( fieldReference ); + } + + /** + * Target the given fields in the match predicate. + *

+ * Equivalent to {@link #field(String)} followed by multiple calls to + * {@link MatchPredicateFieldMoreStep#field(Object)}, + * the only difference being that calls to {@link MatchPredicateFieldMoreStep#boost(float)} + * and other field-specific settings on the returned step will only need to be done once + * and will apply to all the fields passed to this method. + * + * @param fieldReferences The field references representing paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see #field(MatchPredicateFieldReference) + */ + @SuppressWarnings("unchecked") + MatchPredicateFieldMoreGenericStep> fields( + MatchPredicateFieldReference... fieldReferences); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingGenericStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingGenericStep.java new file mode 100644 index 00000000000..f1b325f5eb6 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingGenericStep.java @@ -0,0 +1,26 @@ +/* + * 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.predicate.dsl; + +/** + * The step in a "match" predicate definition where the value to match can be set. + * + * @param The type of the next step. + * @param The type of the match value. + */ +public interface MatchPredicateMatchingGenericStep, T> { + + /** + * Require at least one of the targeted fields to match the given value. + * + * @param value The value to match. + * The signature of this method defines this parameter as an {@code T}, + * but a specific type is expected depending on the targeted field. + * @return The next step. + */ + N matching(T value); +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingStep.java index badf899a97f..0167be5d240 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchPredicateMatchingStep.java @@ -13,7 +13,8 @@ * * @param The type of the next step. */ -public interface MatchPredicateMatchingStep> { +public interface MatchPredicateMatchingStep> + extends MatchPredicateMatchingGenericStep { /** * Require at least one of the targeted fields to match the given value. @@ -22,7 +23,7 @@ public interface MatchPredicateMatchingStep + * The selected field must have a {@link ObjectStructure#NESTED nested structure} in the targeted indexes. + * + * @param field The field reference representing a path to the object field + * to apply the predicate on. + * @return The next step. + */ + default N objectField(NestedPredicateFieldReference field) { + return objectField( field.absolutePath() ); + } + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldMoreStep.java index 4c5700c7e98..890fe7b34a6 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldMoreStep.java @@ -6,17 +6,22 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.PhrasePredicateFieldReference; +import org.hibernate.search.util.common.annotation.Incubating; + /** * The step in a "phrase" predicate definition where the phrase to match can be set * (see the superinterface {@link PhrasePredicateMatchingStep}), * or optional parameters for the last targeted field(s) can be set, * or more target fields can be added. * + * @param Scope root type. * @param The "self" type (the actual exposed type of this step). * @param The type of the next step. */ public interface PhrasePredicateFieldMoreStep< - S extends PhrasePredicateFieldMoreStep, + SR, + S extends PhrasePredicateFieldMoreStep, N extends PhrasePredicateOptionsStep> extends PhrasePredicateMatchingStep, MultiFieldPredicateFieldBoostStep { @@ -54,4 +59,48 @@ default S field(String fieldPath) { */ S fields(String... fieldPaths); + /** + * Target the given field in the phrase predicate, + * as an alternative to the already-targeted fields. + *

+ * Only text fields are supported. + *

+ * See {@link PhrasePredicateFieldStep#field(PhrasePredicateFieldReference)} for more information on targeted fields. + * + * @param field The field reference representing a path to the index field + * to apply the predicate on. + * @return The next step. + * + * @see PhrasePredicateFieldStep#field(PhrasePredicateFieldReference) + */ + @Incubating + @SuppressWarnings("unchecked") + default S field(PhrasePredicateFieldReference field) { + return fields( field ); + } + + /** + * Target the given fields in the phrase predicate, + * as an alternative to the already-targeted fields. + *

+ * Only text fields are supported. + *

+ * See {@link PhrasePredicateFieldStep#fields(PhrasePredicateFieldReference...)} for more information on targeted fields. + * + * @param fields The field references representing paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see PhrasePredicateFieldStep#fields(PhrasePredicateFieldReference...) + */ + @Incubating + @SuppressWarnings("unchecked") + default S fields(PhrasePredicateFieldReference... fields) { + String[] paths = new String[fields.length]; + for ( int i = 0; i < fields.length; i++ ) { + paths[i] = fields[i].absolutePath(); + } + return fields( paths ); + } + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldStep.java index 3778d88c54d..67c88a61615 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/PhrasePredicateFieldStep.java @@ -6,12 +6,16 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.PhrasePredicateFieldReference; +import org.hibernate.search.util.common.annotation.Incubating; + /** * The initial step in a "phrase" predicate definition, where the target field can be set. * + * @param Scope root type. * @param The type of the next step. */ -public interface PhrasePredicateFieldStep> { +public interface PhrasePredicateFieldStep> { /** * Target the given field in the phrase predicate. @@ -51,4 +55,54 @@ default N field(String fieldPath) { */ N fields(String... fieldPaths); + /** + * Target the given field in the phrase predicate. + *

+ * Only text fields are supported. + *

+ * Multiple fields may be targeted by the same predicate: + * the predicate will match if any targeted field matches. + *

+ * When targeting multiple fields, those fields must have compatible types. + * Please refer to the reference documentation for more information. + * + * @param field The field reference representing a path to the index field + * to apply the predicate on. + * @return The next step. + * + * @see PhrasePredicateFieldStep#field(PhrasePredicateFieldReference) + */ + @Incubating + @SuppressWarnings("unchecked") + default N field(PhrasePredicateFieldReference field) { + return fields( field ); + } + + /** + * Target the given fields in the phrase predicate. + *

+ * Only text fields are supported. + *

+ * Equivalent to {@link #field(PhrasePredicateFieldReference)} followed by multiple calls to + * {@link PhrasePredicateFieldMoreStep#field(PhrasePredicateFieldReference)}, + * the only difference being that calls to {@link PhrasePredicateFieldMoreStep#boost(float)} + * and other field-specific settings on the returned step will only need to be done once + * and will apply to all the fields passed to this method. + * + * @param fields The field references representing paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see PhrasePredicateFieldStep#fields(PhrasePredicateFieldReference...) + */ + @Incubating + @SuppressWarnings("unchecked") + default N fields(PhrasePredicateFieldReference... fields) { + String[] paths = new String[fields.length]; + for ( int i = 0; i < fields.length; i++ ) { + paths[i] = fields[i].absolutePath(); + } + return fields( paths ); + } + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldMoreStep.java index cd0a4033954..e25df9217ea 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldMoreStep.java @@ -6,18 +6,22 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.QueryStringPredicateFieldReference; + /** * The step in a "query string" predicate definition where the query string to match can be set * (see the superinterface {@link QueryStringPredicateMatchingStep}), * or optional parameters for the last targeted field(s) can be set, * or more target fields can be added. * + * @param Scope root type. * @param The "self" type (the actual exposed type of this step). * @param The type of the next step. */ public interface QueryStringPredicateFieldMoreStep< - S extends QueryStringPredicateFieldMoreStep, + SR, + S extends QueryStringPredicateFieldMoreStep, N extends QueryStringPredicateOptionsStep> - extends CommonQueryStringPredicateFieldMoreStep { + extends CommonQueryStringPredicateFieldMoreStep> { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldStep.java index be27b89af9c..42006c08544 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/QueryStringPredicateFieldStep.java @@ -6,12 +6,14 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.QueryStringPredicateFieldReference; + /** * The initial step in a "query string" predicate definition, where the target field can be set. * * @param The type of the next step. */ -public interface QueryStringPredicateFieldStep> - extends CommonQueryStringPredicateFieldStep { +public interface QueryStringPredicateFieldStep> + extends CommonQueryStringPredicateFieldStep> { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreGenericStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreGenericStep.java new file mode 100644 index 00000000000..a3ed7616e62 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreGenericStep.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.predicate.dsl; + +import org.hibernate.search.engine.search.reference.predicate.RangePredicateFieldReference; + +/** + * The step in a "range" predicate definition where the limits of the range to match can be set + * (see the superinterface {@link RangePredicateMatchingStep}), + * or optional parameters for the last targeted field(s) can be set, + * or more target fields can be added. + * + * @param Scope root type. + * @param The "self" type (the actual exposed type of this step). + * @param The type of the next step. + * @param The type representing the fields. + * @param The type of the boundary values. + */ +public interface RangePredicateFieldMoreGenericStep< + SR, + S extends RangePredicateFieldMoreGenericStep, + N extends RangePredicateOptionsStep, + V, + T> + extends RangePredicateMatchingGenericStep, MultiFieldPredicateFieldBoostStep { + + /** + * Target the given field in the range predicate, + * as an alternative to the already-targeted fields. + *

+ * See {@link RangePredicateFieldStep#field(RangePredicateFieldReference)} for more information about targeting fields. + * + * @param field The field with a path to the index field + * to apply the predicate on. + * @return The next step. + * + * @see RangePredicateFieldStep#field(RangePredicateFieldReference) + */ + S field(V field); + + /** + * Target the given fields in the range predicate, + * as an alternative to the already-targeted fields. + *

+ * See {@link RangePredicateFieldStep#fields(RangePredicateFieldReference...)} for more information about targeting fields. + * + * @param fields The fields with paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see RangePredicateFieldStep#fields(RangePredicateFieldReference...) + */ + @SuppressWarnings("unchecked") + S fields(V... fields); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreStep.java index e78715db486..728e93246dc 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldMoreStep.java @@ -12,13 +12,16 @@ * or optional parameters for the last targeted field(s) can be set, * or more target fields can be added. * + * @param Scope root type. * @param The "self" type (the actual exposed type of this step). * @param The type of the next step. */ public interface RangePredicateFieldMoreStep< - S extends RangePredicateFieldMoreStep, + SR, + S extends RangePredicateFieldMoreStep, N extends RangePredicateOptionsStep> - extends RangePredicateMatchingStep, MultiFieldPredicateFieldBoostStep { + extends RangePredicateFieldMoreGenericStep, + RangePredicateMatchingStep { /** * Target the given field in the range predicate, @@ -49,5 +52,4 @@ default S field(String fieldPath) { * @see RangePredicateFieldStep#fields(String...) */ S fields(String... fieldPaths); - } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldStep.java index 0083db6db3f..b79b3b44bb8 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateFieldStep.java @@ -6,13 +6,17 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.RangePredicateFieldReference; /** * The initial step in a "range" predicate definition, where the target field can be set. * + * @param Scope root type. * @param The type of the next step. */ -public interface RangePredicateFieldStep> { +public interface RangePredicateFieldStep< + SR, + N extends RangePredicateFieldMoreStep> { /** * Target the given field in the range predicate. @@ -47,4 +51,43 @@ default N field(String fieldPath) { * @see #field(String) */ N fields(String... fieldPaths); + + /** + * Target the given field in the range predicate. + *

+ * Multiple fields may be targeted by the same predicate: + * the predicate will match if any targeted field matches. + *

+ * When targeting multiple fields, those fields must have compatible types. + * Please refer to the reference documentation for more information. + * + * @param field The field reference representing a path to the index field + * to apply the predicate on. + * @return The next step. + */ + @SuppressWarnings("unchecked") + default RangePredicateFieldMoreGenericStep, T> field( + RangePredicateFieldReference field) { + return fields( field ); + } + + /** + * Target the given fields in the range predicate. + *

+ * Equivalent to {@link #field(RangePredicateFieldReference)} followed by multiple calls to + * {@link RangePredicateFieldMoreGenericStep#field(Object)}, + * the only difference being that calls to {@link RangePredicateFieldMoreStep#boost(float)} + * and other field-specific settings on the returned step will only need to be done once + * and will apply to all the fields passed to this method. + * + * @param fields The field references representing paths to the index fields + * to apply the predicate on. + * @return The next step. + * + * @see #field(RangePredicateFieldReference) + */ + @SuppressWarnings("unchecked") + RangePredicateFieldMoreGenericStep, T> fields( + RangePredicateFieldReference... fields); + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingGenericStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingGenericStep.java new file mode 100644 index 00000000000..9c1fcc6ecb4 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingGenericStep.java @@ -0,0 +1,117 @@ +/* + * 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.predicate.dsl; + +import org.hibernate.search.util.common.data.Range; +import org.hibernate.search.util.common.data.RangeBoundInclusion; + +/** + * The step in a "range" predicate definition where the range to match can be set. + * + * @param The type of the next step. + * @param The type of the boundary values. + */ +public interface RangePredicateMatchingGenericStep> { + + /** + * Require at least one of the targeted fields to be in the range + * defined by the given bounds. + * + * @param lowerBound The lower bound of the range. {@code null} means {@code -Infinity} (no lower bound). + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @param upperBound The upper bound of the range. {@code null} means {@code +Infinity} (no upper bound). + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @return The next step. + */ + default N between(T lowerBound, T upperBound) { + return range( Range.between( lowerBound, upperBound ) ); + } + + /** + * Require at least one of the targeted fields to be in the range + * defined by the given bounds. + * + * @param lowerBound The lower bound of the range. {@code null} means {@code -Infinity} (no lower bound). + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @param lowerBoundInclusion Whether the lower bound is included in the range or excluded. + * @param upperBound The upper bound of the range. {@code null} means {@code +Infinity} (no upper bound). + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @param upperBoundInclusion Whether the upper bound is included in the range or excluded. + * @return The next step. + */ + default N between(T lowerBound, RangeBoundInclusion lowerBoundInclusion, + T upperBound, RangeBoundInclusion upperBoundInclusion) { + return range( Range.between( lowerBound, lowerBoundInclusion, upperBound, upperBoundInclusion ) ); + } + + /** + * Require at least one of the targeted fields to be "greater than or equal to" the given value, + * with no limit as to how high it can be. + * + * @param lowerBoundValue The lower bound of the range, included. Must not be null. + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @return The next step. + */ + default N atLeast(T lowerBoundValue) { + return range( Range.atLeast( lowerBoundValue ) ); + } + + /** + * Require at least one of the targeted fields to be "strictly greater than" the given value, + * with no limit as to how high it can be. + * + * @param lowerBoundValue The lower bound of the range, excluded. Must not be null. + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @return The next step. + */ + default N greaterThan(T lowerBoundValue) { + return range( Range.greaterThan( lowerBoundValue ) ); + } + + /** + * Require at least one of the targeted fields to be "lesser than or equal to" the given value, + * with no limit as to how low it can be. + * + * @param upperBoundValue The upper bound of the range, included. Must not be null. + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @return The next step. + */ + default N atMost(T upperBoundValue) { + return range( Range.atMost( upperBoundValue ) ); + } + + /** + * Require at least one of the targeted fields to be "lesser than" the given value, + * with no limit as to how low it can be. + * + * @param upperBoundValue The upper bound of the range, excluded. Must not be null. + * The signature of this method defines this parameter as an {@link Object}, + * but a specific type is expected depending on the targeted field. + * @return The next step. + */ + default N lessThan(T upperBoundValue) { + return range( Range.lessThan( upperBoundValue ) ); + } + + /** + * Require at least one of the targeted fields to be in the given range. + * + * @param range The range to match. + * The signature of this method defines this parameter as a range with bounds of any type, + * but a specific type is expected depending on the targeted field. + * @return The next step. + */ + N range(Range range); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingStep.java index 9033f5231f0..a918b21bad4 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/RangePredicateMatchingStep.java @@ -15,7 +15,8 @@ * * @param The type of the next step. */ -public interface RangePredicateMatchingStep> { +public interface RangePredicateMatchingStep> + extends RangePredicateMatchingGenericStep { /** * Require at least one of the targeted fields to be in the range diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactory.java index 1d4550f5e60..98c7f9f86c5 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactory.java @@ -13,6 +13,7 @@ import org.hibernate.search.engine.search.common.BooleanOperator; import org.hibernate.search.engine.search.common.NamedValues; import org.hibernate.search.engine.search.predicate.SearchPredicate; +import org.hibernate.search.engine.search.reference.predicate.NestedPredicateFieldReference; import org.hibernate.search.util.common.SearchException; import org.hibernate.search.util.common.annotation.Incubating; @@ -165,7 +166,7 @@ SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, * @return The initial step of a DSL where the "match" predicate can be defined. * @see MatchPredicateFieldStep */ - MatchPredicateFieldStep match(); + MatchPredicateFieldStep match(); /** * Match documents where targeted fields have a value within lower and upper bounds. @@ -173,7 +174,7 @@ SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, * @return The initial step of a DSL where the "range" predicate can be defined. * @see RangePredicateFieldStep */ - RangePredicateFieldStep range(); + RangePredicateFieldStep range(); /** * Match documents where targeted fields have a value that contains a given phrase. @@ -181,7 +182,7 @@ SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, * @return The initial step of a DSL where the "phrase" predicate can be defined. * @see PhrasePredicateFieldStep */ - PhrasePredicateFieldStep phrase(); + PhrasePredicateFieldStep phrase(); /** * Match documents where targeted fields contain a term that matches a given pattern, @@ -235,6 +236,22 @@ SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, */ NestedPredicateClausesStep nested(String objectFieldPath); + /** + * Match documents where a {@link ObjectStructure#NESTED nested object} matches inner predicates + * to be defined in the next steps. + *

+ * The resulting nested predicate must match all inner clauses, + * similarly to an {@link #and() "and" predicate}. + * + * @param field The field reference representing a path to the object field + * to apply the predicate on. + * @return The initial step of a DSL where the "nested" predicate can be defined. + * @see NestedPredicateFieldStep + */ + default NestedPredicateClausesStep nested(NestedPredicateFieldReference field) { + return nested( field.absolutePath() ); + } + /** * Match documents according to a given query string, * with a simple query language adapted to end users. @@ -247,7 +264,7 @@ SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, * @return The initial step of a DSL where the "simple query string" predicate can be defined. * @see SimpleQueryStringPredicateFieldStep */ - SimpleQueryStringPredicateFieldStep simpleQueryString(); + SimpleQueryStringPredicateFieldStep simpleQueryString(); /** * Match documents according to a given query string, @@ -261,7 +278,7 @@ SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, * @return The initial step of a DSL where the "query string" predicate can be defined. * @see QueryStringPredicateFieldStep */ - QueryStringPredicateFieldStep queryString(); + QueryStringPredicateFieldStep queryString(); /** * Match documents where a given field exists. @@ -271,7 +288,7 @@ SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, * @return The initial step of a DSL where the "exists" predicate can be defined. * @see ExistsPredicateFieldStep */ - ExistsPredicateFieldStep exists(); + ExistsPredicateFieldStep exists(); /** * Access the different types of spatial predicates. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldMoreStep.java index 7a8c4e02ab3..b1c80212644 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldMoreStep.java @@ -6,18 +6,22 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.SimpleQueryStringPredicateFieldReference; + /** * The step in a "simple query string" predicate definition where the query string to match can be set * (see the superinterface {@link SimpleQueryStringPredicateMatchingStep}), * or optional parameters for the last targeted field(s) can be set, * or more target fields can be added. * + * @param Scope root type. * @param The "self" type (the actual exposed type of this step). * @param The type of the next step. */ public interface SimpleQueryStringPredicateFieldMoreStep< - S extends SimpleQueryStringPredicateFieldMoreStep, + SR, + S extends SimpleQueryStringPredicateFieldMoreStep, N extends SimpleQueryStringPredicateOptionsStep> - extends CommonQueryStringPredicateFieldMoreStep { + extends CommonQueryStringPredicateFieldMoreStep> { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldStep.java index 654833cb112..cbe330be09a 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleQueryStringPredicateFieldStep.java @@ -6,13 +6,15 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.engine.search.reference.predicate.SimpleQueryStringPredicateFieldReference; + /** * The initial step in a "simple query string" predicate definition, where the target field can be set. * + * @param Scope root type. * @param The type of the next step. */ -public interface SimpleQueryStringPredicateFieldStep> - extends CommonQueryStringPredicateFieldStep { - +public interface SimpleQueryStringPredicateFieldStep> + extends CommonQueryStringPredicateFieldStep> { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractMatchPredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractMatchPredicateFieldMoreStep.java new file mode 100644 index 00000000000..0aa9023bb80 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractMatchPredicateFieldMoreStep.java @@ -0,0 +1,312 @@ +/* + * 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.predicate.dsl.impl; + +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import org.hibernate.search.engine.logging.impl.Log; +import org.hibernate.search.engine.search.common.ValueConvert; +import org.hibernate.search.engine.search.common.spi.SearchIndexScope; +import org.hibernate.search.engine.search.predicate.SearchPredicate; +import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateFieldMoreGenericStep; +import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateFieldMoreStep; +import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateOptionsStep; +import org.hibernate.search.engine.search.predicate.dsl.MinimumShouldMatchConditionStep; +import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; +import org.hibernate.search.engine.search.predicate.spi.MatchPredicateBuilder; +import org.hibernate.search.engine.search.predicate.spi.MinimumShouldMatchBuilder; +import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; +import org.hibernate.search.engine.search.reference.predicate.MatchPredicateFieldReference; +import org.hibernate.search.util.common.impl.Contracts; +import org.hibernate.search.util.common.logging.impl.LoggerFactory; + +abstract class AbstractMatchPredicateFieldMoreStep< + CS extends AbstractMatchPredicateFieldMoreStep.GenericCommonState, + S extends AbstractMatchPredicateFieldMoreStep, + T, + V> + implements AbstractBooleanMultiFieldPredicateCommonState.FieldSetState { + + private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); + + protected final CS commonState; + + protected final Map predicateBuilders = new LinkedHashMap<>(); + + private Float fieldSetBoost; + + public static MatchPredicateFieldMoreStep create( + SearchPredicateDslContext dslContext, String[] fields) { + return new MatchPredicateFieldMoreStepString( + dslContext, + Arrays.asList( fields ) + ); + } + + public static MatchPredicateFieldMoreGenericStep> create( + SearchPredicateDslContext dslContext, MatchPredicateFieldReference[] fields) { + return new MatchPredicateFieldMoreStepFieldReference<>( + dslContext, + Arrays.asList( fields ) + ); + } + + protected AbstractMatchPredicateFieldMoreStep(CS commonState, List fieldPaths) { + this.commonState = commonState; + this.commonState.add( thisAsS() ); + SearchIndexScope scope = commonState.scope(); + for ( V fieldPath : fieldPaths ) { + predicateBuilders.put( fieldPath, scope.fieldQueryElement( fieldPath( fieldPath ), PredicateTypeKeys.MATCH ) ); + } + } + + protected abstract S thisAsS(); + + protected abstract String fieldPath(V field); + + public S boost(float boost) { + this.fieldSetBoost = boost; + return thisAsS(); + } + + @Override + public void contributePredicates(Consumer collector) { + for ( MatchPredicateBuilder predicateBuilder : predicateBuilders.values() ) { + // Perform last-minute changes, since it's the last call that will be made on this field set state + commonState.applyBoostAndConstantScore( fieldSetBoost, predicateBuilder ); + + collector.accept( predicateBuilder.build() ); + } + } + + private static class MatchPredicateFieldMoreStepString + extends + AbstractMatchPredicateFieldMoreStep + implements + MatchPredicateFieldMoreStep { + + MatchPredicateFieldMoreStepString(SearchPredicateDslContext dslContext, List fieldPaths) { + super( new CommonState( dslContext ), fieldPaths ); + } + + private MatchPredicateFieldMoreStepString(CommonState commonState, List fieldPaths) { + super( commonState, fieldPaths ); + } + + @Override + protected MatchPredicateFieldMoreStepString thisAsS() { + return this; + } + + @Override + protected String fieldPath(String field) { + return field; + } + + @Override + public MatchPredicateFieldMoreStepString field(String field) { + return new MatchPredicateFieldMoreStepString( commonState, Arrays.asList( field ) ); + } + + @Override + public MatchPredicateFieldMoreStepString fields(String... fieldPaths) { + return new MatchPredicateFieldMoreStepString( commonState, Arrays.asList( fieldPaths ) ); + } + + @Override + public CommonState matching(Object value, ValueConvert convert) { + return commonState.matching( value, convert ); + } + + + private static class CommonState extends GenericCommonState { + + CommonState(SearchPredicateDslContext dslContext) { + super( dslContext ); + } + + CommonState matching(Object value, ValueConvert convert) { + Contracts.assertNotNull( value, "value" ); + Contracts.assertNotNull( convert, "convert" ); + + for ( MatchPredicateFieldMoreStepString fieldSetState : getFieldSetStates() ) { + for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders.values() ) { + predicateBuilder.value( value, convert ); + } + } + return this; + } + + } + } + + private static class MatchPredicateFieldMoreStepFieldReference + extends + AbstractMatchPredicateFieldMoreStep, + MatchPredicateFieldMoreStepFieldReference, + T, + MatchPredicateFieldReference> + implements + MatchPredicateFieldMoreGenericStep, + MatchPredicateFieldMoreStepFieldReference.CommonState, + T, + MatchPredicateFieldReference> { + + MatchPredicateFieldMoreStepFieldReference(SearchPredicateDslContext dslContext, + List> fieldPaths) { + super( new CommonState<>( dslContext ), fieldPaths ); + } + + private MatchPredicateFieldMoreStepFieldReference(CommonState commonState, + List> fieldPaths) { + super( commonState, fieldPaths ); + } + + @Override + public MatchPredicateFieldMoreStepFieldReference field(MatchPredicateFieldReference field) { + return new MatchPredicateFieldMoreStepFieldReference<>( commonState, Collections.singletonList( field ) ); + } + + @Override + @SuppressWarnings("unchecked") + public MatchPredicateFieldMoreStepFieldReference fields(MatchPredicateFieldReference... fieldPaths) { + return new MatchPredicateFieldMoreStepFieldReference<>( commonState, Arrays.asList( fieldPaths ) ); + } + + @Override + public CommonState matching(T value) { + return commonState.matching( value ); + } + + @Override + protected MatchPredicateFieldMoreStepFieldReference thisAsS() { + return this; + } + + @Override + protected String fieldPath(MatchPredicateFieldReference field) { + return field.absolutePath(); + } + + private static class CommonState + extends + GenericCommonState, MatchPredicateFieldMoreStepFieldReference> { + CommonState(SearchPredicateDslContext dslContext) { + super( dslContext ); + } + + CommonState matching(T value) { + Contracts.assertNotNull( value, "value" ); + + for ( MatchPredicateFieldMoreStepFieldReference fieldSetState : getFieldSetStates() ) { + for ( Map.Entry, + MatchPredicateBuilder> entry : fieldSetState.predicateBuilders + .entrySet() ) { + entry.getValue().value( value, entry.getKey().valueConvert() ); + } + } + return this; + } + } + } + + static class GenericCommonState> + extends AbstractBooleanMultiFieldPredicateCommonState, S> + implements MatchPredicateOptionsStep> { + + private final MinimumShouldMatchConditionStepImpl> minimumShouldMatchStep; + + GenericCommonState(SearchPredicateDslContext dslContext) { + super( dslContext ); + minimumShouldMatchStep = new MinimumShouldMatchConditionStepImpl<>( new MatchMinimumShouldMatchBuilder(), this ); + } + + @Override + public GenericCommonState fuzzy(int maxEditDistance, int exactPrefixLength) { + if ( maxEditDistance < 0 || 2 < maxEditDistance ) { + throw log.invalidFuzzyMaximumEditDistance( maxEditDistance ); + } + if ( exactPrefixLength < 0 ) { + throw log.invalidExactPrefixLength( exactPrefixLength ); + } + + for ( AbstractMatchPredicateFieldMoreStep fieldSetState : getFieldSetStates() ) { + for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders.values() ) { + predicateBuilder.fuzzy( maxEditDistance, exactPrefixLength ); + } + } + return this; + } + + @Override + public GenericCommonState analyzer(String analyzerName) { + for ( AbstractMatchPredicateFieldMoreStep fieldSetState : getFieldSetStates() ) { + for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders.values() ) { + predicateBuilder.analyzer( analyzerName ); + } + } + return this; + } + + @Override + public GenericCommonState skipAnalysis() { + for ( AbstractMatchPredicateFieldMoreStep fieldSetState : getFieldSetStates() ) { + for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders.values() ) { + predicateBuilder.skipAnalysis(); + } + } + return this; + } + + @Override + protected GenericCommonState thisAsS() { + return this; + } + + @Override + public MinimumShouldMatchConditionStep> minimumShouldMatch() { + return minimumShouldMatchStep; + } + + @Override + public GenericCommonState minimumShouldMatch( + Consumer> constraintContributor) { + constraintContributor.accept( minimumShouldMatchStep ); + return this; + } + + private class MatchMinimumShouldMatchBuilder implements MinimumShouldMatchBuilder { + @Override + public void minimumShouldMatchNumber(int ignoreConstraintCeiling, int matchingClausesNumber) { + for ( AbstractMatchPredicateFieldMoreStep fieldSetState : getFieldSetStates() ) { + for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders.values() ) { + predicateBuilder.minimumShouldMatchNumber( ignoreConstraintCeiling, matchingClausesNumber ); + } + } + } + + @Override + public void minimumShouldMatchPercent(int ignoreConstraintCeiling, int matchingClausesPercent) { + for ( AbstractMatchPredicateFieldMoreStep fieldSetState : getFieldSetStates() ) { + for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders.values() ) { + predicateBuilder.minimumShouldMatchPercent( ignoreConstraintCeiling, matchingClausesPercent ); + } + } + } + } + } + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractRangePredicateFieldMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractRangePredicateFieldMoreStep.java new file mode 100644 index 00000000000..8b0b2809a59 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/AbstractRangePredicateFieldMoreStep.java @@ -0,0 +1,273 @@ +/* + * 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.predicate.dsl.impl; + +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.hibernate.search.engine.logging.impl.Log; +import org.hibernate.search.engine.reporting.spi.EventContexts; +import org.hibernate.search.engine.search.common.ValueConvert; +import org.hibernate.search.engine.search.common.spi.SearchIndexScope; +import org.hibernate.search.engine.search.predicate.SearchPredicate; +import org.hibernate.search.engine.search.predicate.dsl.RangePredicateFieldMoreGenericStep; +import org.hibernate.search.engine.search.predicate.dsl.RangePredicateFieldMoreStep; +import org.hibernate.search.engine.search.predicate.dsl.RangePredicateOptionsStep; +import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; +import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; +import org.hibernate.search.engine.search.predicate.spi.RangePredicateBuilder; +import org.hibernate.search.engine.search.reference.predicate.RangePredicateFieldReference; +import org.hibernate.search.util.common.data.Range; +import org.hibernate.search.util.common.impl.Contracts; +import org.hibernate.search.util.common.logging.impl.LoggerFactory; +import org.hibernate.search.util.common.reporting.EventContext; + +abstract class AbstractRangePredicateFieldMoreStep< + SR, + CS extends AbstractRangePredicateFieldMoreStep.GenericCommonState, + S extends AbstractRangePredicateFieldMoreStep, + T, + V> + implements + //RangePredicateFieldMoreStep, RangePredicateOptionsStep>, + AbstractBooleanMultiFieldPredicateCommonState.FieldSetState { + + private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); + + protected final CS commonState; + + private final List fields; + private final Map predicateBuilders = new HashMap<>(); + + private Float fieldSetBoost; + + public static RangePredicateFieldMoreStepString create( + SearchPredicateDslContext dslContext, String[] fields) { + return new RangePredicateFieldMoreStepString<>( + dslContext, + Arrays.asList( fields ) + ); + } + + public static RangePredicateFieldMoreStepReference create( + SearchPredicateDslContext dslContext, RangePredicateFieldReference[] fields) { + return new RangePredicateFieldMoreStepReference<>( + dslContext, + Arrays.asList( fields ) + ); + } + + private AbstractRangePredicateFieldMoreStep(CS commonState, List fields) { + this.commonState = commonState; + this.commonState.add( this ); + this.fields = fields; + SearchIndexScope scope = commonState.scope(); + for ( V field : fields ) { + predicateBuilders.put( field, scope.fieldQueryElement( fieldPath( field ), PredicateTypeKeys.RANGE ) ); + } + } + + protected abstract String fieldPath(V field); + + protected abstract S thisAsS(); + + public S boost(float boost) { + this.fieldSetBoost = boost; + return thisAsS(); + } + + @Override + public void contributePredicates(Consumer collector) { + for ( RangePredicateBuilder predicateBuilder : predicateBuilders.values() ) { + // Perform last-minute changes, since it's the last call that will be made on this field set state + commonState.applyBoostAndConstantScore( fieldSetBoost, predicateBuilder ); + + collector.accept( predicateBuilder.build() ); + } + } + + private static class RangePredicateFieldMoreStepString + extends + AbstractRangePredicateFieldMoreStep, + RangePredicateFieldMoreStepString, + Object, + String> + implements + RangePredicateFieldMoreStep, + RangePredicateFieldMoreStepString.CommonState> { + + private RangePredicateFieldMoreStepString(SearchPredicateDslContext dslContext, List fields) { + this( new CommonState<>( dslContext ), fields ); + } + + private RangePredicateFieldMoreStepString(CommonState commonState, List fields) { + super( commonState, fields ); + } + + @Override + protected String fieldPath(String field) { + return field; + } + + @Override + protected RangePredicateFieldMoreStepString thisAsS() { + return this; + } + + @Override + public RangePredicateFieldMoreStepString fields(String... fieldPaths) { + return new RangePredicateFieldMoreStepString<>( commonState, Arrays.asList( fieldPaths ) ); + } + + @Override + public CommonState range(Range range, ValueConvert convert) { + return commonState.range( range, convert, convert ); + } + + + public static class CommonState + extends GenericCommonState> { + CommonState(SearchPredicateDslContext dslContext) { + super( dslContext ); + } + + CommonState range(Range range, ValueConvert lowerBoundConvert, ValueConvert upperBoundConvert) { + Contracts.assertNotNull( range, "range" ); + Contracts.assertNotNull( lowerBoundConvert, "lowerBoundConvert" ); + Contracts.assertNotNull( upperBoundConvert, "upperBoundConvert" ); + if ( !range.lowerBoundValue().isPresent() && !range.upperBoundValue().isPresent() ) { + throw log.rangePredicateCannotMatchNullValue( getEventContext() ); + } + for ( var fieldSetState : getFieldSetStates() ) { + for ( RangePredicateBuilder predicateBuilder : fieldSetState.predicateBuilders.values() ) { + predicateBuilder.range( range, lowerBoundConvert, upperBoundConvert ); + } + } + return this; + } + + @Override + protected String fieldPath(String field) { + return field; + } + } + } + + private static class RangePredicateFieldMoreStepReference + extends + AbstractRangePredicateFieldMoreStep, + RangePredicateFieldMoreStepReference, + T, + RangePredicateFieldReference> + implements + RangePredicateFieldMoreGenericStep, + RangePredicateFieldMoreStepReference.CommonState, + RangePredicateFieldReference, + T> { + + private RangePredicateFieldMoreStepReference(SearchPredicateDslContext dslContext, + List> fields) { + this( new CommonState<>( dslContext ), fields ); + } + + private RangePredicateFieldMoreStepReference(CommonState commonState, + List> fields) { + super( commonState, fields ); + } + + @Override + protected String fieldPath(RangePredicateFieldReference field) { + return field.absolutePath(); + } + + @Override + protected RangePredicateFieldMoreStepReference thisAsS() { + return this; + } + + @Override + public RangePredicateFieldMoreStepReference field(RangePredicateFieldReference field) { + return new RangePredicateFieldMoreStepReference<>( commonState, List.of( field ) ); + } + + @Override + @SuppressWarnings("unchecked") + public RangePredicateFieldMoreStepReference fields(RangePredicateFieldReference... fields) { + return new RangePredicateFieldMoreStepReference<>( commonState, Arrays.asList( fields ) ); + } + + @Override + public CommonState range(Range range) { + return commonState.range( range ); + } + + + public static class CommonState + extends + GenericCommonState, RangePredicateFieldMoreStepReference> { + CommonState(SearchPredicateDslContext dslContext) { + super( dslContext ); + } + + CommonState range(Range range) { + Contracts.assertNotNull( range, "range" ); + if ( !range.lowerBoundValue().isPresent() && !range.upperBoundValue().isPresent() ) { + throw log.rangePredicateCannotMatchNullValue( getEventContext() ); + } + for ( var fieldSetState : getFieldSetStates() ) { + for ( var entry : fieldSetState.predicateBuilders.entrySet() ) { + RangePredicateBuilder predicateBuilder = entry.getValue(); + ValueConvert valueConvert = entry.getKey().valueConvert(); + predicateBuilder.range( range, valueConvert, valueConvert ); + } + } + return this; + } + + @Override + protected String fieldPath(RangePredicateFieldReference field) { + return field.absolutePath(); + } + } + } + + abstract static class GenericCommonState> + extends + AbstractBooleanMultiFieldPredicateCommonState, + AbstractRangePredicateFieldMoreStep> + implements RangePredicateOptionsStep> { + + GenericCommonState(SearchPredicateDslContext dslContext) { + super( dslContext ); + } + + @Override + protected GenericCommonState thisAsS() { + return this; + } + + protected abstract String fieldPath(V field); + + protected final EventContext getEventContext() { + return EventContexts.fromIndexFieldAbsolutePaths( + getFieldSetStates().stream().flatMap( f -> f.fields.stream() ) + .map( this::fieldPath ) + .collect( Collectors.toList() ) + ); + } + } + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/ExistsPredicateFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/ExistsPredicateFieldStepImpl.java index 58edabca38a..8ed3cf694f4 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/ExistsPredicateFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/ExistsPredicateFieldStepImpl.java @@ -14,9 +14,9 @@ import org.hibernate.search.engine.search.predicate.spi.ExistsPredicateBuilder; import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; -public final class ExistsPredicateFieldStepImpl +public final class ExistsPredicateFieldStepImpl extends AbstractPredicateFinalStep - implements ExistsPredicateFieldStep>, + implements ExistsPredicateFieldStep>, ExistsPredicateOptionsStep> { private ExistsPredicateBuilder builder; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/KnnPredicateFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/KnnPredicateFieldStepImpl.java index 6659cf643be..99e2176b5a1 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/KnnPredicateFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/KnnPredicateFieldStepImpl.java @@ -11,6 +11,7 @@ import org.hibernate.search.engine.search.predicate.SearchPredicate; import org.hibernate.search.engine.search.predicate.dsl.KnnPredicateFieldStep; import org.hibernate.search.engine.search.predicate.dsl.KnnPredicateOptionsStep; +import org.hibernate.search.engine.search.predicate.dsl.KnnPredicateVectorGenericStep; import org.hibernate.search.engine.search.predicate.dsl.KnnPredicateVectorStep; import org.hibernate.search.engine.search.predicate.dsl.PredicateFinalStep; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; @@ -19,6 +20,7 @@ import org.hibernate.search.engine.search.predicate.spi.BooleanPredicateBuilder; import org.hibernate.search.engine.search.predicate.spi.KnnPredicateBuilder; import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; +import org.hibernate.search.engine.search.reference.predicate.KnnPredicateFieldReference; public class KnnPredicateFieldStepImpl extends AbstractPredicateFinalStep @@ -43,11 +45,9 @@ public KnnPredicateVectorStep field(String fieldPath) { } @Override - protected SearchPredicate build() { - if ( this.booleanBuilder != null ) { - builder.filter( booleanBuilder.build() ); - } - return builder.build(); + public KnnPredicateVectorGenericStep field(KnnPredicateFieldReference field) { + this.field( field.absolutePath() ); + return new KnnPredicateVectorGenericStepImpl<>(); } @Override @@ -93,6 +93,14 @@ public KnnPredicateOptionsStep constantScore() { return this; } + @Override + protected SearchPredicate build() { + if ( this.booleanBuilder != null ) { + builder.filter( booleanBuilder.build() ); + } + return builder.build(); + } + private BooleanPredicateBuilder booleanPredicateBuilder() { if ( this.booleanBuilder == null ) { this.booleanBuilder = dslContext.scope().predicateBuilders().bool(); @@ -100,4 +108,13 @@ private BooleanPredicateBuilder booleanPredicateBuilder() { return this.booleanBuilder; } + private class KnnPredicateVectorGenericStepImpl implements KnnPredicateVectorGenericStep { + + @Override + public KnnPredicateOptionsStep matching(T vector) { + KnnPredicateFieldStepImpl.this.builder.vector( vector ); + return KnnPredicateFieldStepImpl.this; + } + } + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldMoreStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldMoreStepImpl.java deleted file mode 100644 index e0afd0e1238..00000000000 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldMoreStepImpl.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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.predicate.dsl.impl; - -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Consumer; - -import org.hibernate.search.engine.logging.impl.Log; -import org.hibernate.search.engine.search.common.ValueConvert; -import org.hibernate.search.engine.search.common.spi.SearchIndexScope; -import org.hibernate.search.engine.search.predicate.SearchPredicate; -import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateFieldMoreStep; -import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateOptionsStep; -import org.hibernate.search.engine.search.predicate.dsl.MinimumShouldMatchConditionStep; -import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; -import org.hibernate.search.engine.search.predicate.spi.MatchPredicateBuilder; -import org.hibernate.search.engine.search.predicate.spi.MinimumShouldMatchBuilder; -import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; -import org.hibernate.search.util.common.impl.Contracts; -import org.hibernate.search.util.common.logging.impl.LoggerFactory; - -class MatchPredicateFieldMoreStepImpl - implements MatchPredicateFieldMoreStep>, - AbstractBooleanMultiFieldPredicateCommonState.FieldSetState { - - private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); - - private final CommonState commonState; - - private final List predicateBuilders = new ArrayList<>(); - - private Float fieldSetBoost; - - MatchPredicateFieldMoreStepImpl(CommonState commonState, List fieldPaths) { - this.commonState = commonState; - this.commonState.add( this ); - SearchIndexScope scope = commonState.scope(); - for ( String fieldPath : fieldPaths ) { - predicateBuilders.add( scope.fieldQueryElement( fieldPath, PredicateTypeKeys.MATCH ) ); - } - } - - @Override - public MatchPredicateFieldMoreStepImpl fields(String... fieldPaths) { - return new MatchPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); - } - - @Override - public MatchPredicateFieldMoreStepImpl boost(float boost) { - this.fieldSetBoost = boost; - return this; - } - - @Override - public MatchPredicateOptionsStep matching(Object value, ValueConvert convert) { - return commonState.matching( value, convert ); - } - - @Override - public void contributePredicates(Consumer collector) { - for ( MatchPredicateBuilder predicateBuilder : predicateBuilders ) { - // Perform last-minute changes, since it's the last call that will be made on this field set state - commonState.applyBoostAndConstantScore( fieldSetBoost, predicateBuilder ); - - collector.accept( predicateBuilder.build() ); - } - } - - static class CommonState extends AbstractBooleanMultiFieldPredicateCommonState - implements MatchPredicateOptionsStep { - private final MinimumShouldMatchConditionStepImpl minimumShouldMatchStep; - - CommonState(SearchPredicateDslContext dslContext) { - super( dslContext ); - minimumShouldMatchStep = new MinimumShouldMatchConditionStepImpl<>( new MatchMinimumShouldMatchBuilder(), this ); - } - - MatchPredicateOptionsStep matching(Object value, ValueConvert convert) { - Contracts.assertNotNull( value, "value" ); - Contracts.assertNotNull( convert, "convert" ); - - for ( MatchPredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { - for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { - predicateBuilder.value( value, convert ); - } - } - return this; - } - - @Override - public CommonState fuzzy(int maxEditDistance, int exactPrefixLength) { - if ( maxEditDistance < 0 || 2 < maxEditDistance ) { - throw log.invalidFuzzyMaximumEditDistance( maxEditDistance ); - } - if ( exactPrefixLength < 0 ) { - throw log.invalidExactPrefixLength( exactPrefixLength ); - } - - for ( MatchPredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { - for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { - predicateBuilder.fuzzy( maxEditDistance, exactPrefixLength ); - } - } - return this; - } - - @Override - public CommonState analyzer(String analyzerName) { - for ( MatchPredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { - for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { - predicateBuilder.analyzer( analyzerName ); - } - } - return this; - } - - @Override - public CommonState skipAnalysis() { - for ( MatchPredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { - for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { - predicateBuilder.skipAnalysis(); - } - } - return this; - } - - @Override - protected CommonState thisAsS() { - return this; - } - - @Override - public MinimumShouldMatchConditionStep minimumShouldMatch() { - return minimumShouldMatchStep; - } - - @Override - public CommonState minimumShouldMatch(Consumer> constraintContributor) { - constraintContributor.accept( minimumShouldMatchStep ); - return this; - } - - private class MatchMinimumShouldMatchBuilder implements MinimumShouldMatchBuilder { - @Override - public void minimumShouldMatchNumber(int ignoreConstraintCeiling, int matchingClausesNumber) { - for ( MatchPredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { - for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { - predicateBuilder.minimumShouldMatchNumber( ignoreConstraintCeiling, matchingClausesNumber ); - } - } - } - - @Override - public void minimumShouldMatchPercent(int ignoreConstraintCeiling, int matchingClausesPercent) { - for ( MatchPredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { - for ( MatchPredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { - predicateBuilder.minimumShouldMatchPercent( ignoreConstraintCeiling, matchingClausesPercent ); - } - } - } - } - } - -} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldStepImpl.java index 05eb5c247e3..b639d7f39a9 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/MatchPredicateFieldStepImpl.java @@ -6,22 +6,29 @@ */ package org.hibernate.search.engine.search.predicate.dsl.impl; -import java.util.Arrays; - +import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateFieldMoreGenericStep; import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateFieldMoreStep; import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateFieldStep; import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; +import org.hibernate.search.engine.search.reference.predicate.MatchPredicateFieldReference; -public final class MatchPredicateFieldStepImpl implements MatchPredicateFieldStep> { +public final class MatchPredicateFieldStepImpl implements MatchPredicateFieldStep> { - private final MatchPredicateFieldMoreStepImpl.CommonState commonState; + private final SearchPredicateDslContext dslContext; public MatchPredicateFieldStepImpl(SearchPredicateDslContext dslContext) { - this.commonState = new MatchPredicateFieldMoreStepImpl.CommonState( dslContext ); + this.dslContext = dslContext; } @Override public MatchPredicateFieldMoreStep fields(String... fieldPaths) { - return new MatchPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + return AbstractMatchPredicateFieldMoreStep.create( dslContext, fieldPaths ); + } + + @Override + @SuppressWarnings("unchecked") + public MatchPredicateFieldMoreGenericStep> fields( + MatchPredicateFieldReference... fields) { + return AbstractMatchPredicateFieldMoreStep.create( dslContext, fields ); } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldMoreStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldMoreStepImpl.java index 940e072e05d..e430ad341e2 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldMoreStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldMoreStepImpl.java @@ -23,19 +23,19 @@ import org.hibernate.search.util.common.impl.Contracts; import org.hibernate.search.util.common.logging.impl.LoggerFactory; -class PhrasePredicateFieldMoreStepImpl - implements PhrasePredicateFieldMoreStep>, +class PhrasePredicateFieldMoreStepImpl + implements PhrasePredicateFieldMoreStep, PhrasePredicateOptionsStep>, AbstractBooleanMultiFieldPredicateCommonState.FieldSetState { private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); - private final CommonState commonState; + private final CommonState commonState; private final List predicateBuilders = new ArrayList<>(); private Float fieldSetBoost; - PhrasePredicateFieldMoreStepImpl(CommonState commonState, List fieldPaths) { + PhrasePredicateFieldMoreStepImpl(CommonState commonState, List fieldPaths) { this.commonState = commonState; this.commonState.add( this ); SearchIndexScope scope = commonState.scope(); @@ -45,12 +45,12 @@ class PhrasePredicateFieldMoreStepImpl } @Override - public PhrasePredicateFieldMoreStepImpl fields(String... fieldPaths) { - return new PhrasePredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + public PhrasePredicateFieldMoreStepImpl fields(String... fieldPaths) { + return new PhrasePredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); } @Override - public PhrasePredicateFieldMoreStepImpl boost(float boost) { + public PhrasePredicateFieldMoreStepImpl boost(float boost) { this.fieldSetBoost = boost; return this; } @@ -70,9 +70,9 @@ public void contributePredicates(Consumer collector) { } } - static class CommonState - extends AbstractBooleanMultiFieldPredicateCommonState - implements PhrasePredicateOptionsStep { + static class CommonState + extends AbstractBooleanMultiFieldPredicateCommonState, PhrasePredicateFieldMoreStepImpl> + implements PhrasePredicateOptionsStep> { CommonState(SearchPredicateDslContext dslContext) { super( dslContext ); @@ -80,7 +80,7 @@ static class CommonState private PhrasePredicateOptionsStep matching(String phrase) { Contracts.assertNotNull( phrase, "phrase" ); - for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { + for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { for ( PhrasePredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { predicateBuilder.phrase( phrase ); } @@ -89,12 +89,12 @@ private PhrasePredicateOptionsStep matching(String phrase) { } @Override - public CommonState slop(int slop) { + public CommonState slop(int slop) { if ( slop < 0 ) { throw log.invalidPhrasePredicateSlop( slop ); } - for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { + for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { for ( PhrasePredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { predicateBuilder.slop( slop ); } @@ -103,8 +103,8 @@ public CommonState slop(int slop) { } @Override - public CommonState analyzer(String analyzerName) { - for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { + public CommonState analyzer(String analyzerName) { + for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { for ( PhrasePredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { predicateBuilder.analyzer( analyzerName ); } @@ -113,8 +113,8 @@ public CommonState analyzer(String analyzerName) { } @Override - public CommonState skipAnalysis() { - for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { + public CommonState skipAnalysis() { + for ( PhrasePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { for ( PhrasePredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { predicateBuilder.skipAnalysis(); } @@ -123,7 +123,7 @@ public CommonState skipAnalysis() { } @Override - protected CommonState thisAsS() { + protected CommonState thisAsS() { return this; } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldStepImpl.java index 61509ba30e2..8f28271fea4 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/PhrasePredicateFieldStepImpl.java @@ -12,16 +12,17 @@ import org.hibernate.search.engine.search.predicate.dsl.PhrasePredicateFieldStep; import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; -public final class PhrasePredicateFieldStepImpl implements PhrasePredicateFieldStep> { +public final class PhrasePredicateFieldStepImpl + implements PhrasePredicateFieldStep> { - private final PhrasePredicateFieldMoreStepImpl.CommonState commonState; + private final PhrasePredicateFieldMoreStepImpl.CommonState commonState; public PhrasePredicateFieldStepImpl(SearchPredicateDslContext dslContext) { - this.commonState = new PhrasePredicateFieldMoreStepImpl.CommonState( dslContext ); + this.commonState = new PhrasePredicateFieldMoreStepImpl.CommonState( dslContext ); } @Override - public PhrasePredicateFieldMoreStep fields(String... fieldPaths) { - return new PhrasePredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + public PhrasePredicateFieldMoreStep fields(String... fieldPaths) { + return new PhrasePredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldMoreStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldMoreStepImpl.java index 01296a55590..ed8ee687802 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldMoreStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldMoreStepImpl.java @@ -22,9 +22,9 @@ import org.hibernate.search.engine.search.predicate.spi.QueryStringPredicateBuilder; import org.hibernate.search.util.common.logging.impl.LoggerFactory; -class QueryStringPredicateFieldMoreStepImpl +class QueryStringPredicateFieldMoreStepImpl implements - QueryStringPredicateFieldMoreStep> { + QueryStringPredicateFieldMoreStep, QueryStringPredicateOptionsStep> { private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); @@ -40,12 +40,12 @@ class QueryStringPredicateFieldMoreStepImpl } @Override - public QueryStringPredicateFieldMoreStepImpl fields(String... fieldPaths) { - return new QueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + public QueryStringPredicateFieldMoreStepImpl fields(String... fieldPaths) { + return new QueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); } @Override - public QueryStringPredicateFieldMoreStepImpl boost(float boost) { + public QueryStringPredicateFieldMoreStepImpl boost(float boost) { fieldStates.forEach( c -> c.boost( boost ) ); return this; } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldStepImpl.java index 4c551578c77..de2ddfdf72b 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/QueryStringPredicateFieldStepImpl.java @@ -12,8 +12,8 @@ import org.hibernate.search.engine.search.predicate.dsl.QueryStringPredicateFieldStep; import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; -public final class QueryStringPredicateFieldStepImpl - implements QueryStringPredicateFieldStep> { +public final class QueryStringPredicateFieldStepImpl + implements QueryStringPredicateFieldStep> { private final QueryStringPredicateFieldMoreStepImpl.CommonState commonState; @@ -22,7 +22,7 @@ public QueryStringPredicateFieldStepImpl(SearchPredicateDslContext dslContext } @Override - public QueryStringPredicateFieldMoreStep fields(String... fieldPaths) { - return new QueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + public QueryStringPredicateFieldMoreStep fields(String... fieldPaths) { + return new QueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldMoreStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldMoreStepImpl.java deleted file mode 100644 index 9461431dc64..00000000000 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldMoreStepImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.predicate.dsl.impl; - -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import org.hibernate.search.engine.logging.impl.Log; -import org.hibernate.search.engine.reporting.spi.EventContexts; -import org.hibernate.search.engine.search.common.ValueConvert; -import org.hibernate.search.engine.search.common.spi.SearchIndexScope; -import org.hibernate.search.engine.search.predicate.SearchPredicate; -import org.hibernate.search.engine.search.predicate.dsl.RangePredicateFieldMoreStep; -import org.hibernate.search.engine.search.predicate.dsl.RangePredicateOptionsStep; -import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; -import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; -import org.hibernate.search.engine.search.predicate.spi.RangePredicateBuilder; -import org.hibernate.search.util.common.data.Range; -import org.hibernate.search.util.common.impl.Contracts; -import org.hibernate.search.util.common.logging.impl.LoggerFactory; -import org.hibernate.search.util.common.reporting.EventContext; - -class RangePredicateFieldMoreStepImpl - implements RangePredicateFieldMoreStep>, - AbstractBooleanMultiFieldPredicateCommonState.FieldSetState { - - private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); - - private final CommonState commonState; - - private final List fieldPaths; - private final List predicateBuilders = new ArrayList<>(); - - private Float fieldSetBoost; - - RangePredicateFieldMoreStepImpl(CommonState commonState, List fieldPaths) { - this.commonState = commonState; - this.commonState.add( this ); - this.fieldPaths = fieldPaths; - SearchIndexScope scope = commonState.scope(); - for ( String fieldPath : fieldPaths ) { - predicateBuilders.add( scope.fieldQueryElement( fieldPath, PredicateTypeKeys.RANGE ) ); - } - } - - @Override - public RangePredicateFieldMoreStepImpl fields(String... fieldPaths) { - return new RangePredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); - } - - @Override - public RangePredicateFieldMoreStepImpl boost(float boost) { - this.fieldSetBoost = boost; - return this; - } - - @Override - public RangePredicateOptionsStep range(Range range, ValueConvert convert) { - return commonState.range( range, convert, convert ); - } - - @Override - public void contributePredicates(Consumer collector) { - for ( RangePredicateBuilder predicateBuilder : predicateBuilders ) { - // Perform last-minute changes, since it's the last call that will be made on this field set state - commonState.applyBoostAndConstantScore( fieldSetBoost, predicateBuilder ); - - collector.accept( predicateBuilder.build() ); - } - } - - static class CommonState - extends AbstractBooleanMultiFieldPredicateCommonState - implements RangePredicateOptionsStep { - - CommonState(SearchPredicateDslContext dslContext) { - super( dslContext ); - } - - CommonState range(Range range, ValueConvert lowerBoundConvert, ValueConvert upperBoundConvert) { - Contracts.assertNotNull( range, "range" ); - Contracts.assertNotNull( lowerBoundConvert, "lowerBoundConvert" ); - Contracts.assertNotNull( upperBoundConvert, "upperBoundConvert" ); - if ( !range.lowerBoundValue().isPresent() && !range.upperBoundValue().isPresent() ) { - throw log.rangePredicateCannotMatchNullValue( getEventContext() ); - } - for ( RangePredicateFieldMoreStepImpl fieldSetState : getFieldSetStates() ) { - for ( RangePredicateBuilder predicateBuilder : fieldSetState.predicateBuilders ) { - predicateBuilder.range( range, lowerBoundConvert, upperBoundConvert ); - } - } - return this; - } - - @Override - protected CommonState thisAsS() { - return this; - } - - protected final EventContext getEventContext() { - return EventContexts.fromIndexFieldAbsolutePaths( - getFieldSetStates().stream().flatMap( f -> f.fieldPaths.stream() ) - .collect( Collectors.toList() ) - ); - } - } - -} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldStepImpl.java index 15eee673439..0077c5d4fee 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/RangePredicateFieldStepImpl.java @@ -6,22 +6,32 @@ */ package org.hibernate.search.engine.search.predicate.dsl.impl; -import java.util.Arrays; - +import org.hibernate.search.engine.search.predicate.dsl.RangePredicateFieldMoreGenericStep; import org.hibernate.search.engine.search.predicate.dsl.RangePredicateFieldMoreStep; import org.hibernate.search.engine.search.predicate.dsl.RangePredicateFieldStep; import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; +import org.hibernate.search.engine.search.reference.predicate.RangePredicateFieldReference; -public final class RangePredicateFieldStepImpl implements RangePredicateFieldStep> { +public final class RangePredicateFieldStepImpl + implements + RangePredicateFieldStep> { - private final RangePredicateFieldMoreStepImpl.CommonState commonState; + private final SearchPredicateDslContext dslContext; public RangePredicateFieldStepImpl(SearchPredicateDslContext dslContext) { - this.commonState = new RangePredicateFieldMoreStepImpl.CommonState( dslContext ); + this.dslContext = dslContext; } @Override - public RangePredicateFieldMoreStep fields(String... fieldPaths) { - return new RangePredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + public RangePredicateFieldMoreStep fields(String... fieldPaths) { + return AbstractRangePredicateFieldMoreStep.create( dslContext, fieldPaths ); } + + @Override + @SuppressWarnings("unchecked") + public RangePredicateFieldMoreGenericStep, T> fields( + RangePredicateFieldReference... fields) { + return AbstractRangePredicateFieldMoreStep.create( dslContext, fields ); + } + } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldMoreStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldMoreStepImpl.java index 682e7c97e36..483e634b508 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldMoreStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldMoreStepImpl.java @@ -18,9 +18,10 @@ import org.hibernate.search.engine.search.predicate.spi.CommonQueryStringPredicateBuilder; import org.hibernate.search.engine.search.predicate.spi.SimpleQueryStringPredicateBuilder; -class SimpleQueryStringPredicateFieldMoreStepImpl +class SimpleQueryStringPredicateFieldMoreStepImpl implements SimpleQueryStringPredicateFieldMoreStep< - SimpleQueryStringPredicateFieldMoreStepImpl, + SR, + SimpleQueryStringPredicateFieldMoreStepImpl, SimpleQueryStringPredicateOptionsStep> { private final CommonState commonState; @@ -35,12 +36,12 @@ class SimpleQueryStringPredicateFieldMoreStepImpl } @Override - public SimpleQueryStringPredicateFieldMoreStepImpl fields(String... fieldPaths) { - return new SimpleQueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + public SimpleQueryStringPredicateFieldMoreStepImpl fields(String... fieldPaths) { + return new SimpleQueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); } @Override - public SimpleQueryStringPredicateFieldMoreStepImpl boost(float boost) { + public SimpleQueryStringPredicateFieldMoreStepImpl boost(float boost) { fieldStates.forEach( c -> c.boost( boost ) ); return this; } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldStepImpl.java index 9ebeecf1219..f5a0a8787fc 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/impl/SimpleQueryStringPredicateFieldStepImpl.java @@ -12,8 +12,8 @@ import org.hibernate.search.engine.search.predicate.dsl.SimpleQueryStringPredicateFieldStep; import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; -public final class SimpleQueryStringPredicateFieldStepImpl - implements SimpleQueryStringPredicateFieldStep> { +public final class SimpleQueryStringPredicateFieldStepImpl + implements SimpleQueryStringPredicateFieldStep> { private final SimpleQueryStringPredicateFieldMoreStepImpl.CommonState commonState; @@ -22,7 +22,7 @@ public SimpleQueryStringPredicateFieldStepImpl(SearchPredicateDslContext dslC } @Override - public SimpleQueryStringPredicateFieldMoreStep fields(String... fieldPaths) { - return new SimpleQueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); + public SimpleQueryStringPredicateFieldMoreStep fields(String... fieldPaths) { + return new SimpleQueryStringPredicateFieldMoreStepImpl( commonState, Arrays.asList( fieldPaths ) ); } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/spi/AbstractSearchPredicateFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/spi/AbstractSearchPredicateFactory.java index 8d39835a7de..8503ee2395c 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/spi/AbstractSearchPredicateFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/spi/AbstractSearchPredicateFactory.java @@ -154,18 +154,18 @@ public PredicateFinalStep bool(Consumer match() { - return new MatchPredicateFieldStepImpl( dslContext ); + public MatchPredicateFieldStep match() { + return new MatchPredicateFieldStepImpl( dslContext ); } @Override - public RangePredicateFieldStep range() { - return new RangePredicateFieldStepImpl( dslContext ); + public RangePredicateFieldStep range() { + return new RangePredicateFieldStepImpl<>( dslContext ); } @Override - public PhrasePredicateFieldStep phrase() { - return new PhrasePredicateFieldStepImpl( dslContext ); + public PhrasePredicateFieldStep phrase() { + return new PhrasePredicateFieldStepImpl( dslContext ); } @Override @@ -195,18 +195,18 @@ public TermsPredicateFieldStep terms() { } @Override - public SimpleQueryStringPredicateFieldStep simpleQueryString() { - return new SimpleQueryStringPredicateFieldStepImpl( dslContext ); + public SimpleQueryStringPredicateFieldStep simpleQueryString() { + return new SimpleQueryStringPredicateFieldStepImpl( dslContext ); } @Override - public QueryStringPredicateFieldStep queryString() { - return new QueryStringPredicateFieldStepImpl( dslContext ); + public QueryStringPredicateFieldStep queryString() { + return new QueryStringPredicateFieldStepImpl( dslContext ); } @Override - public ExistsPredicateFieldStep exists() { - return new ExistsPredicateFieldStepImpl( dslContext ); + public ExistsPredicateFieldStep exists() { + return new ExistsPredicateFieldStepImpl( dslContext ); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/ExtendedSearchProjectionFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/ExtendedSearchProjectionFactory.java index 596d3e02587..cadffde67bb 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/ExtendedSearchProjectionFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/ExtendedSearchProjectionFactory.java @@ -6,6 +6,8 @@ */ package org.hibernate.search.engine.search.projection.dsl; +import org.hibernate.search.engine.search.reference.object.ObjectFieldReference; + /** * A base interface for subtypes of {@link SearchProjectionFactory} allowing to * easily override the self type for all relevant methods. @@ -22,4 +24,9 @@ public interface ExtendedSearchProjectionFactory objectFieldReference) { + return withRoot( objectFieldReference.absolutePath() ); + } } 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 659a887dc0e..c6de7b5fa5e 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 @@ -15,6 +15,10 @@ import org.hibernate.search.engine.search.common.NamedValues; import org.hibernate.search.engine.search.common.ValueConvert; import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.reference.object.ObjectFieldReference; +import org.hibernate.search.engine.search.reference.projection.DistanceProjectionFieldReference; +import org.hibernate.search.engine.search.reference.projection.FieldProjectionFieldReference; +import org.hibernate.search.engine.search.reference.projection.HighlightProjectionFieldReference; import org.hibernate.search.engine.spatial.GeoPoint; import org.hibernate.search.util.common.SearchException; import org.hibernate.search.util.common.annotation.Incubating; @@ -161,6 +165,18 @@ default FieldProjectionValueStep field(String fieldPath) { */ FieldProjectionValueStep field(String fieldPath, ValueConvert convert); + /** + * Project to the value of a field in the indexed document. + * + * @param fieldReference The reference representing the path to the index field whose value will be extracted. + * @param The resulting type of the projection. + * @return A DSL step where the "field" projection can be defined in more details. + */ + @Incubating + default FieldProjectionValueStep field(FieldProjectionFieldReference fieldReference) { + return field( fieldReference.absolutePath(), fieldReference.projectionType(), fieldReference.valueConvert() ); + } + /** * Project on the score of the hit. * @@ -178,6 +194,20 @@ default FieldProjectionValueStep field(String fieldPath) { */ DistanceToFieldProjectionValueStep distance(String fieldPath, GeoPoint center); + /** + * Project on the distance from the center to a {@link GeoPoint} field. + * + * @param fieldReference The reference representing the path to the index field containing the location + * to compute the distance from. + * @param center The center to compute the distance from. + * @return A DSL step where the "distance" projection can be defined in more details. + */ + @Incubating + default DistanceToFieldProjectionValueStep distance(DistanceProjectionFieldReference fieldReference, + GeoPoint center) { + return distance( fieldReference.absolutePath(), center ); + } + /** * Starts the definition of an object projection, * which will yield one value per object in a given object field, @@ -195,6 +225,26 @@ default FieldProjectionValueStep field(String fieldPath) { */ CompositeProjectionInnerStep object(String objectFieldPath); + /** + * Starts the definition of an object projection, + * which will yield one value per object in a given object field, + * the value being the result of combining multiple given projections + * (usually on fields within the object field). + *

+ * Compared to the basic {@link #composite() composite projection}, + * an object projection is bound to a specific object field, + * and thus it yields zero, one or many values, as many as there are objects in the targeted object field. + * Therefore, you must take care of calling {@link CompositeProjectionValueStep#multi()} + * if the object field is multi-valued. + * + * @param objectFieldReference The reference representing the path to the object field whose object(s) will be extracted. + * @return A DSL step where the "composite" projection can be defined in more details. + */ + @Incubating + default CompositeProjectionInnerStep object(ObjectFieldReference objectFieldReference) { + return object( objectFieldReference.absolutePath() ); + } + /** * Starts the definition of a composite projection, * which will combine multiple given projections. @@ -439,6 +489,21 @@ ProjectionFinalStep withParameters( @Incubating SearchProjectionFactory withRoot(String objectFieldPath); + /** + * Create a new projection factory whose root for all paths passed to the DSL + * will be the given object field. + *

+ * This is used to call reusable methods that can apply the same projection + * on different object fields that have same structure (same sub-fields). + * + * @param objectFieldReference The reference representing the path from the current root to an object field that will become the new root. + * @return A new projection factory using the given object field as root. + */ + @Incubating + default SearchProjectionFactory withRoot(ObjectFieldReference objectFieldReference) { + return withRoot( objectFieldReference.absolutePath() ); + } + /** * @param relativeFieldPath The path to a field, relative to the {@link #withRoot(String) root} of this factory. * @return The absolute path of the field, for use in native projections for example. @@ -455,4 +520,15 @@ ProjectionFinalStep withParameters( */ @Incubating HighlightProjectionOptionsStep highlight(String fieldPath); + + /** + * Project to highlights, i.e. sequences of text that matched the query, extracted from the given field's value. + * + * @param fieldReference The reference representing the path to the index field whose highlights will be extracted. + * @return A DSL step where the "highlight" projection can be defined in more details. + */ + @Incubating + default HighlightProjectionOptionsStep highlight(HighlightProjectionFieldReference fieldReference) { + return highlight( fieldReference.absolutePath() ); + } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/ExtendedSearchSortFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/ExtendedSearchSortFactory.java index 59bf73e3b4e..baabf839fcd 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/ExtendedSearchSortFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/ExtendedSearchSortFactory.java @@ -9,6 +9,8 @@ import java.util.function.Function; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.reference.object.ObjectFieldReference; +import org.hibernate.search.engine.search.reference.sort.FieldSortFieldReference; import org.hibernate.search.engine.spatial.GeoPoint; /** @@ -31,6 +33,11 @@ public interface ExtendedSearchSortFactory< @Override S withRoot(String objectFieldPath); + @Override + default S withRoot(ObjectFieldReference objectFieldReference) { + return withRoot( objectFieldReference.absolutePath() ); + } + @Override FieldSortOptionsStep field(String fieldPath); @@ -41,4 +48,15 @@ public interface ExtendedSearchSortFactory< default DistanceSortOptionsStep distance(String fieldPath, double latitude, double longitude) { return distance( fieldPath, GeoPoint.of( latitude, longitude ) ); } + + @Override + default DistanceSortOptionsStep distance(FieldSortFieldReference fieldReference, GeoPoint location) { + return distance( fieldReference.absolutePath(), location ); + } + + @Override + default DistanceSortOptionsStep distance(FieldSortFieldReference fieldReference, double latitude, + double longitude) { + return distance( fieldReference, GeoPoint.of( latitude, longitude ) ); + } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorGenericStep.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorGenericStep.java new file mode 100644 index 00000000000..b6f1ba299bd --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorGenericStep.java @@ -0,0 +1,70 @@ +/* + * 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.sort.dsl; + +import org.hibernate.search.util.common.SearchException; + +/** + * The step in a sort definition where the behavior on missing values can be set. + * + * @param The type of the missing value to use. + * @param The type of the next step (returned by {@link FieldSortMissingValueBehaviorGenericStep#first()}, for example). + * + * @author Emmanuel Bernard emmanuel@hibernate.org + */ +public interface FieldSortMissingValueBehaviorGenericStep { + + /** + * Put documents with missing values last in the sorting. + * + *

This instruction is independent of whether the sort is being ascending + * or descending. + * + * @return The next step. + */ + N last(); + + /** + * Put documents with missing values first in the sorting. + * + *

This instruction is independent of whether the sort is being ascending + * or descending. + * + * @return The next step. + */ + N first(); + + /** + * Give documents with missing values the highest value when sorting. + *

+ * This puts documents with missing values last when using ascending order, + * or first when using descending order. + * + * @return The next step. + */ + N highest(); + + /** + * Give documents with missing values the lowest value when sorting. + *

+ * This puts documents with missing values first when using ascending order, + * or last when using descending order. + * + * @return The next step. + */ + N lowest(); + + /** + * When documents are missing a value on the sort field, use the given value instead. + * + * @param value The value to use as a default when a document is missing a value on the sort field. + * @return The next step. + * @throws SearchException If the field is not numeric. + */ + N use(T value); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorStep.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorStep.java index db786791a8c..f95e457bb84 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortMissingValueBehaviorStep.java @@ -16,47 +16,7 @@ * * @author Emmanuel Bernard emmanuel@hibernate.org */ -public interface FieldSortMissingValueBehaviorStep { - - /** - * Put documents with missing values last in the sorting. - * - *

This instruction is independent of whether the sort is being ascending - * or descending. - * - * @return The next step. - */ - N last(); - - /** - * Put documents with missing values first in the sorting. - * - *

This instruction is independent of whether the sort is being ascending - * or descending. - * - * @return The next step. - */ - N first(); - - /** - * Give documents with missing values the highest value when sorting. - *

- * This puts documents with missing values last when using ascending order, - * or first when using descending order. - * - * @return The next step. - */ - N highest(); - - /** - * Give documents with missing values the lowest value when sorting. - *

- * This puts documents with missing values first when using ascending order, - * or last when using descending order. - * - * @return The next step. - */ - N lowest(); +public interface FieldSortMissingValueBehaviorStep extends FieldSortMissingValueBehaviorGenericStep { /** * When documents are missing a value on the sort field, use the given value instead. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsGenericStep.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsGenericStep.java new file mode 100644 index 00000000000..d3c0373b4ca --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsGenericStep.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.sort.dsl; + +import java.util.function.Function; + +import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; + +/** + * The initial and final step in a "field" sort definition, where optional parameters can be set. + * + * @param Scope root type. + * @param The "self" type (the actual exposed type of this step). + * @param The type of factory used to create predicates in {@link #filter(Function)}. + * + * @author Emmanuel Bernard emmanuel@hibernate.org + */ +public interface FieldSortOptionsGenericStep< + SR, + T, + S extends FieldSortOptionsGenericStep, + N extends FieldSortMissingValueBehaviorGenericStep, + PDF extends SearchPredicateFactory> + extends SortFinalStep, SortThenStep, SortOrderStep, SortModeStep, SortFilterStep { + + /** + * Start describing the behavior of this sort when a document doesn't + * have any value for the targeted field. + * + * @return The next step. + */ + N missing(); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsStep.java index dbe2c27164e..2df5a031bdd 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/FieldSortOptionsStep.java @@ -20,14 +20,6 @@ * @author Emmanuel Bernard emmanuel@hibernate.org */ public interface FieldSortOptionsStep, PDF extends SearchPredicateFactory> - extends SortFinalStep, SortThenStep, SortOrderStep, SortModeStep, SortFilterStep { - - /** - * Start describing the behavior of this sort when a document doesn't - * have any value for the targeted field. - * - * @return The next step. - */ - FieldSortMissingValueBehaviorStep missing(); + extends FieldSortOptionsGenericStep, PDF> { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/SearchSortFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/SearchSortFactory.java index 0350453cb13..dffe67d9e69 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/SearchSortFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/SearchSortFactory.java @@ -11,6 +11,8 @@ import org.hibernate.search.engine.search.common.NamedValues; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.reference.object.ObjectFieldReference; +import org.hibernate.search.engine.search.reference.sort.FieldSortFieldReference; import org.hibernate.search.engine.spatial.GeoPoint; import org.hibernate.search.util.common.SearchException; import org.hibernate.search.util.common.annotation.Incubating; @@ -64,6 +66,19 @@ public interface SearchSortFactory { */ FieldSortOptionsStep> field(String fieldPath); + /** + * Order elements by the value of a specific field. + *

+ * The default order is ascending. + * + * @param fieldReference The reference representing the path to the index field to sort by. + * @return A DSL step where the "field" sort can be defined in more details. + * @throws SearchException If the field doesn't exist or cannot be sorted on. + */ + @Incubating + FieldSortOptionsGenericStep> field( + FieldSortFieldReference fieldReference); + /** * Order elements by the distance from the location stored in the specified field to the location specified. *

@@ -77,6 +92,23 @@ public interface SearchSortFactory { */ DistanceSortOptionsStep> distance(String fieldPath, GeoPoint location); + /** + * Order elements by the distance from the location stored in the specified field to the location specified. + *

+ * The default order is ascending. + * + * @param fieldReference The reference representing the path to the index field + * containing the location to compute the distance from. + * @param location The location to which we want to compute the distance. + * @return A DSL step where the "distance" sort can be defined in more details. + * @throws SearchException If the field type does not constitute a valid location. + */ + @Incubating + default DistanceSortOptionsStep> distance( + FieldSortFieldReference fieldReference, GeoPoint location) { + return distance( fieldReference.absolutePath(), location ); + } + /** * Order elements by the distance from the location stored in the specified field to the location specified. *

@@ -94,6 +126,25 @@ public interface SearchSortFactory { return distance( fieldPath, GeoPoint.of( latitude, longitude ) ); } + /** + * Order elements by the distance from the location stored in the specified field to the location specified. + *

+ * The default order is ascending. + * + * @param fieldReference The reference representing the path to the index field + * containing the location to compute the distance from. + * @param latitude The latitude of the location to which we want to compute the distance. + * @param longitude The longitude of the location to which we want to compute the distance. + * @return A DSL step where the "distance" sort can be defined in more details. + * @throws SearchException If the field type does not constitute a valid location. + */ + @Incubating + default DistanceSortOptionsStep> distance( + FieldSortFieldReference fieldReference, double latitude, + double longitude) { + return distance( fieldReference, GeoPoint.of( latitude, longitude ) ); + } + /** * Order by a sort composed of several elements. *

@@ -175,6 +226,21 @@ public interface SearchSortFactory { @Incubating SearchSortFactory withRoot(String objectFieldPath); + /** + * Create a new sort factory whose root for all paths passed to the DSL + * will be the given object field. + *

+ * This is used to call reusable methods that can apply the same sort + * on different object fields that have same structure (same sub-fields). + * + * @param objectFieldReference The reference representing the path from the current root to an object field that will become the new root. + * @return A new sort factory using the given object field as root. + */ + @Incubating + default SearchSortFactory withRoot(ObjectFieldReference objectFieldReference) { + return withRoot( objectFieldReference.absolutePath() ); + } + /** * @param relativeFieldPath The path to a field, relative to the {@link #withRoot(String) root} of this factory. * @return The absolute path of the field, for use in native sorts for example. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/impl/GenericFieldSortOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/impl/GenericFieldSortOptionsStepImpl.java new file mode 100644 index 00000000000..aaf2bb0c8b9 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/impl/GenericFieldSortOptionsStepImpl.java @@ -0,0 +1,114 @@ +/* + * 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.sort.dsl.impl; + +import java.util.function.Function; + +import org.hibernate.search.engine.search.common.SortMode; +import org.hibernate.search.engine.search.common.ValueConvert; +import org.hibernate.search.engine.search.predicate.SearchPredicate; +import org.hibernate.search.engine.search.predicate.dsl.PredicateFinalStep; +import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.reference.sort.FieldSortFieldReference; +import org.hibernate.search.engine.search.sort.SearchSort; +import org.hibernate.search.engine.search.sort.dsl.FieldSortMissingValueBehaviorGenericStep; +import org.hibernate.search.engine.search.sort.dsl.FieldSortOptionsGenericStep; +import org.hibernate.search.engine.search.sort.dsl.SortOrder; +import org.hibernate.search.engine.search.sort.dsl.spi.AbstractSortThenStep; +import org.hibernate.search.engine.search.sort.dsl.spi.SearchSortDslContext; +import org.hibernate.search.engine.search.sort.spi.FieldSortBuilder; +import org.hibernate.search.engine.search.sort.spi.SortTypeKeys; + +public class GenericFieldSortOptionsStepImpl> + extends AbstractSortThenStep + implements + FieldSortOptionsGenericStep, + GenericFieldSortOptionsStepImpl, + PDF>, + FieldSortMissingValueBehaviorGenericStep> { + + private final SearchSortDslContext dslContext; + private final FieldSortBuilder builder; + private final ValueConvert valueConvert; + + public GenericFieldSortOptionsStepImpl(SearchSortDslContext dslContext, + FieldSortFieldReference fieldReference) { + super( dslContext ); + this.dslContext = dslContext; + this.builder = dslContext.scope().fieldQueryElement( fieldReference.absolutePath(), SortTypeKeys.FIELD ); + this.valueConvert = fieldReference.valueConvert(); + } + + @Override + public GenericFieldSortOptionsStepImpl order(SortOrder order) { + builder.order( order ); + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl mode(SortMode mode) { + builder.mode( mode ); + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl missing() { + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl filter( + Function clauseContributor) { + SearchPredicate predicate = clauseContributor.apply( dslContext.predicateFactory() ).toPredicate(); + + return filter( predicate ); + } + + @Override + public GenericFieldSortOptionsStepImpl filter(SearchPredicate searchPredicate) { + builder.filter( searchPredicate ); + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl first() { + builder.missingFirst(); + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl last() { + builder.missingLast(); + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl highest() { + builder.missingHighest(); + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl lowest() { + builder.missingLowest(); + return this; + } + + @Override + public GenericFieldSortOptionsStepImpl use(T value) { + builder.missingAs( value, valueConvert ); + return this; + } + + @Override + protected SearchSort build() { + return builder.build(); + } + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/spi/AbstractSearchSortFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/spi/AbstractSearchSortFactory.java index ef991b7e935..33518067c21 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/spi/AbstractSearchSortFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/sort/dsl/spi/AbstractSearchSortFactory.java @@ -12,10 +12,12 @@ import org.hibernate.search.engine.common.dsl.spi.DslExtensionState; import org.hibernate.search.engine.search.common.NamedValues; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.reference.sort.FieldSortFieldReference; import org.hibernate.search.engine.search.sort.SearchSort; import org.hibernate.search.engine.search.sort.dsl.CompositeSortComponentsStep; import org.hibernate.search.engine.search.sort.dsl.DistanceSortOptionsStep; import org.hibernate.search.engine.search.sort.dsl.ExtendedSearchSortFactory; +import org.hibernate.search.engine.search.sort.dsl.FieldSortOptionsGenericStep; import org.hibernate.search.engine.search.sort.dsl.FieldSortOptionsStep; import org.hibernate.search.engine.search.sort.dsl.ScoreSortOptionsStep; import org.hibernate.search.engine.search.sort.dsl.SearchSortFactoryExtension; @@ -25,6 +27,7 @@ import org.hibernate.search.engine.search.sort.dsl.impl.CompositeSortComponentsStepImpl; import org.hibernate.search.engine.search.sort.dsl.impl.DistanceSortOptionsStepImpl; import org.hibernate.search.engine.search.sort.dsl.impl.FieldSortOptionsStepImpl; +import org.hibernate.search.engine.search.sort.dsl.impl.GenericFieldSortOptionsStepImpl; import org.hibernate.search.engine.search.sort.dsl.impl.ScoreSortOptionsStepImpl; import org.hibernate.search.engine.search.sort.dsl.impl.SearchSortFactoryExtensionStep; import org.hibernate.search.engine.search.sort.dsl.impl.WithParametersSortFinalStep; @@ -59,6 +62,12 @@ public SortThenStep indexOrder() { return new FieldSortOptionsStepImpl<>( dslContext, fieldPath ); } + @Override + public FieldSortOptionsGenericStep> field( + FieldSortFieldReference fieldReference) { + return new GenericFieldSortOptionsStepImpl<>( dslContext, fieldReference ); + } + @Override public DistanceSortOptionsStep distance(String fieldPath, GeoPoint location) { return new DistanceSortOptionsStepImpl<>( diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateBaseIT.java index 62a6530d3d6..a8e690602d9 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateBaseIT.java @@ -28,7 +28,7 @@ //CHECKSTYLE:OFF HideUtilityClassConstructor ignore the rule since it is a class with nested test classes. // cannot make a private constructor. -abstract class AbstractBaseQueryStringPredicateBaseIT

> { +abstract class AbstractBaseQueryStringPredicateBaseIT

> { //CHECKSTYLE:ON private static final List< @@ -121,7 +121,7 @@ private static CommonQueryStringPredicateTestValues testValues(FieldTypeDescr class SingleFieldIT extends SingleFieldConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } } @@ -165,14 +165,14 @@ protected Map parameterValues(int matchingDocOrdinal, return Map.of( paramName, dataSet.values.matchingArg( matchingDocOrdinal ) ); } - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class MultiFieldIT extends MultiFieldConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } } @@ -216,14 +216,14 @@ protected PredicateFinalStep predicateOnFieldAndFields(SearchPredicateFactory .matching( dataSet.values.matchingArg( matchingDocOrdinal ) ); } - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class InObjectFieldIT extends InObjectFieldConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } } @@ -258,14 +258,14 @@ protected PredicateFinalStep predicate(SearchPredicateFactory f, String field return predicate( f ).field( fieldPath ).matching( dataSet.values.matchingArg( matchingDocOrdinal ) ); } - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class AnalysisIT extends AnalysisConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } } @@ -301,14 +301,14 @@ protected PredicateFinalStep predicateWithSkipAnalysis(SearchPredicateFactory return predicate( f ).field( fieldPath ).matching( matchingParam ).skipAnalysis(); } - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class ScoreIT extends ScoreConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } } @@ -396,14 +396,14 @@ protected PredicateFinalStep predicateWithFieldLevelBoostAndPredicateLevelBoost( .boost( predicateBoost ); } - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class InvalidFieldIT extends InvalidFieldConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } @@ -429,14 +429,14 @@ protected void tryPredicate(SearchPredicateFactory f, String fieldPath) { protected abstract String predicateTrait(); - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class UnsupportedTypeIT extends UnsupportedTypeConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } @@ -469,7 +469,7 @@ protected void tryPredicate(SearchPredicateFactory f, String fieldPath) { protected abstract String predicateTrait(); - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested @@ -477,7 +477,7 @@ class SearchableIT extends SearchableConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } @@ -517,14 +517,14 @@ protected void tryPredicate(SearchPredicateFactory f, String fieldPath, Field protected abstract String predicateTrait(); - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class ArgumentCheckingIT extends ArgumentCheckingConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } } @@ -550,14 +550,14 @@ protected void tryPredicateWithNullMatchingParam(SearchPredicateFactory f, St predicate( f ).field( fieldPath ).matching( null ); } - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } @Nested class TypeCheckingNoConversionIT extends TypeCheckingNoConversionConfigured { // JDK 11 does not allow static fields in non-static inner class and JUnit does not allow running @Nested tests in static inner classes... @Override - CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return AbstractBaseQueryStringPredicateBaseIT.this.predicate( f ); } @@ -615,7 +615,7 @@ protected PredicateFinalStep predicate(SearchPredicateFactory f, String field protected abstract String predicateTrait(); - abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); + abstract CommonQueryStringPredicateFieldStep predicate(SearchPredicateFactory f); } abstract P predicate(SearchPredicateFactory f); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateSpecificsIT.java index 6746758e288..b98d320126d 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractBaseQueryStringPredicateSpecificsIT.java @@ -46,7 +46,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -abstract class AbstractBaseQueryStringPredicateSpecificsIT

> { +abstract class AbstractBaseQueryStringPredicateSpecificsIT

> { protected static final String DOCUMENT_1 = "document1"; protected static final String DOCUMENT_2 = "document2"; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateBaseIT.java index 11a00e37e4a..caf6f7cf4af 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateBaseIT.java @@ -11,11 +11,11 @@ //CHECKSTYLE:OFF HideUtilityClassConstructor ignore the rule since it is a class with nested test classes. // cannot make a private constructor. -class QueryStringPredicateBaseIT extends AbstractBaseQueryStringPredicateBaseIT> { +class QueryStringPredicateBaseIT extends AbstractBaseQueryStringPredicateBaseIT> { //CHECKSTYLE:ON @Override - QueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + QueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return f.queryString(); } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateSpecificsIT.java index 9e07ffd0360..58c862d5ea0 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/QueryStringPredicateSpecificsIT.java @@ -34,7 +34,8 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -class QueryStringPredicateSpecificsIT extends AbstractBaseQueryStringPredicateSpecificsIT> { +class QueryStringPredicateSpecificsIT + extends AbstractBaseQueryStringPredicateSpecificsIT> { @ParameterizedTest @MethodSource("rewriteMethodOptions") @@ -474,7 +475,7 @@ public static List queryStringSyntax() { } @Override - QueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + QueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return f.queryString(); } } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateBaseIT.java index 6e6139b9821..65fe9c35bdf 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateBaseIT.java @@ -11,10 +11,11 @@ //CHECKSTYLE:OFF HideUtilityClassConstructor ignore the rule since it is a class with nested test classes. // cannot make a private constructor. -class SimpleQueryStringPredicateBaseIT extends AbstractBaseQueryStringPredicateBaseIT> { +class SimpleQueryStringPredicateBaseIT + extends AbstractBaseQueryStringPredicateBaseIT> { //CHECKSTYLE:ON @Override - SimpleQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + SimpleQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return f.simpleQueryString(); } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateSpecificsIT.java index c29de498481..76997862dc0 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/SimpleQueryStringPredicateSpecificsIT.java @@ -37,7 +37,7 @@ import org.junit.jupiter.params.provider.MethodSource; class SimpleQueryStringPredicateSpecificsIT - extends AbstractBaseQueryStringPredicateSpecificsIT> { + extends AbstractBaseQueryStringPredicateSpecificsIT> { @Test @TestForIssue(jiraKey = "HSEARCH-2678") @@ -415,7 +415,7 @@ public static List simpleQueryStringSyntax() { } @Override - SimpleQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { + SimpleQueryStringPredicateFieldStep predicate(SearchPredicateFactory f) { return f.simpleQueryString(); } } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/ObjectProjectionSpecificsIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/ObjectProjectionSpecificsIT.java index 9fbe4e8be3b..360bb13dd2d 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/ObjectProjectionSpecificsIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/ObjectProjectionSpecificsIT.java @@ -44,7 +44,7 @@ static void setup() { @Test void nullFieldPath() { - assertThatThrownBy( () -> index.createScope().projection().object( null ) ) + assertThatThrownBy( () -> index.createScope().projection().object( (String) null ) ) .isInstanceOf( IllegalArgumentException.class ) .hasMessageContaining( "'objectFieldPath' must not be null" ); } diff --git a/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsSimpleQueryStringQueryBuilder.java b/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsSimpleQueryStringQueryBuilder.java index 8cbd4d0a6dc..14bbec37354 100644 --- a/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsSimpleQueryStringQueryBuilder.java +++ b/v5migrationhelper/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsSimpleQueryStringQueryBuilder.java @@ -57,8 +57,8 @@ public Query createQuery() { private SearchPredicate createPredicate() { SearchPredicateFactory factory = queryContext.getScope().predicate(); - SimpleQueryStringPredicateFieldStep fieldStep = factory.simpleQueryString(); - SimpleQueryStringPredicateFieldMoreStep fieldMoreStep = null; + SimpleQueryStringPredicateFieldStep fieldStep = factory.simpleQueryString(); + SimpleQueryStringPredicateFieldMoreStep fieldMoreStep = null; for ( FieldContext fieldContext : fieldsContext ) { fieldMoreStep = fieldContext.applyBoost( fieldStep.field( fieldContext.getField() ) ); }