diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java index e7b04f5ddf3..94e8cf707b0 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java @@ -22,21 +22,21 @@ import org.hibernate.search.engine.backend.types.dsl.IndexFieldTypeFactoryExtension; import org.hibernate.search.engine.common.schema.management.SchemaExport; import org.hibernate.search.engine.common.schema.management.SchemaExportExtension; -import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactory; import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactoryExtension; +import org.hibernate.search.engine.search.aggregation.dsl.TypedSearchAggregationFactory; import org.hibernate.search.engine.search.loading.spi.SearchLoadingContext; import org.hibernate.search.engine.search.loading.spi.SearchLoadingContextBuilder; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactoryExtension; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; +import org.hibernate.search.engine.search.projection.dsl.TypedSearchProjectionFactory; import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.engine.search.query.SearchQueryExtension; import org.hibernate.search.engine.search.query.dsl.SearchQueryDslExtension; import org.hibernate.search.engine.search.query.dsl.SearchQuerySelectStep; import org.hibernate.search.engine.search.query.spi.SearchQueryIndexScope; -import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory; import org.hibernate.search.engine.search.sort.dsl.SearchSortFactoryExtension; +import org.hibernate.search.engine.search.sort.dsl.TypedSearchSortFactory; /** * An extension for the Elasticsearch backend, giving access to Elasticsearch-specific features. @@ -106,12 +106,12 @@ private ElasticsearchExtension() { @Override public Optional> extendOptional( SearchQuerySelectStep original, - SearchQueryIndexScope scope, + SearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder) { if ( scope instanceof ElasticsearchSearchQueryIndexScope ) { return Optional.of( new ElasticsearchSearchQuerySelectStepImpl<>( - (ElasticsearchSearchQueryIndexScope) scope, sessionContext, loadingContextBuilder + (ElasticsearchSearchQueryIndexScope) scope, sessionContext, loadingContextBuilder ) ); } else { @@ -137,7 +137,7 @@ public Optional> extendOptional(SearchQuery origi * {@inheritDoc} */ @Override - public Optional> extendOptional(SearchPredicateFactory original) { + public Optional> extendOptional(TypedSearchPredicateFactory original) { if ( original instanceof ElasticsearchSearchPredicateFactory ) { return Optional.of( (ElasticsearchSearchPredicateFactory) original ); } @@ -151,7 +151,7 @@ public Optional> extendOptional(SearchPr */ @Override public Optional> extendOptional( - SearchSortFactory original) { + TypedSearchSortFactory original) { if ( original instanceof ElasticsearchSearchSortFactory ) { return Optional.of( (ElasticsearchSearchSortFactory) original ); } @@ -164,7 +164,8 @@ public Optional> extendOptional( * {@inheritDoc} */ @Override - public Optional> extendOptional(SearchProjectionFactory original) { + public Optional> extendOptional( + TypedSearchProjectionFactory original) { if ( original instanceof ElasticsearchSearchProjectionFactory ) { return Optional.of( (ElasticsearchSearchProjectionFactory) original ); } @@ -178,7 +179,7 @@ public Optional> extendOptional(S */ @Override public Optional> extendOptional( - SearchAggregationFactory original) { + TypedSearchAggregationFactory original) { if ( original instanceof ElasticsearchSearchAggregationFactory ) { return Optional.of( (ElasticsearchSearchAggregationFactory) original ); } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/AbstractElasticsearchIndexCompositeNodeBuilder.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/AbstractElasticsearchIndexCompositeNodeBuilder.java index bee4b6f8bfc..7b72b16832f 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/AbstractElasticsearchIndexCompositeNodeBuilder.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/AbstractElasticsearchIndexCompositeNodeBuilder.java @@ -5,7 +5,9 @@ package org.hibernate.search.backend.elasticsearch.document.model.dsl.impl; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import org.hibernate.search.backend.elasticsearch.document.model.impl.ElasticsearchIndexCompositeNode; import org.hibernate.search.backend.elasticsearch.document.model.impl.ElasticsearchIndexField; @@ -26,6 +28,7 @@ import org.hibernate.search.engine.backend.types.ObjectStructure; import org.hibernate.search.engine.common.tree.spi.TreeNodeInclusion; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; public abstract class AbstractElasticsearchIndexCompositeNodeBuilder implements IndexCompositeNodeBuilder { @@ -35,7 +38,7 @@ public abstract class AbstractElasticsearchIndexCompositeNodeBuilder implements // Use a LinkedHashMap for deterministic iteration private final Map fields = new LinkedHashMap<>(); private final Map templates = new LinkedHashMap<>(); - private final Map namedPredicates = new LinkedHashMap<>(); + private final Set namedPredicates = new LinkedHashSet<>(); protected AbstractElasticsearchIndexCompositeNodeBuilder( ElasticsearchIndexCompositeNodeType.Builder typeBuilder) { @@ -74,14 +77,23 @@ public IndexObjectFieldBuilder addObjectField(String relativeFieldName, TreeNode @Override public IndexSchemaNamedPredicateOptionsStep addNamedPredicate(String name, TreeNodeInclusion inclusion, PredicateDefinition definition) { - ElasticsearchIndexNamedPredicateOptions options = new ElasticsearchIndexNamedPredicateOptions( - inclusion, definition ); - putNamedPredicate( name, options ); + putNamedPredicate( name ); if ( TreeNodeInclusion.INCLUDED.equals( inclusion ) ) { typeBuilder.queryElementFactory( PredicateTypeKeys.named( name ), - new ElasticsearchNamedPredicate.Factory( options.definition, name ) ); + new ElasticsearchNamedPredicate.Factory( definition, name ) ); } - return options; + return new ElasticsearchIndexNamedPredicateOptions<>( inclusion, definition ); + } + + @Override + public IndexSchemaNamedPredicateOptionsStep addNamedPredicate(String name, + TreeNodeInclusion inclusion, TypedPredicateDefinition definition) { + putNamedPredicate( name ); + if ( TreeNodeInclusion.INCLUDED.equals( inclusion ) ) { + typeBuilder.queryElementFactory( PredicateTypeKeys.named( name ), + new ElasticsearchNamedPredicate.TypedFactory<>( definition, name ) ); + } + return new ElasticsearchIndexNamedPredicateOptions<>( inclusion, definition ); } @Override @@ -147,9 +159,8 @@ private void putTemplate(String name, ElasticsearchIndexNodeContributor contribu } } - private void putNamedPredicate(String name, ElasticsearchIndexNamedPredicateOptions options) { - Object previous = namedPredicates.putIfAbsent( name, options ); - if ( previous != null ) { + private void putNamedPredicate(String name) { + if ( !namedPredicates.add( name ) ) { throw MappingLog.INSTANCE.indexSchemaNamedPredicateNameConflict( name, eventContext() ); } } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/ElasticsearchIndexNamedPredicateOptions.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/ElasticsearchIndexNamedPredicateOptions.java index eeb1a94b0da..36bb25df5cf 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/ElasticsearchIndexNamedPredicateOptions.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/document/model/dsl/impl/ElasticsearchIndexNamedPredicateOptions.java @@ -6,16 +6,8 @@ import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaNamedPredicateOptionsStep; import org.hibernate.search.engine.common.tree.spi.TreeNodeInclusion; -import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; -public class ElasticsearchIndexNamedPredicateOptions implements IndexSchemaNamedPredicateOptionsStep { - - public final TreeNodeInclusion inclusion; - public final PredicateDefinition definition; - - ElasticsearchIndexNamedPredicateOptions(TreeNodeInclusion inclusion, PredicateDefinition definition) { - this.inclusion = inclusion; - this.definition = definition; - } +public record ElasticsearchIndexNamedPredicateOptions(TreeNodeInclusion inclusion, T definition) + implements IndexSchemaNamedPredicateOptionsStep { } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexManagerImpl.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexManagerImpl.java index 3426ecba915..e6ca2eb4247 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexManagerImpl.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexManagerImpl.java @@ -195,9 +195,9 @@ public IndexWorkspace createWorkspace(BackendMappingContext mappingContext, Set< } @Override - public IndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext) { - return new ElasticsearchIndexScopeBuilder( - backendContext, mappingContext, this + public IndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext, Class rootScopeType) { + return new ElasticsearchIndexScopeBuilder<>( + backendContext, mappingContext, rootScopeType, this ); } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexScopeBuilder.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexScopeBuilder.java index 52ea0941b3c..d7dbd890f5a 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexScopeBuilder.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/ElasticsearchIndexScopeBuilder.java @@ -15,18 +15,20 @@ import org.hibernate.search.engine.backend.scope.spi.IndexScope; import org.hibernate.search.engine.backend.scope.spi.IndexScopeBuilder; -class ElasticsearchIndexScopeBuilder implements IndexScopeBuilder { +class ElasticsearchIndexScopeBuilder implements IndexScopeBuilder { private final IndexManagerBackendContext backendContext; private final BackendMappingContext mappingContext; + private final Class rootScopeType; // Use LinkedHashSet to ensure stable order when generating requests private final Set indexManagers = new LinkedHashSet<>(); ElasticsearchIndexScopeBuilder(IndexManagerBackendContext backendContext, - BackendMappingContext mappingContext, ElasticsearchIndexManagerImpl indexManager) { + BackendMappingContext mappingContext, Class rootScopeType, ElasticsearchIndexManagerImpl indexManager) { this.backendContext = backendContext; this.mappingContext = mappingContext; + this.rootScopeType = rootScopeType; this.indexManagers.add( indexManager ); } @@ -40,11 +42,11 @@ void add(IndexManagerBackendContext backendContext, ElasticsearchIndexManagerImp } @Override - public IndexScope build() { + public IndexScope build() { // Use LinkedHashSet to ensure stable order when generating requests Set indexModels = indexManagers.stream().map( ElasticsearchIndexManagerImpl::model ) .collect( Collectors.toCollection( LinkedHashSet::new ) ); - return new ElasticsearchIndexScope( mappingContext, backendContext, indexModels ); + return new ElasticsearchIndexScope<>( mappingContext, backendContext, rootScopeType, indexModels ); } @Override diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/IndexManagerBackendContext.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/IndexManagerBackendContext.java index e88455acb4f..1b85263f4d4 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/IndexManagerBackendContext.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/index/impl/IndexManagerBackendContext.java @@ -146,10 +146,12 @@ public SearchProjectionBackendContext getSearchProjectionBackendContext() { } @Override - public ElasticsearchSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, + public ElasticsearchSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, + Class rootScopeType, Set indexModels) { - return new ElasticsearchSearchIndexScopeImpl( + return new ElasticsearchSearchIndexScopeImpl<>( mappingContext, + rootScopeType, this, userFacingGson, link.getSearchSyntax(), multiTenancyStrategy, diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/ElasticsearchLog.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/ElasticsearchLog.java index f00cdd0afb4..dd69d5000f7 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/ElasticsearchLog.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/ElasticsearchLog.java @@ -40,6 +40,6 @@ public interface ElasticsearchLog * here to the next value. */ @LogMessage(level = TRACE) - @Message(id = ID_OFFSET + 193, value = "") + @Message(id = ID_OFFSET + 194, value = "") void nextLoggerIdForConvenience(); } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/QueryLog.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/QueryLog.java index 22b6c65aed0..c09254dcf4b 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/QueryLog.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/logging/impl/QueryLog.java @@ -333,4 +333,8 @@ SearchException vectorKnnMatchVectorTypeDiffersFromField(String absoluteFieldPat @Message(id = ID_OFFSET + 190, value = "A single-valued highlight projection requested, " + "but the corresponding highlighter does not set number of fragments to 1.") SearchException highlighterIncompatibleCardinality(); + + @Message(id = ID_OFFSET + 193, value = "Current factory cannot be resocped to '%1$s' as it is scoped to '%2$s'.") + SearchException incompatibleScopeRootType(@FormatWith(ClassFormatter.class) Class requested, + @FormatWith(ClassFormatter.class) Class actual); } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/impl/ElasticsearchIndexScope.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/impl/ElasticsearchIndexScope.java index df386bfcca1..d645240480c 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/impl/ElasticsearchIndexScope.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/impl/ElasticsearchIndexScope.java @@ -12,14 +12,15 @@ import org.hibernate.search.engine.backend.mapping.spi.BackendMappingContext; import org.hibernate.search.engine.backend.scope.spi.IndexScope; -public class ElasticsearchIndexScope - implements IndexScope { +public class ElasticsearchIndexScope + implements IndexScope { - private final ElasticsearchSearchQueryIndexScope searchScope; + private final ElasticsearchSearchQueryIndexScope searchScope; public ElasticsearchIndexScope(BackendMappingContext mappingContext, SearchBackendContext backendContext, + Class rootScopeType, Set indexModels) { - this.searchScope = backendContext.createSearchContext( mappingContext, indexModels ); + this.searchScope = backendContext.createSearchContext( mappingContext, rootScopeType, indexModels ); } @Override @@ -28,7 +29,7 @@ public String toString() { } @Override - public ElasticsearchSearchQueryIndexScope searchScope() { + public ElasticsearchSearchQueryIndexScope searchScope() { return searchScope; } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/model/impl/ElasticsearchSearchIndexScopeImpl.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/model/impl/ElasticsearchSearchIndexScopeImpl.java index 385dda24105..58934e9ed81 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/model/impl/ElasticsearchSearchIndexScopeImpl.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/scope/model/impl/ElasticsearchSearchIndexScopeImpl.java @@ -54,14 +54,15 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; -public final class ElasticsearchSearchIndexScopeImpl +public final class ElasticsearchSearchIndexScopeImpl extends AbstractSearchIndexScope< - ElasticsearchSearchIndexScopeImpl, + SR, + ElasticsearchSearchIndexScopeImpl, ElasticsearchIndexModel, ElasticsearchSearchIndexNodeContext, ElasticsearchSearchIndexCompositeNodeContext> - implements ElasticsearchSearchIndexScope, - ElasticsearchSearchQueryIndexScope { + implements ElasticsearchSearchIndexScope>, + ElasticsearchSearchQueryIndexScope> { // Backend context private final SearchBackendContext backendContext; @@ -81,12 +82,13 @@ public final class ElasticsearchSearchIndexScopeImpl private final ElasticsearchSearchAggregationBuilderFactory aggregationFactory; public ElasticsearchSearchIndexScopeImpl(BackendMappingContext mappingContext, + Class rootScopeType, SearchBackendContext backendContext, Gson userFacingGson, ElasticsearchSearchSyntax searchSyntax, MultiTenancyStrategy multiTenancyStrategy, TimingSource timingSource, Set indexModels) { - super( mappingContext, indexModels ); + super( mappingContext, rootScopeType, indexModels ); this.backendContext = backendContext; this.userFacingGson = userFacingGson; this.searchSyntax = searchSyntax; @@ -115,7 +117,7 @@ public ElasticsearchSearchIndexScopeImpl(BackendMappingContext mappingContext, this.aggregationFactory = new ElasticsearchSearchAggregationBuilderFactory( this ); } - private ElasticsearchSearchIndexScopeImpl(ElasticsearchSearchIndexScopeImpl parentScope, + private ElasticsearchSearchIndexScopeImpl(ElasticsearchSearchIndexScopeImpl parentScope, ElasticsearchSearchIndexCompositeNodeContext overriddenRoot) { super( parentScope, overriddenRoot ); this.backendContext = parentScope.backendContext; @@ -134,13 +136,13 @@ private ElasticsearchSearchIndexScopeImpl(ElasticsearchSearchIndexScopeImpl pare } @Override - protected ElasticsearchSearchIndexScopeImpl self() { + protected ElasticsearchSearchIndexScopeImpl self() { return this; } @Override - public ElasticsearchSearchIndexScopeImpl withRoot(String objectFieldPath) { - return new ElasticsearchSearchIndexScopeImpl( this, field( objectFieldPath ).toComposite() ); + public ElasticsearchSearchIndexScopeImpl withRoot(String objectFieldPath) { + return new ElasticsearchSearchIndexScopeImpl<>( this, field( objectFieldPath ).toComposite() ); } @Override @@ -171,23 +173,23 @@ public

ElasticsearchSearchQueryBuilder

select(BackendSessionContext sessi } @Override - public ElasticsearchSearchPredicateFactory predicateFactory() { - return new ElasticsearchSearchPredicateFactoryImpl<>( SearchPredicateDslContext.root( this ) ); + public ElasticsearchSearchPredicateFactory predicateFactory() { + return new ElasticsearchSearchPredicateFactoryImpl<>( rootScopeType, SearchPredicateDslContext.root( this ) ); } @Override - public ElasticsearchSearchSortFactory sortFactory() { + public ElasticsearchSearchSortFactory sortFactory() { return new ElasticsearchSearchSortFactoryImpl<>( SearchSortDslContext .root( this, ElasticsearchSearchSortFactoryImpl::new, predicateFactory() ) ); } @Override - public ElasticsearchSearchProjectionFactory projectionFactory() { + public ElasticsearchSearchProjectionFactory projectionFactory() { return new ElasticsearchSearchProjectionFactoryImpl<>( SearchProjectionDslContext.root( this ) ); } @Override - public ElasticsearchSearchAggregationFactory aggregationFactory() { + public ElasticsearchSearchAggregationFactory aggregationFactory() { return new ElasticsearchSearchAggregationFactoryImpl<>( SearchAggregationDslContext.root( this, predicateFactory() ) ); } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/dsl/impl/ElasticsearchSearchPredicateFactoryImpl.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/dsl/impl/ElasticsearchSearchPredicateFactoryImpl.java index 3df4026ae94..8cff933cccb 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/dsl/impl/ElasticsearchSearchPredicateFactoryImpl.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/dsl/impl/ElasticsearchSearchPredicateFactoryImpl.java @@ -4,8 +4,10 @@ */ package org.hibernate.search.backend.elasticsearch.search.predicate.dsl.impl; +import org.hibernate.search.backend.elasticsearch.logging.impl.QueryLog; import org.hibernate.search.backend.elasticsearch.search.predicate.dsl.ElasticsearchSearchPredicateFactory; import org.hibernate.search.backend.elasticsearch.search.predicate.impl.ElasticsearchSearchPredicateIndexScope; +import org.hibernate.search.engine.search.common.NonStaticMetamodelScope; import org.hibernate.search.engine.search.predicate.dsl.PredicateFinalStep; import org.hibernate.search.engine.search.predicate.dsl.spi.AbstractSearchPredicateFactory; import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; @@ -21,16 +23,36 @@ public class ElasticsearchSearchPredicateFactoryImpl implements ElasticsearchSearchPredicateFactory { public ElasticsearchSearchPredicateFactoryImpl( + Class scopeRootType, SearchPredicateDslContext> dslContext) { - super( dslContext ); + super( scopeRootType, dslContext ); } @Override public ElasticsearchSearchPredicateFactory withRoot(String objectFieldPath) { - return new ElasticsearchSearchPredicateFactoryImpl<>( dslContext.rescope( + return new ElasticsearchSearchPredicateFactoryImpl<>( scopeRootType, dslContext.rescope( dslContext.scope().withRoot( objectFieldPath ) ) ); } + @SuppressWarnings("unchecked") // well because we check ;) + @Override + public ElasticsearchSearchPredicateFactory withScopeRoot(Class scopeRootType) { + if ( this.scopeRootType.equals( scopeRootType ) ) { + return (ElasticsearchSearchPredicateFactory) this; + } + if ( + // if we want the "untyped" version of the factory we can get it from any other factory + // e.g. we have one tied to a Book__ and we want to use some "raw" string paths in a named predicate. + scopeRootType.equals( NonStaticMetamodelScope.class ) + // scope type is in the same hierarchy: + || this.scopeRootType.isAssignableFrom( scopeRootType ) + || scopeRootType.isAssignableFrom( this.scopeRootType ) + ) { + return new ElasticsearchSearchPredicateFactoryImpl<>( scopeRootType, dslContext ); + } + throw QueryLog.INSTANCE.incompatibleScopeRootType( scopeRootType, this.scopeRootType ); + } + @Override public PredicateFinalStep fromJson(String jsonString) { return new StaticPredicateFinalStep( dslContext.scope().predicateBuilders().fromJson( jsonString ) ); diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/impl/ElasticsearchNamedPredicate.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/impl/ElasticsearchNamedPredicate.java index b024823eac4..8fe707d8b24 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/impl/ElasticsearchNamedPredicate.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/predicate/impl/ElasticsearchNamedPredicate.java @@ -11,12 +11,18 @@ import org.hibernate.search.backend.elasticsearch.search.common.impl.AbstractElasticsearchCompositeNodeSearchQueryElementFactory; import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexCompositeNodeContext; import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexScope; +import org.hibernate.search.engine.search.common.NonStaticMetamodelScope; import org.hibernate.search.engine.search.common.spi.SearchQueryElementFactory; import org.hibernate.search.engine.search.predicate.SearchPredicate; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; +import org.hibernate.search.engine.search.predicate.dsl.ExtendedSearchPredicateFactory; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateFactoryDelegate; import org.hibernate.search.engine.search.predicate.spi.NamedPredicateBuilder; import org.hibernate.search.engine.search.predicate.spi.NamedValuesBasedPredicateDefinitionContext; +import org.hibernate.search.engine.search.predicate.spi.NamedValuesBasedTypedPredicateDefinitionContext; import com.google.gson.JsonObject; @@ -63,46 +69,112 @@ public void checkCompatibleWith(SearchQueryElementFactory other) { @Override public NamedPredicateBuilder create(ElasticsearchSearchIndexScope scope, ElasticsearchSearchIndexCompositeNodeContext node) { - return new Builder( definition, predicateName, scope, node ); + return new BasicBuilder( definition, predicateName, scope, node ); } } - private static class Builder extends AbstractBuilder implements NamedPredicateBuilder { - private final PredicateDefinition definition; + public static class TypedFactory + extends AbstractElasticsearchCompositeNodeSearchQueryElementFactory { + private final TypedPredicateDefinition definition; private final String predicateName; - private final ElasticsearchSearchIndexCompositeNodeContext field; - private SearchPredicateFactory factory; - private final Map params = new LinkedHashMap<>(); - Builder(PredicateDefinition definition, String predicateName, + public TypedFactory(TypedPredicateDefinition definition, String predicateName) { + this.definition = definition; + this.predicateName = predicateName; + } + + @Override + public void checkCompatibleWith(SearchQueryElementFactory other) { + super.checkCompatibleWith( other ); + TypedFactory castedOther = (TypedFactory) other; + if ( !definition.equals( castedOther.definition ) ) { + throw QueryLog.INSTANCE.differentPredicateDefinitionForQueryElement( definition, castedOther.definition ); + } + } + + @Override + public NamedPredicateBuilder create(ElasticsearchSearchIndexScope scope, + ElasticsearchSearchIndexCompositeNodeContext node) { + return new TypedBuilder<>( definition, predicateName, scope, node ); + } + } + + private abstract static class Builder extends AbstractBuilder implements NamedPredicateBuilder { + protected final String predicateName; + protected final ElasticsearchSearchIndexCompositeNodeContext field; + protected final Map params = new LinkedHashMap<>(); + + Builder(String predicateName, ElasticsearchSearchIndexScope scope, ElasticsearchSearchIndexCompositeNodeContext node) { super( scope, node ); - this.definition = definition; this.predicateName = predicateName; this.field = node; } @Override - public void factory(SearchPredicateFactory factory) { - this.factory = factory; + public final void param(String name, Object value) { + params.put( name, value ); } + protected abstract ElasticsearchSearchPredicate providedPredicate(); + @Override - public void param(String name, Object value) { - params.put( name, value ); + public final SearchPredicate build() { + return new ElasticsearchNamedPredicate( this, providedPredicate() ); + } + + } + + private static class BasicBuilder extends Builder { + private final PredicateDefinition definition; + private SearchPredicateFactory factory; + + BasicBuilder(PredicateDefinition definition, String predicateName, + ElasticsearchSearchIndexScope scope, + ElasticsearchSearchIndexCompositeNodeContext node) { + super( predicateName, scope, node ); + this.definition = definition; + } + + @SuppressWarnings("unchecked") + @Override + public void factory(ExtendedSearchPredicateFactory factory) { + this.factory = new SearchPredicateFactoryDelegate( factory.withScopeRoot( NonStaticMetamodelScope.class ) ); } @Override - public SearchPredicate build() { - NamedValuesBasedPredicateDefinitionContext ctx = - new NamedValuesBasedPredicateDefinitionContext<>( factory, params, + protected ElasticsearchSearchPredicate providedPredicate() { + NamedValuesBasedPredicateDefinitionContext ctx = + new NamedValuesBasedPredicateDefinitionContext( factory, params, name -> QueryLog.INSTANCE.paramNotDefined( name, predicateName, field.eventContext() ) ); - ElasticsearchSearchPredicate providedPredicate = ElasticsearchSearchPredicate.from( - scope, definition.create( ctx ) ); + return ElasticsearchSearchPredicate.from( scope, definition.create( ctx ) ); + } + } + + private static class TypedBuilder extends Builder { + private final TypedPredicateDefinition definition; + private TypedSearchPredicateFactory factory; + + TypedBuilder(TypedPredicateDefinition definition, String predicateName, ElasticsearchSearchIndexScope scope, + ElasticsearchSearchIndexCompositeNodeContext node) { + super( predicateName, scope, node ); + this.definition = definition; + } + + @SuppressWarnings("unchecked") + @Override + public void factory(ExtendedSearchPredicateFactory factory) { + this.factory = factory.withScopeRoot( definition.scopeRootType() ); + } + + @Override + protected ElasticsearchSearchPredicate providedPredicate() { + var ctx = new NamedValuesBasedTypedPredicateDefinitionContext<>( factory, params, + name -> QueryLog.INSTANCE.paramNotDefined( name, predicateName, field.eventContext() ) ); - return new ElasticsearchNamedPredicate( this, providedPredicate ); + return ElasticsearchSearchPredicate.from( scope, definition.create( ctx ) ); } } } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/ElasticsearchSearchProjectionFactory.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/ElasticsearchSearchProjectionFactory.java index f6485bfacbf..c626a0c9711 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/ElasticsearchSearchProjectionFactory.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/ElasticsearchSearchProjectionFactory.java @@ -6,7 +6,7 @@ import org.hibernate.search.engine.search.projection.dsl.ExtendedSearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; +import org.hibernate.search.engine.search.projection.dsl.TypedSearchProjectionFactory; import com.google.gson.JsonObject; @@ -16,7 +16,7 @@ * @param Scope root type. * @param The type of entity references. * @param The type of entities. - * @see SearchProjectionFactory + * @see TypedSearchProjectionFactory */ public interface ElasticsearchSearchProjectionFactory extends ExtendedSearchProjectionFactory, R, E> { diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java index 44c61c9aa07..5257c3e0000 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java @@ -6,6 +6,7 @@ import org.hibernate.search.backend.elasticsearch.search.projection.dsl.ElasticsearchSearchProjectionFactory; import org.hibernate.search.backend.elasticsearch.search.projection.impl.ElasticsearchSearchProjectionIndexScope; +import org.hibernate.search.engine.search.projection.dsl.ExtendedSearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; import org.hibernate.search.engine.search.projection.dsl.spi.AbstractSearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; @@ -33,6 +34,11 @@ public ElasticsearchSearchProjectionFactory withRoot(String objectFiel dslContext.scope().withRoot( objectFieldPath ) ) ); } + @Override + public ExtendedSearchProjectionFactory withScopeRoot(Class scopeRootType) { + return new ElasticsearchSearchProjectionFactoryImpl<>( dslContext ); + } + @Override public ProjectionFinalStep source() { return new StaticProjectionFinalStep<>( dslContext.scope().projectionBuilders().source() ); diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQueryOptionsStepImpl.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQueryOptionsStepImpl.java index 6f346506453..9d395ffbc52 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQueryOptionsStepImpl.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQueryOptionsStepImpl.java @@ -30,12 +30,12 @@ class ElasticsearchSearchQueryOptionsStepImpl ElasticsearchSearchPredicateFactory, ElasticsearchSearchSortFactory, ElasticsearchSearchAggregationFactory, - ElasticsearchSearchQueryIndexScope> + ElasticsearchSearchQueryIndexScope> implements ElasticsearchSearchQueryWhereStep, ElasticsearchSearchQueryOptionsStep { private final ElasticsearchSearchQueryBuilder searchQueryBuilder; - ElasticsearchSearchQueryOptionsStepImpl(ElasticsearchSearchQueryIndexScope scope, + ElasticsearchSearchQueryOptionsStepImpl(ElasticsearchSearchQueryIndexScope scope, ElasticsearchSearchQueryBuilder searchQueryBuilder, SearchLoadingContextBuilder loadingContextBuilder) { super( scope, searchQueryBuilder, loadingContextBuilder ); diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQuerySelectStepImpl.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQuerySelectStepImpl.java index 74f3cf34327..992fe4ad07e 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQuerySelectStepImpl.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/dsl/impl/ElasticsearchSearchQuerySelectStepImpl.java @@ -38,11 +38,11 @@ public class ElasticsearchSearchQuerySelectStepImpl ElasticsearchSearchPredicateFactory> implements ElasticsearchSearchQuerySelectStep { - private final ElasticsearchSearchQueryIndexScope scope; + private final ElasticsearchSearchQueryIndexScope scope; private final BackendSessionContext sessionContext; private final SearchLoadingContextBuilder loadingContextBuilder; - public ElasticsearchSearchQuerySelectStepImpl(ElasticsearchSearchQueryIndexScope scope, + public ElasticsearchSearchQuerySelectStepImpl(ElasticsearchSearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder) { this.scope = scope; @@ -52,7 +52,7 @@ public ElasticsearchSearchQuerySelectStepImpl(ElasticsearchSearchQueryIndexScope @Override public ElasticsearchSearchQueryWhereStep selectEntity() { - return select( scope.projectionFactory().entity().toProjection() ); + return select( scope.projectionFactory().entity().toProjection() ); } @Override @@ -106,7 +106,7 @@ public ElasticsearchSearchQueryOptionsStep where( } @Override - protected SearchQueryIndexScope scope() { + protected SearchQueryIndexScope scope() { return scope; } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/ElasticsearchSearchQueryIndexScope.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/ElasticsearchSearchQueryIndexScope.java index feed3352cd5..09c75b85ac5 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/ElasticsearchSearchQueryIndexScope.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/ElasticsearchSearchQueryIndexScope.java @@ -17,8 +17,8 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.query.spi.SearchQueryIndexScope; -public interface ElasticsearchSearchQueryIndexScope> - extends SearchQueryIndexScope, +public interface ElasticsearchSearchQueryIndexScope> + extends SearchQueryIndexScope, ElasticsearchSearchPredicateIndexScope, ElasticsearchSearchSortIndexScope, ElasticsearchSearchProjectionIndexScope, ElasticsearchSearchAggregationIndexScope { @@ -27,15 +27,15 @@

ElasticsearchSearchQueryBuilder

select(BackendSessionContext sessionConte SearchLoadingContextBuilder loadingContextBuilder, SearchProjection

projection); @Override - ElasticsearchSearchPredicateFactory predicateFactory(); + ElasticsearchSearchPredicateFactory predicateFactory(); @Override - ElasticsearchSearchSortFactory sortFactory(); + ElasticsearchSearchSortFactory sortFactory(); @Override - ElasticsearchSearchProjectionFactory projectionFactory(); + ElasticsearchSearchProjectionFactory projectionFactory(); @Override - ElasticsearchSearchAggregationFactory aggregationFactory(); + ElasticsearchSearchAggregationFactory aggregationFactory(); } diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/SearchBackendContext.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/SearchBackendContext.java index 173fa36726b..789b13f268e 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/SearchBackendContext.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/query/impl/SearchBackendContext.java @@ -29,7 +29,8 @@ public interface SearchBackendContext { SearchProjectionBackendContext getSearchProjectionBackendContext(); - ElasticsearchSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, + ElasticsearchSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, + Class rootScopeType, Set indexModels); ElasticsearchSearchQueryBuilder createSearchQueryBuilder( diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java index 43a4eb1fecb..bb6656b7d0f 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java @@ -25,21 +25,21 @@ import org.hibernate.search.engine.backend.types.dsl.IndexFieldTypeFactoryExtension; import org.hibernate.search.engine.common.schema.management.SchemaExport; import org.hibernate.search.engine.common.schema.management.SchemaExportExtension; -import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactory; import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactoryExtension; +import org.hibernate.search.engine.search.aggregation.dsl.TypedSearchAggregationFactory; import org.hibernate.search.engine.search.loading.spi.SearchLoadingContext; import org.hibernate.search.engine.search.loading.spi.SearchLoadingContextBuilder; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactoryExtension; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; +import org.hibernate.search.engine.search.projection.dsl.TypedSearchProjectionFactory; import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.engine.search.query.SearchQueryExtension; import org.hibernate.search.engine.search.query.dsl.SearchQueryDslExtension; import org.hibernate.search.engine.search.query.dsl.SearchQuerySelectStep; import org.hibernate.search.engine.search.query.spi.SearchQueryIndexScope; -import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory; import org.hibernate.search.engine.search.sort.dsl.SearchSortFactoryExtension; +import org.hibernate.search.engine.search.sort.dsl.TypedSearchSortFactory; /** * An extension for the Lucene backend, giving access to Lucene-specific features. @@ -109,12 +109,12 @@ private LuceneExtension() { @Override public Optional> extendOptional( SearchQuerySelectStep original, - SearchQueryIndexScope scope, + SearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder) { if ( scope instanceof LuceneSearchQueryIndexScope ) { return Optional.of( new LuceneSearchQuerySelectStepImpl<>( - (LuceneSearchQueryIndexScope) scope, sessionContext, loadingContextBuilder + (LuceneSearchQueryIndexScope) scope, sessionContext, loadingContextBuilder ) ); } else { @@ -140,7 +140,7 @@ public Optional> extendOptional(SearchQuery original, * {@inheritDoc} */ @Override - public Optional> extendOptional(SearchPredicateFactory original) { + public Optional> extendOptional(TypedSearchPredicateFactory original) { if ( original instanceof LuceneSearchPredicateFactory ) { return Optional.of( (LuceneSearchPredicateFactory) original ); } @@ -154,7 +154,7 @@ public Optional> extendOptional(SearchPredicate */ @Override public Optional> extendOptional( - SearchSortFactory original) { + TypedSearchSortFactory original) { if ( original instanceof LuceneSearchSortFactory ) { return Optional.of( (LuceneSearchSortFactory) original ); } @@ -167,7 +167,7 @@ public Optional> extendOptional( * {@inheritDoc} */ @Override - public Optional> extendOptional(SearchProjectionFactory original) { + public Optional> extendOptional(TypedSearchProjectionFactory original) { if ( original instanceof LuceneSearchProjectionFactory ) { return Optional.of( (LuceneSearchProjectionFactory) original ); } @@ -180,7 +180,7 @@ public Optional> extendOptional(SearchPr * {@inheritDoc} */ @Override - public Optional> extendOptional(SearchAggregationFactory original) { + public Optional> extendOptional(TypedSearchAggregationFactory original) { if ( original instanceof LuceneSearchAggregationFactory ) { return Optional.of( (LuceneSearchAggregationFactory) original ); } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/AbstractLuceneIndexCompositeNodeBuilder.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/AbstractLuceneIndexCompositeNodeBuilder.java index c8245e79db5..90ed63f3d9e 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/AbstractLuceneIndexCompositeNodeBuilder.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/AbstractLuceneIndexCompositeNodeBuilder.java @@ -5,7 +5,9 @@ package org.hibernate.search.backend.lucene.document.model.dsl.impl; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import org.hibernate.search.backend.lucene.document.model.impl.LuceneIndexCompositeNode; import org.hibernate.search.backend.lucene.document.model.impl.LuceneIndexField; @@ -25,6 +27,7 @@ import org.hibernate.search.engine.backend.types.ObjectStructure; import org.hibernate.search.engine.common.tree.spi.TreeNodeInclusion; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys; abstract class AbstractLuceneIndexCompositeNodeBuilder @@ -35,7 +38,7 @@ abstract class AbstractLuceneIndexCompositeNodeBuilder // Use a LinkedHashMap for deterministic iteration private final Map fields = new LinkedHashMap<>(); private final Map templates = new LinkedHashMap<>(); - private final Map namedPredicates = new LinkedHashMap<>(); + private final Set namedPredicates = new LinkedHashSet<>(); protected AbstractLuceneIndexCompositeNodeBuilder(LuceneIndexCompositeNodeType.Builder typeBuilder) { this.typeBuilder = typeBuilder; @@ -73,14 +76,23 @@ public IndexObjectFieldBuilder addObjectField(String relativeFieldName, TreeNode @Override public IndexSchemaNamedPredicateOptionsStep addNamedPredicate(String name, TreeNodeInclusion inclusion, PredicateDefinition definition) { - LuceneIndexNamedPredicateOptions options = new LuceneIndexNamedPredicateOptions( - inclusion, definition ); - putNamedPredicate( name, options ); + putNamedPredicate( name ); if ( TreeNodeInclusion.INCLUDED.equals( inclusion ) ) { typeBuilder.queryElementFactory( PredicateTypeKeys.named( name ), - new LuceneNamedPredicate.Factory( options.definition, name ) ); + new LuceneNamedPredicate.Factory( definition, name ) ); } - return options; + return new LuceneIndexNamedPredicateOptions<>( inclusion, definition ); + } + + @Override + public IndexSchemaNamedPredicateOptionsStep addNamedPredicate(String name, + TreeNodeInclusion inclusion, TypedPredicateDefinition definition) { + putNamedPredicate( name ); + if ( TreeNodeInclusion.INCLUDED.equals( inclusion ) ) { + typeBuilder.queryElementFactory( PredicateTypeKeys.named( name ), + new LuceneNamedPredicate.TypedFactory<>( definition, name ) ); + } + return new LuceneIndexNamedPredicateOptions<>( inclusion, definition ); } @Override @@ -138,9 +150,8 @@ private void putTemplate(String name, LuceneIndexNodeContributor contributor) { } } - private void putNamedPredicate(String name, LuceneIndexNamedPredicateOptions options) { - Object previous = namedPredicates.putIfAbsent( name, options ); - if ( previous != null ) { + private void putNamedPredicate(String name) { + if ( !namedPredicates.add( name ) ) { throw MappingLog.INSTANCE.indexSchemaNamedPredicateNameConflict( name, eventContext() ); } } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/LuceneIndexNamedPredicateOptions.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/LuceneIndexNamedPredicateOptions.java index ac9f84d1734..900e7eee4e1 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/LuceneIndexNamedPredicateOptions.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/document/model/dsl/impl/LuceneIndexNamedPredicateOptions.java @@ -6,16 +6,8 @@ import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaNamedPredicateOptionsStep; import org.hibernate.search.engine.common.tree.spi.TreeNodeInclusion; -import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; - -public class LuceneIndexNamedPredicateOptions implements IndexSchemaNamedPredicateOptionsStep { - - public final TreeNodeInclusion inclusion; - public final PredicateDefinition definition; - - LuceneIndexNamedPredicateOptions(TreeNodeInclusion inclusion, PredicateDefinition definition) { - this.inclusion = inclusion; - this.definition = definition; - } +public record LuceneIndexNamedPredicateOptions( TreeNodeInclusion inclusion, + T definition) + implements IndexSchemaNamedPredicateOptionsStep { } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/IndexManagerBackendContext.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/IndexManagerBackendContext.java index 80c1373f668..d62bcdabc0c 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/IndexManagerBackendContext.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/IndexManagerBackendContext.java @@ -142,15 +142,15 @@ public IndexWorkspace createWorkspace(WorkExecutionIndexManagerContext indexMana } @Override - public LuceneSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, - Set indexManagerContexts) { - return new LuceneSearchIndexScopeImpl( mappingContext, this, analysisDefinitionRegistry, + public LuceneSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, + Class scopeRootType, Set indexManagerContexts) { + return new LuceneSearchIndexScopeImpl<>( mappingContext, scopeRootType, this, analysisDefinitionRegistry, multiTenancyStrategy, timingSource, indexManagerContexts ); } @Override public LuceneSearchQueryBuilder createSearchQueryBuilder( - LuceneSearchQueryIndexScope scope, + LuceneSearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder, LuceneSearchProjection rootProjection) { diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexManagerImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexManagerImpl.java index 0d5fb9b64b6..c7eeb93ee5b 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexManagerImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexManagerImpl.java @@ -142,9 +142,9 @@ public IndexWorkspace createWorkspace(BackendMappingContext mappingContext, Set< } @Override - public IndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext) { - return new LuceneIndexScopeBuilder( - backendContext, mappingContext, this + public IndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext, Class rootScopeType) { + return new LuceneIndexScopeBuilder<>( + backendContext, mappingContext, rootScopeType, this ); } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexScopeBuilder.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexScopeBuilder.java index dd7db555817..037639b5e79 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexScopeBuilder.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/index/impl/LuceneIndexScopeBuilder.java @@ -13,18 +13,21 @@ import org.hibernate.search.engine.backend.scope.spi.IndexScope; import org.hibernate.search.engine.backend.scope.spi.IndexScopeBuilder; -class LuceneIndexScopeBuilder implements IndexScopeBuilder { +class LuceneIndexScopeBuilder implements IndexScopeBuilder { private final IndexManagerBackendContext backendContext; private final BackendMappingContext mappingContext; + private final Class rootScopeType; // Use LinkedHashSet to ensure stable order when generating requests private final Set indexManagers = new LinkedHashSet<>(); LuceneIndexScopeBuilder(IndexManagerBackendContext backendContext, BackendMappingContext mappingContext, + Class rootScopeType, LuceneIndexManagerImpl indexManager) { this.backendContext = backendContext; this.mappingContext = mappingContext; + this.rootScopeType = rootScopeType; this.indexManagers.add( indexManager ); } @@ -38,8 +41,8 @@ void add(IndexManagerBackendContext backendContext, LuceneIndexManagerImpl index } @Override - public IndexScope build() { - return new LuceneIndexScopeImpl( backendContext, mappingContext, indexManagers ); + public IndexScope build() { + return new LuceneIndexScopeImpl<>( backendContext, mappingContext, rootScopeType, indexManagers ); } @Override diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/LuceneLog.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/LuceneLog.java index c8af86be7b3..eca1b449010 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/LuceneLog.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/LuceneLog.java @@ -63,6 +63,6 @@ public interface LuceneLog * here to the next value. */ @LogMessage(level = TRACE) - @Message(id = ID_OFFSET + 194, value = "") + @Message(id = ID_OFFSET + 195, value = "") void nextLoggerIdForConvenience(); } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/QueryLog.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/QueryLog.java index 67478f2d8bd..4054e8a2c7c 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/QueryLog.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/logging/impl/QueryLog.java @@ -324,4 +324,8 @@ SearchException vectorKnnMatchVectorTypeDiffersFromField(String absoluteFieldPat @Message(id = ID_OFFSET + 186, value = "A single-valued highlight projection requested, " + "but the corresponding highlighter does not set number of fragments to 1.") SearchException highlighterIncompatibleCardinality(); + + @Message(id = ID_OFFSET + 194, value = "Current factory cannot be resocped to '%1$s' as it is scoped to '%2$s'.") + SearchException incompatibleScopeRootType(@FormatWith(ClassFormatter.class) Class requested, + @FormatWith(ClassFormatter.class) Class actual); } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/impl/LuceneIndexScopeImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/impl/LuceneIndexScopeImpl.java index 3a08961c3b1..2a0a00e8529 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/impl/LuceneIndexScopeImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/impl/LuceneIndexScopeImpl.java @@ -18,15 +18,16 @@ import org.apache.lucene.index.IndexReader; -public class LuceneIndexScopeImpl - implements IndexScope, LuceneIndexScope { +public class LuceneIndexScopeImpl + implements IndexScope, LuceneIndexScope { - private final LuceneSearchQueryIndexScope searchScope; + private final LuceneSearchQueryIndexScope searchScope; public LuceneIndexScopeImpl(SearchBackendContext backendContext, BackendMappingContext mappingContext, + Class rootScopeType, Set indexManagerContexts) { - this.searchScope = backendContext.createSearchContext( mappingContext, indexManagerContexts ); + this.searchScope = backendContext.createSearchContext( mappingContext, rootScopeType, indexManagerContexts ); } @Override @@ -35,7 +36,7 @@ public String toString() { } @Override - public LuceneSearchQueryIndexScope searchScope() { + public LuceneSearchQueryIndexScope searchScope() { return searchScope; } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/model/impl/LuceneSearchIndexScopeImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/model/impl/LuceneSearchIndexScopeImpl.java index d3a375c0352..aea49477f35 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/model/impl/LuceneSearchIndexScopeImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/scope/model/impl/LuceneSearchIndexScopeImpl.java @@ -54,14 +54,15 @@ import org.apache.lucene.search.Query; -public final class LuceneSearchIndexScopeImpl +public final class LuceneSearchIndexScopeImpl extends AbstractSearchIndexScope< - LuceneSearchIndexScopeImpl, + SR, + LuceneSearchIndexScopeImpl, LuceneIndexModel, LuceneSearchIndexNodeContext, LuceneSearchIndexCompositeNodeContext> - implements LuceneSearchIndexScope, - LuceneSearchQueryIndexScope { + implements LuceneSearchIndexScope>, + LuceneSearchQueryIndexScope> { // Backend context private final SearchBackendContext backendContext; @@ -81,12 +82,13 @@ public final class LuceneSearchIndexScopeImpl private final LuceneSearchAggregationBuilderFactory aggregationBuilderFactory; public LuceneSearchIndexScopeImpl(BackendMappingContext mappingContext, + Class rootScopeType, SearchBackendContext backendContext, LuceneAnalysisDefinitionRegistry analysisDefinitionRegistry, MultiTenancyStrategy multiTenancyStrategy, TimingSource timingSource, Set indexManagerContexts) { - super( mappingContext, toModels( indexManagerContexts ) ); + super( mappingContext, rootScopeType, toModels( indexManagerContexts ) ); this.backendContext = backendContext; this.analysisDefinitionRegistry = analysisDefinitionRegistry; this.multiTenancyStrategy = multiTenancyStrategy; @@ -103,7 +105,7 @@ public LuceneSearchIndexScopeImpl(BackendMappingContext mappingContext, this.aggregationBuilderFactory = new LuceneSearchAggregationBuilderFactory( this ); } - private LuceneSearchIndexScopeImpl(LuceneSearchIndexScopeImpl parentScope, + private LuceneSearchIndexScopeImpl(LuceneSearchIndexScopeImpl parentScope, LuceneSearchIndexCompositeNodeContext overriddenRoot) { super( parentScope, overriddenRoot ); this.backendContext = parentScope.backendContext; @@ -125,13 +127,13 @@ private static Set toModels( } @Override - protected LuceneSearchIndexScopeImpl self() { + protected LuceneSearchIndexScopeImpl self() { return this; } @Override - public LuceneSearchIndexScopeImpl withRoot(String objectFieldPath) { - return new LuceneSearchIndexScopeImpl( this, field( objectFieldPath ).toComposite() ); + public LuceneSearchIndexScopeImpl withRoot(String objectFieldPath) { + return new LuceneSearchIndexScopeImpl<>( this, field( objectFieldPath ).toComposite() ); } @Override @@ -162,23 +164,23 @@ public

LuceneSearchQueryBuilder

select(BackendSessionContext sessionConte } @Override - public LuceneSearchPredicateFactory predicateFactory() { - return new LuceneSearchPredicateFactoryImpl<>( SearchPredicateDslContext.root( this ) ); + public LuceneSearchPredicateFactory predicateFactory() { + return new LuceneSearchPredicateFactoryImpl<>( rootScopeType, SearchPredicateDslContext.root( this ) ); } @Override - public LuceneSearchSortFactory sortFactory() { + public LuceneSearchSortFactory sortFactory() { return new LuceneSearchSortFactoryImpl<>( SearchSortDslContext .root( this, LuceneSearchSortFactoryImpl::new, predicateFactory() ) ); } @Override - public LuceneSearchProjectionFactory projectionFactory() { + public LuceneSearchProjectionFactory projectionFactory() { return new LuceneSearchProjectionFactoryImpl<>( SearchProjectionDslContext.root( this ) ); } @Override - public LuceneSearchAggregationFactory aggregationFactory() { + public LuceneSearchAggregationFactory aggregationFactory() { return new LuceneSearchAggregationFactoryImpl<>( SearchAggregationDslContext.root( this, predicateFactory() ) ); } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationExtractContext.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationExtractContext.java index fdead4da9b5..f8ad0b4fca4 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationExtractContext.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationExtractContext.java @@ -21,7 +21,7 @@ public class AggregationExtractContext { - private final LuceneSearchQueryIndexScope queryIndexScope; + private final LuceneSearchQueryIndexScope queryIndexScope; private final BackendSessionContext sessionContext; private final IndexReader indexReader; private final FromDocumentValueConvertContext fromDocumentValueConvertContext; @@ -29,7 +29,7 @@ public class AggregationExtractContext { private final Set routingKeys; private final QueryParameters parameters; - public AggregationExtractContext(LuceneSearchQueryIndexScope queryIndexScope, BackendSessionContext sessionContext, + public AggregationExtractContext(LuceneSearchQueryIndexScope queryIndexScope, BackendSessionContext sessionContext, IndexReader indexReader, FromDocumentValueConvertContext fromDocumentValueConvertContext, HibernateSearchMultiCollectorManager.MultiCollectedResults multiCollectedResults, Set routingKeys, diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationRequestContext.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationRequestContext.java index e16eedcc502..b7b87fc573a 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationRequestContext.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/aggregation/impl/AggregationRequestContext.java @@ -21,13 +21,13 @@ public final class AggregationRequestContext { - private final LuceneSearchQueryIndexScope queryIndexScope; + private final LuceneSearchQueryIndexScope queryIndexScope; private final BackendSessionContext sessionContext; private final Set routingKeys; private final ExtractionRequirements.Builder extractionRequirementsBuilder; private final QueryParameters parameters; - public AggregationRequestContext(LuceneSearchQueryIndexScope queryIndexScope, BackendSessionContext sessionContext, + public AggregationRequestContext(LuceneSearchQueryIndexScope queryIndexScope, BackendSessionContext sessionContext, Set routingKeys, ExtractionRequirements.Builder extractionRequirementsBuilder, QueryParameters parameters) { this.queryIndexScope = queryIndexScope; diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/dsl/impl/LuceneSearchPredicateFactoryImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/dsl/impl/LuceneSearchPredicateFactoryImpl.java index 9f3e6c99424..d2ac8134713 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/dsl/impl/LuceneSearchPredicateFactoryImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/dsl/impl/LuceneSearchPredicateFactoryImpl.java @@ -4,8 +4,10 @@ */ package org.hibernate.search.backend.lucene.search.predicate.dsl.impl; +import org.hibernate.search.backend.lucene.logging.impl.QueryLog; import org.hibernate.search.backend.lucene.search.predicate.dsl.LuceneSearchPredicateFactory; import org.hibernate.search.backend.lucene.search.predicate.impl.LuceneSearchPredicateIndexScope; +import org.hibernate.search.engine.search.common.NonStaticMetamodelScope; import org.hibernate.search.engine.search.predicate.dsl.PredicateFinalStep; import org.hibernate.search.engine.search.predicate.dsl.spi.AbstractSearchPredicateFactory; import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; @@ -20,13 +22,14 @@ public class LuceneSearchPredicateFactoryImpl LuceneSearchPredicateIndexScope> implements LuceneSearchPredicateFactory { - public LuceneSearchPredicateFactoryImpl(SearchPredicateDslContext> dslContext) { - super( dslContext ); + public LuceneSearchPredicateFactoryImpl(Class scopeRootType, + SearchPredicateDslContext> dslContext) { + super( scopeRootType, dslContext ); } @Override public LuceneSearchPredicateFactory withRoot(String objectFieldPath) { - return new LuceneSearchPredicateFactoryImpl<>( dslContext.rescope( + return new LuceneSearchPredicateFactoryImpl<>( scopeRootType, dslContext.rescope( dslContext.scope().withRoot( objectFieldPath ) ) ); } @@ -34,4 +37,23 @@ public LuceneSearchPredicateFactory withRoot(String objectFieldPath) { public PredicateFinalStep fromLuceneQuery(Query luceneQuery) { return new StaticPredicateFinalStep( dslContext.scope().predicateBuilders().fromLuceneQuery( luceneQuery ) ); } + + @SuppressWarnings("unchecked") // well because we check ;) + @Override + public LuceneSearchPredicateFactory withScopeRoot(Class scopeRootType) { + if ( this.scopeRootType.equals( scopeRootType ) ) { + return (LuceneSearchPredicateFactory) this; + } + if ( + // if we want the "untyped" version of the factory we can get it from any other factory + // e.g. we have one tied to a Book__ and we want to use some "raw" string paths in a named predicate. + scopeRootType.equals( NonStaticMetamodelScope.class ) + // scope type is in the same hierarchy: + || this.scopeRootType.isAssignableFrom( scopeRootType ) + || scopeRootType.isAssignableFrom( this.scopeRootType ) + ) { + return new LuceneSearchPredicateFactoryImpl<>( scopeRootType, dslContext ); + } + throw QueryLog.INSTANCE.incompatibleScopeRootType( scopeRootType, this.scopeRootType ); + } } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/LuceneNamedPredicate.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/LuceneNamedPredicate.java index 8da0453254e..3be2a23d3bc 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/LuceneNamedPredicate.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/LuceneNamedPredicate.java @@ -11,12 +11,18 @@ import org.hibernate.search.backend.lucene.search.common.impl.AbstractLuceneCompositeNodeSearchQueryElementFactory; import org.hibernate.search.backend.lucene.search.common.impl.LuceneSearchIndexCompositeNodeContext; import org.hibernate.search.backend.lucene.search.common.impl.LuceneSearchIndexScope; +import org.hibernate.search.engine.search.common.NonStaticMetamodelScope; import org.hibernate.search.engine.search.common.spi.SearchQueryElementFactory; import org.hibernate.search.engine.search.predicate.SearchPredicate; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; +import org.hibernate.search.engine.search.predicate.dsl.ExtendedSearchPredicateFactory; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateFactoryDelegate; import org.hibernate.search.engine.search.predicate.spi.NamedPredicateBuilder; import org.hibernate.search.engine.search.predicate.spi.NamedValuesBasedPredicateDefinitionContext; +import org.hibernate.search.engine.search.predicate.spi.NamedValuesBasedTypedPredicateDefinitionContext; import org.apache.lucene.search.Query; @@ -62,44 +68,108 @@ public void checkCompatibleWith(SearchQueryElementFactory other) { @Override public NamedPredicateBuilder create(LuceneSearchIndexScope scope, LuceneSearchIndexCompositeNodeContext node) { - return new Builder( definition, predicateName, scope, node ); + return new BasicBuilder( definition, predicateName, scope, node ); } } - private static class Builder extends AbstractBuilder implements NamedPredicateBuilder { - private final PredicateDefinition definition; + public static class TypedFactory + extends AbstractLuceneCompositeNodeSearchQueryElementFactory { + private final TypedPredicateDefinition definition; private final String predicateName; - private final LuceneSearchIndexCompositeNodeContext field; - private SearchPredicateFactory factory; - private final Map params = new LinkedHashMap<>(); - Builder(PredicateDefinition definition, String predicateName, LuceneSearchIndexScope scope, + public TypedFactory(TypedPredicateDefinition definition, String predicateName) { + this.definition = definition; + this.predicateName = predicateName; + } + + @Override + public void checkCompatibleWith(SearchQueryElementFactory other) { + super.checkCompatibleWith( other ); + TypedFactory castedOther = (TypedFactory) other; + if ( !definition.equals( castedOther.definition ) ) { + throw QueryLog.INSTANCE.differentPredicateDefinitionForQueryElement( definition, castedOther.definition ); + } + } + + @Override + public NamedPredicateBuilder create(LuceneSearchIndexScope scope, LuceneSearchIndexCompositeNodeContext node) { + return new TypedBuilder<>( definition, predicateName, scope, node ); + } + } + + private abstract static class Builder extends AbstractBuilder implements NamedPredicateBuilder { + protected final String predicateName; + protected final LuceneSearchIndexCompositeNodeContext field; + protected final Map params = new LinkedHashMap<>(); + + Builder(String predicateName, LuceneSearchIndexScope scope, LuceneSearchIndexCompositeNodeContext node) { super( scope, node ); - this.definition = definition; this.predicateName = predicateName; this.field = node; } @Override - public void factory(SearchPredicateFactory factory) { - this.factory = factory; + public final void param(String name, Object value) { + params.put( name, value ); + } + + protected abstract LuceneSearchPredicate providedPredicate(); + + @Override + public final SearchPredicate build() { + return new LuceneNamedPredicate( this, providedPredicate() ); + } + } + + private static class BasicBuilder extends Builder { + private final PredicateDefinition definition; + private SearchPredicateFactory factory; + + BasicBuilder(PredicateDefinition definition, String predicateName, LuceneSearchIndexScope scope, + LuceneSearchIndexCompositeNodeContext node) { + super( predicateName, scope, node ); + this.definition = definition; } + @SuppressWarnings("unchecked") @Override - public void param(String name, Object value) { - params.put( name, value ); + public void factory(ExtendedSearchPredicateFactory factory) { + this.factory = new SearchPredicateFactoryDelegate( factory.withScopeRoot( NonStaticMetamodelScope.class ) ); } @Override - public SearchPredicate build() { - NamedValuesBasedPredicateDefinitionContext ctx = - new NamedValuesBasedPredicateDefinitionContext<>( factory, params, + protected LuceneSearchPredicate providedPredicate() { + NamedValuesBasedPredicateDefinitionContext ctx = + new NamedValuesBasedPredicateDefinitionContext( factory, params, name -> QueryLog.INSTANCE.paramNotDefined( name, predicateName, field.eventContext() ) ); - LuceneSearchPredicate providedPredicate = LuceneSearchPredicate.from( scope, definition.create( ctx ) ); + return LuceneSearchPredicate.from( scope, definition.create( ctx ) ); + } + } + + private static class TypedBuilder extends Builder { + private final TypedPredicateDefinition definition; + private TypedSearchPredicateFactory factory; + + TypedBuilder(TypedPredicateDefinition definition, String predicateName, LuceneSearchIndexScope scope, + LuceneSearchIndexCompositeNodeContext node) { + super( predicateName, scope, node ); + this.definition = definition; + } + + @SuppressWarnings("unchecked") + @Override + public void factory(ExtendedSearchPredicateFactory factory) { + this.factory = factory.withScopeRoot( definition.scopeRootType() ); + } + + @Override + protected LuceneSearchPredicate providedPredicate() { + var ctx = new NamedValuesBasedTypedPredicateDefinitionContext<>( factory, params, + name -> QueryLog.INSTANCE.paramNotDefined( name, predicateName, field.eventContext() ) ); - return new LuceneNamedPredicate( this, providedPredicate ); + return LuceneSearchPredicate.from( scope, definition.create( ctx ) ); } } } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/PredicateRequestContext.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/PredicateRequestContext.java index ebfa5400833..722472c10ca 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/PredicateRequestContext.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/predicate/impl/PredicateRequestContext.java @@ -37,7 +37,7 @@ public String getNestedPath() { public abstract NamedValues queryParameters(); - public static PredicateRequestContext withSession(LuceneSearchQueryIndexScope scope, + public static PredicateRequestContext withSession(LuceneSearchQueryIndexScope scope, BackendSessionContext sessionContext, Set routingKeys, QueryParameters parameters) { Contracts.assertNotNull( scope, "scope" ); Contracts.assertNotNull( scope, "sessionContext" ); @@ -89,13 +89,13 @@ public Optional getOptional(String parameterName, Class parameterValue } private static class FullPredicateRequestContext extends PredicateRequestContext { - private final LuceneSearchQueryIndexScope scope; + private final LuceneSearchQueryIndexScope scope; private final BackendSessionContext sessionContext; private final Set routingKeys; private final QueryParameters parameters; - private FullPredicateRequestContext(String nestedPath, LuceneSearchQueryIndexScope scope, + private FullPredicateRequestContext(String nestedPath, LuceneSearchQueryIndexScope scope, BackendSessionContext sessionContext, Set routingKeys, QueryParameters parameters) { super( nestedPath ); this.scope = scope; diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/LuceneSearchProjectionFactory.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/LuceneSearchProjectionFactory.java index 94d8717e4c0..6e6222c30ac 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/LuceneSearchProjectionFactory.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/LuceneSearchProjectionFactory.java @@ -6,7 +6,7 @@ import org.hibernate.search.engine.search.projection.dsl.ExtendedSearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; +import org.hibernate.search.engine.search.projection.dsl.TypedSearchProjectionFactory; import org.hibernate.search.util.common.annotation.Incubating; import org.apache.lucene.document.Document; @@ -18,7 +18,7 @@ * @param Scope root type. * @param The type of entity references. * @param The type of entities. - * @see SearchProjectionFactory + * @see TypedSearchProjectionFactory */ public interface LuceneSearchProjectionFactory extends ExtendedSearchProjectionFactory, R, E> { diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java index 8b1d8c2d554..320d54db314 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java @@ -7,6 +7,7 @@ import org.hibernate.search.backend.lucene.search.projection.dsl.DocumentTree; import org.hibernate.search.backend.lucene.search.projection.dsl.LuceneSearchProjectionFactory; import org.hibernate.search.backend.lucene.search.projection.impl.LuceneSearchProjectionIndexScope; +import org.hibernate.search.engine.search.projection.dsl.ExtendedSearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; import org.hibernate.search.engine.search.projection.dsl.spi.AbstractSearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; @@ -34,6 +35,11 @@ public LuceneSearchProjectionFactory withRoot(String objectFieldPath) dslContext.scope().withRoot( objectFieldPath ) ) ); } + @Override + public ExtendedSearchProjectionFactory withScopeRoot(Class scopeRootType) { + return new LuceneSearchProjectionFactoryImpl<>( dslContext ); + } + @Override public ProjectionFinalStep document() { return new StaticProjectionFinalStep<>( dslContext.scope().projectionBuilders().document() ); diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/impl/LuceneDocumentTreeProjection.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/impl/LuceneDocumentTreeProjection.java index 237b0f61a91..9459443f838 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/impl/LuceneDocumentTreeProjection.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/impl/LuceneDocumentTreeProjection.java @@ -39,7 +39,7 @@ class LuceneDocumentTreeProjection extends AbstractLuceneProjection nestedObjectsPaths; private final List models; - LuceneDocumentTreeProjection(LuceneSearchIndexScopeImpl scope) { + LuceneDocumentTreeProjection(LuceneSearchIndexScopeImpl scope) { super( scope ); nestedObjectsPaths = new LinkedHashSet<>(); models = new ArrayList<>(); diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQueryOptionsStepImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQueryOptionsStepImpl.java index 3515b979882..fa536a796c2 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQueryOptionsStepImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQueryOptionsStepImpl.java @@ -29,12 +29,12 @@ class LuceneSearchQueryOptionsStepImpl LuceneSearchPredicateFactory, LuceneSearchSortFactory, LuceneSearchAggregationFactory, - LuceneSearchQueryIndexScope> + LuceneSearchQueryIndexScope> implements LuceneSearchQueryWhereStep, LuceneSearchQueryOptionsStep { private final LuceneSearchQueryBuilder searchQueryBuilder; - LuceneSearchQueryOptionsStepImpl(LuceneSearchQueryIndexScope scope, + LuceneSearchQueryOptionsStepImpl(LuceneSearchQueryIndexScope scope, LuceneSearchQueryBuilder searchQueryBuilder, SearchLoadingContextBuilder loadingContextBuilder) { super( scope, searchQueryBuilder, loadingContextBuilder ); diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQuerySelectStepImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQuerySelectStepImpl.java index 2a1283cb6e3..f9fd4332b7a 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQuerySelectStepImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/dsl/impl/LuceneSearchQuerySelectStepImpl.java @@ -37,11 +37,11 @@ public class LuceneSearchQuerySelectStepImpl LuceneSearchPredicateFactory> implements LuceneSearchQuerySelectStep { - private final LuceneSearchQueryIndexScope scope; + private final LuceneSearchQueryIndexScope scope; private final BackendSessionContext sessionContext; private final SearchLoadingContextBuilder loadingContextBuilder; - public LuceneSearchQuerySelectStepImpl(LuceneSearchQueryIndexScope scope, + public LuceneSearchQuerySelectStepImpl(LuceneSearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder) { this.scope = scope; @@ -51,7 +51,7 @@ public LuceneSearchQuerySelectStepImpl(LuceneSearchQueryIndexScope scope, @Override public LuceneSearchQueryWhereStep selectEntity() { - return select( scope.projectionFactory().entity().toProjection() ); + return select( scope.projectionFactory().entity().toProjection() ); } @Override @@ -104,7 +104,7 @@ public LuceneSearchQueryOptionsStep where( } @Override - protected LuceneSearchQueryIndexScope scope() { + protected LuceneSearchQueryIndexScope scope() { return scope; } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryBuilder.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryBuilder.java index 4d657022c4d..6bcf85e9ac6 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryBuilder.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryBuilder.java @@ -54,7 +54,7 @@ public class LuceneSearchQueryBuilder implements SearchQueryBuilder, Lucen private final LuceneWorkFactory workFactory; private final LuceneSyncWorkOrchestrator queryOrchestrator; - private final LuceneSearchQueryIndexScope scope; + private final LuceneSearchQueryIndexScope scope; private final BackendSessionContext sessionContext; private final Set routingKeys; @@ -76,7 +76,7 @@ public class LuceneSearchQueryBuilder implements SearchQueryBuilder, Lucen public LuceneSearchQueryBuilder( LuceneWorkFactory workFactory, LuceneSyncWorkOrchestrator queryOrchestrator, - LuceneSearchQueryIndexScope scope, + LuceneSearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder, LuceneSearchProjection rootProjection) { diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryImpl.java index 32b8f0bdaa0..2f811849080 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryImpl.java @@ -38,7 +38,7 @@ public class LuceneSearchQueryImpl extends AbstractSearchQuery scope; + private final LuceneSearchQueryIndexScope scope; private final BackendSessionContext sessionContext; private final SearchLoadingContext loadingContext; private final Set routingKeys; @@ -50,7 +50,7 @@ public class LuceneSearchQueryImpl extends AbstractSearchQuery scope, + LuceneWorkFactory workFactory, LuceneSearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContext loadingContext, Set routingKeys, diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryIndexScope.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryIndexScope.java index 026703216b8..c7d78629788 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryIndexScope.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryIndexScope.java @@ -26,8 +26,8 @@ import org.apache.lucene.search.Query; -public interface LuceneSearchQueryIndexScope> - extends SearchQueryIndexScope, LuceneSearchIndexScope, +public interface LuceneSearchQueryIndexScope> + extends SearchQueryIndexScope, LuceneSearchIndexScope, LuceneSearchPredicateIndexScope, LuceneSearchSortIndexScope, LuceneSearchProjectionIndexScope, LuceneSearchAggregationIndexScope { @@ -36,16 +36,16 @@

LuceneSearchQueryBuilder

select(BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder, SearchProjection

projection); @Override - LuceneSearchPredicateFactory predicateFactory(); + LuceneSearchPredicateFactory predicateFactory(); @Override - LuceneSearchSortFactory sortFactory(); + LuceneSearchSortFactory sortFactory(); @Override - LuceneSearchProjectionFactory projectionFactory(); + LuceneSearchProjectionFactory projectionFactory(); @Override - LuceneSearchAggregationFactory aggregationFactory(); + LuceneSearchAggregationFactory aggregationFactory(); Query filterOrNull(String tenantId); diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryRequestContext.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryRequestContext.java index 3ec9015ce6f..6a39ca4e9f9 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryRequestContext.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchQueryRequestContext.java @@ -19,7 +19,7 @@ */ class LuceneSearchQueryRequestContext { - private final LuceneSearchQueryIndexScope queryIndexScope; + private final LuceneSearchQueryIndexScope queryIndexScope; private final BackendSessionContext sessionContext; private final SearchLoadingContext loadingContext; private final Query luceneQuery; @@ -28,7 +28,7 @@ class LuceneSearchQueryRequestContext { private final QueryParameters parameters; LuceneSearchQueryRequestContext( - LuceneSearchQueryIndexScope queryIndexScope, BackendSessionContext sessionContext, + LuceneSearchQueryIndexScope queryIndexScope, BackendSessionContext sessionContext, SearchLoadingContext loadingContext, Query luceneQuery, Sort luceneSort, @@ -42,7 +42,7 @@ class LuceneSearchQueryRequestContext { this.parameters = parameters; } - public LuceneSearchQueryIndexScope getQueryIndexScope() { + public LuceneSearchQueryIndexScope getQueryIndexScope() { return queryIndexScope; } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchScrollImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchScrollImpl.java index 95be6c76fc8..b0ab8df265d 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchScrollImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/LuceneSearchScrollImpl.java @@ -26,7 +26,7 @@ public class LuceneSearchScrollImpl implements LuceneSearchScroll { // shared with its query instance: private final LuceneSyncWorkOrchestrator queryOrchestrator; private final LuceneWorkFactory workFactory; - private final LuceneSearchQueryIndexScope scope; + private final LuceneSearchQueryIndexScope scope; private final Set routingKeys; private final TimeoutManager timeoutManager; private final LuceneSearcher, LuceneExtractableSearchResult> searcher; @@ -42,7 +42,7 @@ public class LuceneSearchScrollImpl implements LuceneSearchScroll { private int currentPageOffset = 0; public LuceneSearchScrollImpl(LuceneSyncWorkOrchestrator queryOrchestrator, - LuceneWorkFactory workFactory, LuceneSearchQueryIndexScope scope, + LuceneWorkFactory workFactory, LuceneSearchQueryIndexScope scope, Set routingKeys, TimeoutManager timeoutManager, LuceneSearcher, LuceneExtractableSearchResult> searcher, diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/SearchBackendContext.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/SearchBackendContext.java index f6f1cf3c8b3..afeab35f056 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/SearchBackendContext.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/query/impl/SearchBackendContext.java @@ -25,11 +25,12 @@ */ public interface SearchBackendContext { - LuceneSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, + LuceneSearchQueryIndexScope createSearchContext(BackendMappingContext mappingContext, + Class rootScopeType, Set indexManagerContexts); LuceneSearchQueryBuilder createSearchQueryBuilder( - LuceneSearchQueryIndexScope scope, + LuceneSearchQueryIndexScope scope, BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder, LuceneSearchProjection rootProjection); diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/namedpredicate/SkuIdentifierBinder.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/namedpredicate/SkuIdentifierBinder.java index da1f2cb468f..5cdabffd55f 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/namedpredicate/SkuIdentifierBinder.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/namedpredicate/SkuIdentifierBinder.java @@ -12,7 +12,9 @@ import org.hibernate.search.engine.search.predicate.SearchPredicate; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinitionContext; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinitionContext; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.mapper.pojo.bridge.PropertyBridge; import org.hibernate.search.mapper.pojo.bridge.binding.PropertyBindingContext; import org.hibernate.search.mapper.pojo.bridge.mapping.programmatic.PropertyBinder; @@ -45,6 +47,38 @@ public void bind(PropertyBindingContext context) { "skuIdMatch", // <2> new SkuIdentifierMatchPredicateDefinition() // <3> ); + + skuIdObjectField.namedPredicate( // <1> + "skuIdMatch2", // <2> + new TypedPredicateDefinition() { + + @Override + public SearchPredicate create(TypedPredicateDefinitionContext context) { + return null; + } + + @Override + public Class scopeRootType() { + return SkuIdentifierBinder.class; + } + } // <3> + ); + + skuIdObjectField.namedPredicate( // <1> + "skuIdMatch3", // <2> + new TypedPredicateDefinition<>() { + + @Override + public SearchPredicate create(TypedPredicateDefinitionContext context) { + return null; + } + + @Override + public Class scopeRootType() { + return Object.class; + } + } // <3> + ); } // ... class continues below @@ -88,8 +122,8 @@ public void write(DocumentElement target, String skuId, PropertyBridgeWriteConte private static class SkuIdentifierMatchPredicateDefinition implements PredicateDefinition { // <1> @Override - public SearchPredicate create(PredicateDefinitionContext context) { - SearchPredicateFactory f = context.predicate(); // <2> + public SearchPredicate create(PredicateDefinitionContext context) { + TypedSearchPredicateFactory f = context.predicate(); // <2> String pattern = context.params().get( "pattern", String.class ); // <3> diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/constructorparameter/MyFieldProjectionBinder.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/constructorparameter/MyFieldProjectionBinder.java index b7ecbd508bc..483c38860d8 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/constructorparameter/MyFieldProjectionBinder.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/constructorparameter/MyFieldProjectionBinder.java @@ -7,7 +7,6 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinition; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinitionContext; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBinder; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBindingContext; @@ -31,9 +30,8 @@ private MyProjectionDefinition(String fieldName) { } @Override - public SearchProjection create(SearchProjectionFactory factory, - ProjectionDefinitionContext context) { - return factory.field( fieldName, String.class ) // <3> + public SearchProjection create(ProjectionDefinitionContext context) { + return context.projection().field( fieldName, String.class ) // <3> .toProjection(); } } diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/multi/MyFieldProjectionBinder.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/multi/MyFieldProjectionBinder.java index b45d0c8f3ad..99415ba4f29 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/multi/MyFieldProjectionBinder.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/multi/MyFieldProjectionBinder.java @@ -11,7 +11,6 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinition; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinitionContext; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.mapper.pojo.model.PojoModelValue; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBinder; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBindingContext; @@ -32,9 +31,8 @@ public void bind(ProjectionBindingContext context) { private static class MyProjectionDefinition implements ProjectionDefinition> { // <4> @Override - public SearchProjection> create(SearchProjectionFactory factory, - ProjectionDefinitionContext context) { - return factory.field( "tags", String.class ) + public SearchProjection> create(ProjectionDefinitionContext context) { + return context.projection().field( "tags", String.class ) .collector( ProjectionCollector.list() ) // <4> .toProjection(); } diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/annotation/MyFieldProjectionBinder.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/annotation/MyFieldProjectionBinder.java index 5c3317e60fb..66a6ee26529 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/annotation/MyFieldProjectionBinder.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/annotation/MyFieldProjectionBinder.java @@ -7,7 +7,6 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinition; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinitionContext; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBinder; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBindingContext; @@ -39,9 +38,8 @@ public MyProjectionDefinition(String fieldName) { // <2> } @Override - public SearchProjection create(SearchProjectionFactory factory, - ProjectionDefinitionContext context) { - return factory.field( fieldName, String.class ) // <3> + public SearchProjection create(ProjectionDefinitionContext context) { + return context.projection().field( fieldName, String.class ) // <3> .toProjection(); } } diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/string/MyFieldProjectionBinder.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/string/MyFieldProjectionBinder.java index f98e6497247..9be4f511d3a 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/string/MyFieldProjectionBinder.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/param/string/MyFieldProjectionBinder.java @@ -7,7 +7,6 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinition; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinitionContext; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBinder; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBindingContext; @@ -32,9 +31,8 @@ public MyProjectionDefinition(String fieldName) { // <2> } @Override - public SearchProjection create(SearchProjectionFactory factory, - ProjectionDefinitionContext context) { - return factory.field( fieldName, String.class ) // <3> + public SearchProjection create(ProjectionDefinitionContext context) { + return context.projection().field( fieldName, String.class ) // <3> .toProjection(); } } diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/simple/MyFieldProjectionBinder.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/simple/MyFieldProjectionBinder.java index e8b3cfdecc2..6dbf6a4f759 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/simple/MyFieldProjectionBinder.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/binding/projectionbinder/simple/MyFieldProjectionBinder.java @@ -7,7 +7,6 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinition; import org.hibernate.search.engine.search.projection.definition.ProjectionDefinitionContext; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBinder; import org.hibernate.search.mapper.pojo.search.definition.binding.ProjectionBindingContext; @@ -29,9 +28,8 @@ public void bind(ProjectionBindingContext context) { // <2> private static class MyProjectionDefinition // <1> implements ProjectionDefinition { // <2> @Override - public SearchProjection create(SearchProjectionFactory factory, - ProjectionDefinitionContext context) { - return factory.field( "title", String.class ) // <3> + public SearchProjection create(ProjectionDefinitionContext context) { + return context.projection().field( "title", String.class ) // <3> .toProjection(); // <4> } } diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/entrypoints/HibernateOrmEntryPointsIT.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/entrypoints/HibernateOrmEntryPointsIT.java index e1c8df2b9f3..bd584a3fb5a 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/entrypoints/HibernateOrmEntryPointsIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/entrypoints/HibernateOrmEntryPointsIT.java @@ -102,13 +102,13 @@ void searchScope_fromSearchMapping() { // end::searchScope-fromSearchMapping[] Search.mapping( theSessionFactory ); // tag::searchScope-fromSearchMapping[] - SearchScope bookScope = searchMapping.scope( Book.class ); // <2> - SearchScope associateAndManagerScope = + SearchScope bookScope = searchMapping.scope( Book.class ); // <2> + SearchScope associateAndManagerScope = searchMapping.scope( Arrays.asList( Associate.class, Manager.class ) ); // <3> - SearchScope personScope = searchMapping.scope( Person.class ); // <4> - SearchScope personSubTypesScope = searchMapping.scope( Person.class, + SearchScope personScope = searchMapping.scope( Person.class ); // <4> + SearchScope personSubTypesScope = searchMapping.scope( Person.class, Arrays.asList( "Manager", "Associate" ) ); // <5> - SearchScope allScope = searchMapping.scope( Object.class ); // <6> + SearchScope allScope = searchMapping.scope( Object.class ); // <6> // end::searchScope-fromSearchMapping[] assertThat( bookScope.includedTypes() ) .extracting( SearchIndexedEntity::jpaName ) @@ -135,13 +135,13 @@ void searchScope_fromSearchSession() { // end::searchScope-fromSearchSession[] Search.session( theSession ); // tag::searchScope-fromSearchSession[] - SearchScope bookScope = searchSession.scope( Book.class ); // <2> - SearchScope associateAndManagerScope = + SearchScope bookScope = searchSession.scope( Book.class ); // <2> + SearchScope associateAndManagerScope = searchSession.scope( Arrays.asList( Associate.class, Manager.class ) ); // <3> - SearchScope personScope = searchSession.scope( Person.class ); // <4> - SearchScope personSubTypesScope = searchSession.scope( Person.class, + SearchScope personScope = searchSession.scope( Person.class ); // <4> + SearchScope personSubTypesScope = searchSession.scope( Person.class, Arrays.asList( "Manager", "Associate" ) ); // <5> - SearchScope allScope = searchSession.scope( Object.class ); // <6> + SearchScope allScope = searchSession.scope( Object.class ); // <6> // end::searchScope-fromSearchSession[] assertThat( bookScope.includedTypes() ) .extracting( SearchIndexedEntity::jpaName ) diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java index 9ac10fc6ffd..9372014968a 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/orm/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java @@ -99,7 +99,7 @@ void test() { // Not shown: get the entity manager and open a transaction SearchSession searchSession = Search.session( entityManager ); // <1> - SearchScope scope = searchSession.scope( Book.class ); // <2> + SearchScope scope = searchSession.scope( Book.class ); // <2> SearchResult result = searchSession.search( scope ) // <3> .where( scope.predicate().match() // <4> diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/entrypoints/StandalonePojoEntryPointsIT.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/entrypoints/StandalonePojoEntryPointsIT.java index 97d93a883c6..53caf50365c 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/entrypoints/StandalonePojoEntryPointsIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/entrypoints/StandalonePojoEntryPointsIT.java @@ -114,13 +114,13 @@ void searchSession_withOptions() { @Test void searchScope_fromSearchMapping() { SearchMapping searchMapping = theSearchMapping; - SearchScope bookScope = searchMapping.scope( Book.class ); - SearchScope associateAndManagerScope = + SearchScope bookScope = searchMapping.scope( Book.class ); + SearchScope associateAndManagerScope = searchMapping.scope( Arrays.asList( Associate.class, Manager.class ) ); - SearchScope personScope = searchMapping.scope( Person.class ); - SearchScope personSubTypesScope = searchMapping.scope( Person.class, + SearchScope personScope = searchMapping.scope( Person.class ); + SearchScope personSubTypesScope = searchMapping.scope( Person.class, Arrays.asList( "Manager", "Associate" ) ); - SearchScope allScope = searchMapping.scope( Object.class ); + SearchScope allScope = searchMapping.scope( Object.class ); assertThat( bookScope.includedTypes() ) .extracting( SearchIndexedEntity::name ) .containsExactlyInAnyOrder( "Book" ); @@ -142,13 +142,13 @@ void searchScope_fromSearchMapping() { void searchScope_fromSearchSession() { SearchMapping searchMapping = theSearchMapping; try ( SearchSession searchSession = searchMapping.createSession() ) { - SearchScope bookScope = searchSession.scope( Book.class ); - SearchScope associateAndManagerScope = + SearchScope bookScope = searchSession.scope( Book.class ); + SearchScope associateAndManagerScope = searchSession.scope( Arrays.asList( Associate.class, Manager.class ) ); - SearchScope personScope = searchSession.scope( Person.class ); - SearchScope personSubTypesScope = searchSession.scope( Person.class, + SearchScope personScope = searchSession.scope( Person.class ); + SearchScope personSubTypesScope = searchSession.scope( Person.class, Arrays.asList( "Manager", "Associate" ) ); - SearchScope allScope = searchSession.scope( Object.class ); + SearchScope allScope = searchSession.scope( Object.class ); assertThat( bookScope.includedTypes() ) .extracting( SearchIndexedEntity::name ) .containsExactlyInAnyOrder( "Book" ); diff --git a/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java b/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java index 5d299f90fcc..2ea915c665b 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/mapper/pojo/standalone/gettingstarted/withhsearch/defaultanalysis/GettingStartedDefaultAnalysisIT.java @@ -102,7 +102,7 @@ void test() { // tag::searching-objects[] try ( SearchSession session = searchMapping.createSession() ) { // <1> - SearchScope scope = session.scope( Book.class ); // <2> + SearchScope scope = session.scope( Book.class ); // <2> SearchResult result = session.search( scope ) // <3> .select( f -> f.id( Integer.class ) ) // <4> diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/aggregation/AggregationDslIT.java b/documentation/src/test/java/org/hibernate/search/documentation/search/aggregation/AggregationDslIT.java index 8b1dcd7b601..fb1e2ef83a1 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/aggregation/AggregationDslIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/aggregation/AggregationDslIT.java @@ -85,7 +85,7 @@ void entryPoint() { Search.session( entityManager ); // tag::entryPoint-objects[] - SearchScope scope = searchSession.scope( Book.class ); + SearchScope scope = searchSession.scope( Book.class ); AggregationKey> countsByGenreKey = AggregationKey.of( "countsByGenre" ); diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/paths/FieldPathsIT.java b/documentation/src/test/java/org/hibernate/search/documentation/search/paths/FieldPathsIT.java index b8cb092ad01..bae23e8e39f 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/paths/FieldPathsIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/paths/FieldPathsIT.java @@ -15,7 +15,7 @@ import org.hibernate.search.documentation.testsupport.BackendConfigurations; import org.hibernate.search.documentation.testsupport.DocumentationSetupHelper; import org.hibernate.search.engine.search.predicate.SearchPredicate; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.mapper.orm.Search; import org.hibernate.search.mapper.orm.session.SearchSession; @@ -114,7 +114,7 @@ void withRoot() { } // tag::withRoot_method[] - private SearchPredicate matchFirstAndLastName(SearchPredicateFactory f, + private SearchPredicate matchFirstAndLastName(TypedSearchPredicateFactory f, String firstName, String lastName) { return f.and( f.match().field( "firstName" ) // <1> diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/FieldReferenceIT.java b/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/FieldReferenceIT.java index 2ee82df3b42..055fb2c3a15 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/FieldReferenceIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/FieldReferenceIT.java @@ -24,7 +24,7 @@ import org.hibernate.search.engine.backend.types.Projectable; import org.hibernate.search.engine.search.common.ValueModel; import org.hibernate.search.engine.search.predicate.dsl.PredicateFinalStep; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.object.ObjectFieldReference; import org.hibernate.search.engine.search.reference.predicate.ExistsPredicateFieldReference; import org.hibernate.search.engine.search.reference.predicate.MatchPredicateFieldReference; @@ -34,6 +34,7 @@ import org.hibernate.search.mapper.orm.scope.HibernateOrmRootReferenceScope; import org.hibernate.search.mapper.orm.scope.SearchScope; import org.hibernate.search.mapper.orm.scope.SearchScopeProvider; +import org.hibernate.search.mapper.orm.scope.TypedSearchScope; import org.hibernate.search.mapper.orm.session.SearchSession; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; @@ -64,7 +65,7 @@ void setup() { void smoke() { withinSearchSession( searchSession -> { - SearchScope scope = ContainingA__.INDEX.scope( searchSession ); + TypedSearchScope scope = ContainingA__.INDEX.scope( searchSession ); assertThat( searchSession.search( scope ) @@ -96,13 +97,13 @@ void smoke() { public static > PredicateFinalStep utilMethodForPredicate( - SearchPredicateFactory factory, ContainingA_e1_e2_Intersection reference) { + TypedSearchPredicateFactory factory, ContainingA_e1_e2_Intersection reference) { return factory.match().field( reference.a() ).matching( "a" ); } public static PredicateFinalStep utilMethodForPredicateNoProjection( - SearchPredicateFactory factory, ContainingA_e1_e2_e3_Intersection reference) { + TypedSearchPredicateFactory factory, ContainingA_e1_e2_e3_Intersection reference) { return factory.match().field( reference.a() ).matching( "a" ); } @@ -110,7 +111,7 @@ public static PredicateFinalStep utilMethodForPredica void smoke2() { withinSearchSession( searchSession -> { - SearchScope scope = searchSession.scope( List.of( ContainingA.class ) ); + SearchScope scope = searchSession.scope( List.of( ContainingA.class ) ); assertThat( searchSession.search( scope ) @@ -293,8 +294,8 @@ public ContainingA__() { } @Override - public SearchScope scope(SearchScopeProvider scopeProvider) { - return scopeProvider.scope( ContainingA.class ); + public TypedSearchScope scope(SearchScopeProvider scopeProvider) { + return scopeProvider.typedScope( ContainingA__.class, List.of( ContainingA.class ) ); } @Override diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/PredicateDslIT.java b/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/PredicateDslIT.java index b74f6b0f333..382f16f035b 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/PredicateDslIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/predicate/PredicateDslIT.java @@ -118,7 +118,7 @@ void entryPoint() { Search.session( entityManager ); // tag::entryPoint-objects[] - SearchScope scope = searchSession.scope( Book.class ); + SearchScope scope = searchSession.scope( Book.class ); List result = searchSession.search( scope ) .where( scope.predicate().match().field( "title" ) diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java b/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java index 1b822f0bc26..2801f65fc0f 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/projection/ProjectionDslIT.java @@ -96,7 +96,7 @@ void entryPoint() { Search.session( entityManager ); // tag::entryPoint-objects[] - SearchScope scope = searchSession.scope( Book.class ); + SearchScope scope = searchSession.scope( Book.class ); List result = searchSession.search( scope ) .select( scope.projection().field( "title", String.class ) diff --git a/documentation/src/test/java/org/hibernate/search/documentation/search/sort/SortDslIT.java b/documentation/src/test/java/org/hibernate/search/documentation/search/sort/SortDslIT.java index dd974590a56..637ef0454c4 100644 --- a/documentation/src/test/java/org/hibernate/search/documentation/search/sort/SortDslIT.java +++ b/documentation/src/test/java/org/hibernate/search/documentation/search/sort/SortDslIT.java @@ -74,7 +74,7 @@ void entryPoint() { Search.session( entityManager ); // tag::entryPoint-objects[] - SearchScope scope = searchSession.scope( Book.class ); + SearchScope scope = searchSession.scope( Book.class ); List result = searchSession.search( scope ) .where( scope.predicate().matchAll().toPredicate() ) diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/IndexSchemaElement.java b/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/IndexSchemaElement.java index 7c5374ffa55..2bc9ba628e1 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/IndexSchemaElement.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/IndexSchemaElement.java @@ -12,6 +12,7 @@ import org.hibernate.search.engine.backend.types.dsl.IndexFieldTypeFactory; import org.hibernate.search.engine.backend.types.dsl.IndexFieldTypeFinalStep; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -74,6 +75,18 @@ IndexSchemaFieldOptionsStep> field(String relative IndexSchemaNamedPredicateOptionsStep namedPredicate( String relativeNamedPredicateName, PredicateDefinition definition); + /** + * Add a named predicate factory to this index schema element. + * + * @param relativeNamedPredicateName The relative name of the new named predicate. + * @param definition The definition of the named predicate. + * @return A DSL step where the named predicate can be defined in more details. + * @see PredicateDefinition + */ + @Incubating + IndexSchemaNamedPredicateOptionsStep namedPredicate( + String relativeNamedPredicateName, TypedPredicateDefinition definition); + /** * Add an object field to this index schema element with the default structure. * diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/impl/IndexSchemaElementImpl.java b/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/impl/IndexSchemaElementImpl.java index 56980b531c3..23199cfe7c3 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/impl/IndexSchemaElementImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/impl/IndexSchemaElementImpl.java @@ -22,6 +22,7 @@ import org.hibernate.search.engine.common.tree.spi.TreeNestingContext; import org.hibernate.search.engine.logging.impl.MappingLog; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; import org.hibernate.search.util.common.impl.StringHelper; public class IndexSchemaElementImpl implements IndexSchemaElement { @@ -77,6 +78,17 @@ public IndexSchemaNamedPredicateOptionsStep namedPredicate(String relativeNamedP ); } + @Override + public IndexSchemaNamedPredicateOptionsStep namedPredicate(String relativeNamedPredicateName, + TypedPredicateDefinition definition) { + checkRelativeNamedPredicateName( relativeNamedPredicateName ); + return nestingContext.nestUnfiltered( + (inclusion, prefix) -> + // Ignore the prefix: it's not relevant here, and it's a deprecated feature anyway. + objectNodeBuilder.addNamedPredicate( relativeNamedPredicateName, inclusion, definition ) + ); + } + @Override public IndexSchemaFieldOptionsStep> field(String relativeFieldName, Function> typeContributor) { diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/spi/IndexCompositeNodeBuilder.java b/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/spi/IndexCompositeNodeBuilder.java index 0b36d43d8d4..ef9c9473ea2 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/spi/IndexCompositeNodeBuilder.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/document/model/dsl/spi/IndexCompositeNodeBuilder.java @@ -12,6 +12,8 @@ import org.hibernate.search.engine.backend.types.ObjectStructure; import org.hibernate.search.engine.common.tree.spi.TreeNodeInclusion; import org.hibernate.search.engine.search.predicate.definition.PredicateDefinition; +import org.hibernate.search.engine.search.predicate.definition.TypedPredicateDefinition; +import org.hibernate.search.util.common.annotation.Incubating; public interface IndexCompositeNodeBuilder extends IndexSchemaBuildContext { @@ -38,6 +40,18 @@ IndexSchemaFieldOptionsStep> addField(String relat IndexSchemaNamedPredicateOptionsStep addNamedPredicate(String relativeNamedPredicateName, TreeNodeInclusion inclusion, PredicateDefinition definition); + /** + * Create a new named predicate and add it to the current builder. + * + * @param relativeNamedPredicateName The relative name of the new named predicate. + * @param inclusion Whether fields matching this template should be included, provided their parent is included. + * @param definition The definition of the named predicate. + * @return A DSL step where the named predicate can be defined in more details. + */ + @Incubating + IndexSchemaNamedPredicateOptionsStep addNamedPredicate(String relativeNamedPredicateName, + TreeNodeInclusion inclusion, TypedPredicateDefinition definition); + /** * Create a new object field and add it to the current builder. * diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/index/spi/IndexManagerImplementor.java b/engine/src/main/java/org/hibernate/search/engine/backend/index/spi/IndexManagerImplementor.java index 78b8ffd7b79..ac0ec2442d7 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/index/spi/IndexManagerImplementor.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/index/spi/IndexManagerImplementor.java @@ -86,7 +86,7 @@ IndexIndexingPlan createIndexingPlan(BackendSessionContext sessionContext, IndexWorkspace createWorkspace(BackendMappingContext mappingContext, Set tenantId); - IndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext); + IndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext, Class rootScopeType); void addTo(IndexScopeBuilder builder); diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/metamodel/IndexObjectFieldTypeDescriptor.java b/engine/src/main/java/org/hibernate/search/engine/backend/metamodel/IndexObjectFieldTypeDescriptor.java index c65807090d8..788922072c4 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/metamodel/IndexObjectFieldTypeDescriptor.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/metamodel/IndexObjectFieldTypeDescriptor.java @@ -4,7 +4,7 @@ */ package org.hibernate.search.engine.backend.metamodel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; /** * The type of an "object" field in the index, @@ -16,7 +16,7 @@ public interface IndexObjectFieldTypeDescriptor extends IndexFieldTypeDescriptor /** * @return {@code true} if this object field is represented internally as a nested document, - * enabling features such as the {@link SearchPredicateFactory#nested(String) nested predicate}. + * enabling features such as the {@link TypedSearchPredicateFactory#nested(String) nested predicate}. */ boolean nested(); diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/AbstractSearchIndexScope.java b/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/AbstractSearchIndexScope.java index b3a8df41ba0..c556e322d8d 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/AbstractSearchIndexScope.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/AbstractSearchIndexScope.java @@ -28,14 +28,16 @@ import org.hibernate.search.util.common.reporting.EventContext; public abstract class AbstractSearchIndexScope< - S extends SearchQueryIndexScope, + SR, + S extends SearchQueryIndexScope, M extends AbstractIndexModel, N extends SearchIndexNodeContext, C extends SearchIndexCompositeNodeContext> - implements SearchIndexScope, SearchQueryIndexScope { + implements SearchIndexScope, SearchQueryIndexScope { // Mapping context protected final BackendMappingContext mappingContext; + protected final Class rootScopeType; // Targeted indexes private final Set hibernateSearchIndexNames; @@ -46,8 +48,10 @@ public abstract class AbstractSearchIndexScope< private final C overriddenRoot; - public AbstractSearchIndexScope(BackendMappingContext mappingContext, Set indexModels) { + public AbstractSearchIndexScope(BackendMappingContext mappingContext, Class rootScopeType, + Set indexModels) { this.mappingContext = mappingContext; + this.rootScopeType = rootScopeType; // Use LinkedHashMap/LinkedHashSet to ensure stable order when generating requests this.hibernateSearchIndexNames = new TreeSet<>(); @@ -61,8 +65,9 @@ public AbstractSearchIndexScope(BackendMappingContext mappingContext, Set parentScope, C overriddenRoot) { + protected AbstractSearchIndexScope(AbstractSearchIndexScope parentScope, C overriddenRoot) { this.mappingContext = parentScope.mappingContext; + this.rootScopeType = parentScope.rootScopeType; this.hibernateSearchIndexNames = parentScope.hibernateSearchIndexNames; this.indexModels = parentScope.indexModels; this.mappedTypeContexts = parentScope.mappedTypeContexts; diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScope.java b/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScope.java index ea76ef6dd53..9163a06485d 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScope.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScope.java @@ -11,9 +11,9 @@ /** * The scope of an index-related operation, aware of the targeted indexes and of the underlying technology (backend). */ -public interface IndexScope { +public interface IndexScope { - SearchQueryIndexScope> searchScope(); + SearchQueryIndexScope> searchScope(); /** * Extend the current index scope with the given extension, diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScopeBuilder.java b/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScopeBuilder.java index f6f02e179ce..abbf1808b4e 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScopeBuilder.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/scope/spi/IndexScopeBuilder.java @@ -4,8 +4,8 @@ */ package org.hibernate.search.engine.backend.scope.spi; -public interface IndexScopeBuilder { +public interface IndexScopeBuilder { - IndexScope build(); + IndexScope build(); } diff --git a/engine/src/main/java/org/hibernate/search/engine/backend/types/ObjectStructure.java b/engine/src/main/java/org/hibernate/search/engine/backend/types/ObjectStructure.java index 6d32ad3af55..8120ca0d7fd 100644 --- a/engine/src/main/java/org/hibernate/search/engine/backend/types/ObjectStructure.java +++ b/engine/src/main/java/org/hibernate/search/engine/backend/types/ObjectStructure.java @@ -4,7 +4,7 @@ */ package org.hibernate.search.engine.backend.types; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; /** * Defines how the structure of an object field is preserved upon indexing. @@ -70,7 +70,7 @@ public enum ObjectStructure { * but has the advantage of preserving the original structure. * Note however that access to that information when querying * requires special care. - * See in particular the {@link SearchPredicateFactory#nested(String) "nested" predicate}. + * See in particular the {@link TypedSearchPredicateFactory#nested(String) "nested" predicate}. */ NESTED diff --git a/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/impl/MappedIndexManagerImpl.java b/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/impl/MappedIndexManagerImpl.java index 64a9cd9bf9c..d6aa316b371 100644 --- a/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/impl/MappedIndexManagerImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/impl/MappedIndexManagerImpl.java @@ -62,9 +62,10 @@ public IndexWorkspace createWorkspace(BackendMappingContext mappingContext, Set< } @Override - public MappedIndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext) { + public MappedIndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext, + Class rootScope) { return new MappedIndexScopeBuilderImpl<>( - implementor, mappingContext + implementor, mappingContext, rootScope ); } diff --git a/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/spi/MappedIndexManager.java b/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/spi/MappedIndexManager.java index af672c96252..dd10cb33947 100644 --- a/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/spi/MappedIndexManager.java +++ b/engine/src/main/java/org/hibernate/search/engine/mapper/mapping/spi/MappedIndexManager.java @@ -35,7 +35,7 @@ IndexIndexingPlan createIndexingPlan(BackendSessionContext sessionContext, IndexWorkspace createWorkspace(BackendMappingContext mappingContext, Set tenantId); - MappedIndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext); + MappedIndexScopeBuilder createScopeBuilder(BackendMappingContext mappingContext, Class rootScope); void addTo(MappedIndexScopeBuilder builder); } diff --git a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeBuilderImpl.java b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeBuilderImpl.java index 9efef954e10..219444f7c39 100644 --- a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeBuilderImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeBuilderImpl.java @@ -11,11 +11,11 @@ import org.hibernate.search.engine.mapper.scope.spi.MappedIndexScopeBuilder; public class MappedIndexScopeBuilderImpl implements MappedIndexScopeBuilder { - private final IndexScopeBuilder delegate; + private final IndexScopeBuilder delegate; public MappedIndexScopeBuilderImpl(IndexManagerImplementor firstIndexManager, - BackendMappingContext mappingContext) { - this.delegate = firstIndexManager.createScopeBuilder( mappingContext ); + BackendMappingContext mappingContext, Class rootScope) { + this.delegate = firstIndexManager.createScopeBuilder( mappingContext, rootScope ); } public void add(IndexManagerImplementor indexManager) { diff --git a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java index 73666e53d9b..de947b051cc 100644 --- a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java @@ -8,20 +8,20 @@ import org.hibernate.search.engine.backend.scope.spi.IndexScope; import org.hibernate.search.engine.backend.session.spi.BackendSessionContext; import org.hibernate.search.engine.mapper.scope.spi.MappedIndexScope; -import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactory; +import org.hibernate.search.engine.search.aggregation.dsl.TypedSearchAggregationFactory; import org.hibernate.search.engine.search.highlighter.dsl.SearchHighlighterFactory; import org.hibernate.search.engine.search.loading.spi.SearchLoadingContextBuilder; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; +import org.hibernate.search.engine.search.projection.dsl.TypedSearchProjectionFactory; import org.hibernate.search.engine.search.query.dsl.SearchQuerySelectStep; import org.hibernate.search.engine.search.query.dsl.impl.DefaultSearchQuerySelectStep; -import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory; +import org.hibernate.search.engine.search.sort.dsl.TypedSearchSortFactory; class MappedIndexScopeImpl implements MappedIndexScope { - private final IndexScope delegate; + private final IndexScope delegate; - MappedIndexScopeImpl(IndexScope delegate) { + MappedIndexScopeImpl(IndexScope delegate) { this.delegate = delegate; } @@ -31,29 +31,29 @@ public String toString() { } @Override - public SearchQuerySelectStep, ?> search( + public SearchQuerySelectStep, ?> search( BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder) { return new DefaultSearchQuerySelectStep<>( delegate.searchScope(), sessionContext, loadingContextBuilder ); } @Override - public SearchPredicateFactory predicate() { + public TypedSearchPredicateFactory predicate() { return delegate.searchScope().predicateFactory(); } @Override - public SearchSortFactory sort() { + public TypedSearchSortFactory sort() { return delegate.searchScope().sortFactory(); } @Override - public SearchProjectionFactory projection() { + public TypedSearchProjectionFactory projection() { return delegate.searchScope().projectionFactory(); } @Override - public SearchAggregationFactory aggregation() { + public TypedSearchAggregationFactory aggregation() { return delegate.searchScope().aggregationFactory(); } diff --git a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/spi/MappedIndexScope.java b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/spi/MappedIndexScope.java index c9e85aaf2a0..8b3fcc9be93 100644 --- a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/spi/MappedIndexScope.java +++ b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/spi/MappedIndexScope.java @@ -6,22 +6,22 @@ import org.hibernate.search.engine.backend.scope.IndexScopeExtension; import org.hibernate.search.engine.backend.session.spi.BackendSessionContext; -import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactory; +import org.hibernate.search.engine.search.aggregation.dsl.TypedSearchAggregationFactory; import org.hibernate.search.engine.search.highlighter.dsl.SearchHighlighterFactory; import org.hibernate.search.engine.search.loading.spi.SearchLoadingContextBuilder; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; -import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; +import org.hibernate.search.engine.search.projection.dsl.TypedSearchProjectionFactory; import org.hibernate.search.engine.search.query.dsl.SearchQuerySelectStep; -import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory; +import org.hibernate.search.engine.search.sort.dsl.TypedSearchSortFactory; /** * @param Scope root type. * @param The type of entity references, i.e. the type of hits returned by * {@link SearchQuerySelectStep#selectEntityReference() reference queries}, - * or the type of objects returned for {@link SearchProjectionFactory#entityReference() entity reference projections}. + * or the type of objects returned for {@link TypedSearchProjectionFactory#entityReference() entity reference projections}. * @param The type of entities, i.e. the type of hits returned by * {@link SearchQuerySelectStep#selectEntity() entity queries} - * or the type of objects returned for {@link SearchProjectionFactory#entity() entity projections}. + * or the type of objects returned for {@link TypedSearchProjectionFactory#entity() entity projections}. */ public interface MappedIndexScope { @@ -31,22 +31,22 @@ public interface MappedIndexScope { * will be wrong. * In particular, we cannot accept a LoadingContextBuilder with any T. */ - SearchQuerySelectStep, ?> search( + SearchQuerySelectStep, ?> search( BackendSessionContext sessionContext, SearchLoadingContextBuilder loadingContextBuilder); - SearchPredicateFactory predicate(); + TypedSearchPredicateFactory predicate(); - SearchSortFactory sort(); + TypedSearchSortFactory sort(); /* * IMPLEMENTATION NOTE: we *must* return a factory with the same R/E type arguments as this class, * otherwise some casts in EntityProjectionOptionsStepImpl and EntityReferenceProjectionOptionsStepImpl * will be wrong. */ - SearchProjectionFactory projection(); + TypedSearchProjectionFactory projection(); - SearchAggregationFactory aggregation(); + TypedSearchAggregationFactory aggregation(); SearchHighlighterFactory highlighter(); diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AggregationFilterStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AggregationFilterStep.java index 09fc32d46a6..66adeadcae5 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AggregationFilterStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AggregationFilterStep.java @@ -8,7 +8,7 @@ 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.predicate.dsl.TypedSearchPredicateFactory; /** * The step in an aggregation definition where a filter can be set @@ -18,7 +18,7 @@ * @param The "self" type (the actual exposed type of this step) * @param The type of factory used to create predicates in {@link #filter(Function)}. */ -public interface AggregationFilterStep> { +public interface AggregationFilterStep> { /** * Filter nested objects from which values will be extracted for this aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationFieldStep.java index cac31d11066..c85815f9c3f 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationFieldStep.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.AvgAggregationFieldReference; import org.hibernate.search.util.common.annotation.Incubating; @@ -18,7 +18,7 @@ * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ @Incubating -public interface AvgAggregationFieldStep> { +public interface AvgAggregationFieldStep> { /** * Target the given field in the avg aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationOptionsStep.java index bfc1d01cab9..562bf4feaa3 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/AvgAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -21,7 +21,7 @@ public interface AvgAggregationOptionsStep< SR, S extends AvgAggregationOptionsStep, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F> extends AggregationFinalStep, AggregationFilterStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationFieldStep.java index dfaef44d371..a2ccf66f9f9 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationFieldStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.CountAggregationFieldReference; import org.hibernate.search.util.common.annotation.Incubating; @@ -17,7 +17,7 @@ * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ @Incubating -public interface CountAggregationFieldStep> { +public interface CountAggregationFieldStep> { /** * Target the given field in the count aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationOptionsStep.java index 9b613d7c239..1e960e720f5 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -20,7 +20,7 @@ public interface CountAggregationOptionsStep< SR, S extends CountAggregationOptionsStep, - PDF extends SearchPredicateFactory> + PDF extends TypedSearchPredicateFactory> extends AggregationFinalStep, AggregationFilterStep { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationFieldStep.java index cb29d9fee3a..ab189dde2b3 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationFieldStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.CountAggregationFieldReference; import org.hibernate.search.util.common.annotation.Incubating; @@ -17,7 +17,7 @@ * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ @Incubating -public interface CountDistinctAggregationFieldStep> { +public interface CountDistinctAggregationFieldStep> { /** * Target the given field in the count distinct aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationOptionsStep.java index 52744c8be00..2aca785be30 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/CountDistinctAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -20,7 +20,7 @@ public interface CountDistinctAggregationOptionsStep< SR, S extends CountDistinctAggregationOptionsStep, - PDF extends SearchPredicateFactory> + PDF extends TypedSearchPredicateFactory> extends AggregationFinalStep, AggregationFilterStep { } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/ExtendedSearchAggregationFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/ExtendedSearchAggregationFactory.java index 87c1385cffe..35d76c953f1 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/ExtendedSearchAggregationFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/ExtendedSearchAggregationFactory.java @@ -6,10 +6,10 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; /** - * A base interface for subtypes of {@link SearchAggregationFactory} allowing to + * A base interface for subtypes of {@link TypedSearchAggregationFactory} allowing to * easily override the self type and predicate factory type for all relevant methods. *

* Warning: Generic parameters of this type are subject to change, @@ -22,8 +22,8 @@ public interface ExtendedSearchAggregationFactory< SR, S extends ExtendedSearchAggregationFactory, - PDF extends SearchPredicateFactory> - extends SearchAggregationFactory { + PDF extends TypedSearchPredicateFactory> + extends TypedSearchAggregationFactory { @Override S withRoot(String objectFieldPath); diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationFieldStep.java index 705630ed9cf..3d2c8bf4977 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationFieldStep.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.MaxAggregationFieldReference; import org.hibernate.search.util.common.annotation.Incubating; @@ -18,7 +18,7 @@ * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ @Incubating -public interface MaxAggregationFieldStep> { +public interface MaxAggregationFieldStep> { /** * Target the given field in the min aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationOptionsStep.java index 4b6918dd3d2..8da7b0a7690 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MaxAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -21,7 +21,7 @@ public interface MaxAggregationOptionsStep< SR, S extends MaxAggregationOptionsStep, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F> extends AggregationFinalStep, AggregationFilterStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationFieldStep.java index 60063f5432d..22e9a6991fa 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationFieldStep.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.MinAggregationFieldReference; import org.hibernate.search.util.common.annotation.Incubating; @@ -18,7 +18,7 @@ * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ @Incubating -public interface MinAggregationFieldStep> { +public interface MinAggregationFieldStep> { /** * Target the given field in the min aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationOptionsStep.java index 65a868f3b32..4e3e22c78af 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/MinAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -21,7 +21,7 @@ public interface MinAggregationOptionsStep< SR, S extends MinAggregationOptionsStep, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F> extends AggregationFinalStep, AggregationFilterStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationFieldStep.java index 9968ef35d0e..6c4c05a3a63 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationFieldStep.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.RangeAggregationFieldReference; /** @@ -16,7 +16,7 @@ * @param Scope root type. * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ -public interface RangeAggregationFieldStep> { +public interface RangeAggregationFieldStep> { /** * Target the given field in the range aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationOptionsStep.java index 2f6cef5c793..f0a23af7110 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; /** * The final step in a "range" aggregation definition, where optional parameters can be set. @@ -20,7 +20,7 @@ public interface RangeAggregationOptionsStep< SR, S extends RangeAggregationOptionsStep, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F, A> extends AggregationFinalStep, AggregationFilterStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeMoreStep.java index 3e04669fedd..a9ec19feda3 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeMoreStep.java @@ -7,7 +7,7 @@ import java.util.Map; import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.data.Range; /** @@ -25,7 +25,7 @@ public interface RangeAggregationRangeMoreStep< SR, S extends RangeAggregationRangeMoreStep, N extends RangeAggregationOptionsStep, Long>>, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F> extends RangeAggregationOptionsStep, Long>>, RangeAggregationRangeStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeStep.java index 2bfb337ce9b..42e99fc17dd 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/RangeAggregationRangeStep.java @@ -7,7 +7,7 @@ import java.util.Collection; import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.data.Range; /** @@ -21,7 +21,7 @@ public interface RangeAggregationRangeStep< SR, N extends RangeAggregationRangeMoreStep, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F> { /** diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactory.java index 3e7f6f466c0..fe2e16dd257 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactory.java @@ -4,10 +4,8 @@ */ package org.hibernate.search.engine.search.aggregation.dsl; -import java.util.function.Function; -import org.hibernate.search.engine.search.common.NamedValues; -import org.hibernate.search.util.common.SearchException; +import org.hibernate.search.engine.search.common.NonStaticMetamodelScope; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -36,112 +34,9 @@ * Such reference provides the information on which search capabilities the particular index field possesses, and allows switching between different * {@link org.hibernate.search.engine.search.common.ValueModel value model representations}. * - * @param Scope root type. - * * @author Emmanuel Bernard emmanuel@hibernate.org */ -public interface SearchAggregationFactory { - - /** - * Perform aggregation in range buckets. - *

- * Given a field and one or more ranges of values, - * this aggregation creates one bucket per range, - * and puts in each bucket every document for which - * the given field has a value that falls into the corresponding range. - *

- * For each bucket, the document count is computed, - * or more complex metrics or sub-aggregations for backends that support it. - * - * @return The next step. - */ - RangeAggregationFieldStep range(); - - /** - * Perform aggregation in term buckets. - *

- * Given a field, - * this aggregation creates one bucket per term of that field in the index, - * and puts in each bucket every document for which - * the given field matches the corresponding term. - *

- * For each bucket, the document count is computed, - * or more complex metrics or sub-aggregations for backends that support it. - * - * @return The next step. - */ - TermsAggregationFieldStep terms(); - - /** - * Perform the sum metric aggregation. - * - * @return The next step. - */ - @Incubating - SumAggregationFieldStep sum(); - - /** - * Perform the min metric aggregation. - * - * @return The next step. - */ - @Incubating - MinAggregationFieldStep min(); - - /** - * Perform the max metric aggregation. - * - * @return The next step. - */ - @Incubating - MaxAggregationFieldStep max(); - - /** - * Perform the count metric aggregation. - * - * @return The next step. - */ - @Incubating - CountAggregationFieldStep count(); - - /** - * Perform the count distinct metric aggregation. - * - * @return The next step. - */ - @Incubating - CountDistinctAggregationFieldStep countDistinct(); - - /** - * Perform the avg metric aggregation. - * - * @return the next step. - */ - @Incubating - AvgAggregationFieldStep avg(); - - /** - * Delegating aggregation that creates the actual aggregation at query create time and provides access to query parameters. - *

- * Which aggregation exactly to create is defined by a function passed to the arguments of this aggregation. - * - * @param aggregationCreator The function creating an actual aggregation. - * @return A final DSL step in a parameterized aggregation definition. - */ - @Incubating - AggregationFinalStep withParameters( - Function> aggregationCreator); - - /** - * Extend the current factory with the given extension, - * resulting in an extended factory offering different types of aggregations. - * - * @param extension The extension to the aggregation DSL. - * @param The type of factory provided by the extension. - * @return The extended factory. - * @throws SearchException If the extension cannot be applied (wrong underlying backend, ...). - */ - T extension(SearchAggregationFactoryExtension extension); +public interface SearchAggregationFactory extends TypedSearchAggregationFactory { /** * Create a new aggregation factory whose root for all paths passed to the DSL @@ -153,7 +48,7 @@ AggregationFinalStep withParameters( * @return A new aggregation factory using the given object field as root. */ @Incubating - SearchAggregationFactory withRoot(String objectFieldPath); + SearchAggregationFactory withRoot(String objectFieldPath); /** * @param relativeFieldPath The path to a field, relative to the {@link #withRoot(String) root} of this factory. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactoryExtension.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactoryExtension.java index c0efcede5cd..ea96421e28e 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactoryExtension.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SearchAggregationFactoryExtension.java @@ -16,9 +16,9 @@ * * @param Scope root type. * @param The type of extended aggregation factories. Should generally extend - * {@link SearchAggregationFactory}. + * {@link TypedSearchAggregationFactory}. * - * @see SearchAggregationFactory#extension(SearchAggregationFactoryExtension) + * @see TypedSearchAggregationFactory#extension(SearchAggregationFactoryExtension) * @see ExtendedSearchAggregationFactory */ public interface SearchAggregationFactoryExtension { @@ -28,10 +28,10 @@ public interface SearchAggregationFactoryExtension { *

* WARNING: this method is not API, see comments at the type level. * - * @param original The original, non-extended {@link SearchAggregationFactory}. + * @param original The original, non-extended {@link TypedSearchAggregationFactory}. * @return An optional containing the extended aggregation factory ({@link T}) in case * of success, or an empty optional otherwise. */ - Optional extendOptional(SearchAggregationFactory original); + Optional extendOptional(TypedSearchAggregationFactory original); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationFieldStep.java index 140eb514abd..9d7e1aba7c5 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationFieldStep.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.SumAggregationFieldReference; import org.hibernate.search.util.common.annotation.Incubating; @@ -18,7 +18,7 @@ * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ @Incubating -public interface SumAggregationFieldStep> { +public interface SumAggregationFieldStep> { /** * Target the given field in the sum aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationOptionsStep.java index e4a0cb6eba2..6f37fe37d83 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/SumAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -21,7 +21,7 @@ public interface SumAggregationOptionsStep< SR, S extends SumAggregationOptionsStep, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F> extends AggregationFinalStep, AggregationFilterStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationFieldStep.java index b3039772faf..6d4ae9fd595 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationFieldStep.java @@ -8,7 +8,7 @@ import java.util.function.Function; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.reference.aggregation.TermsAggregationFieldReference; /** @@ -17,7 +17,7 @@ * @param Scope root type. * @param The type of factory used to create predicates in {@link AggregationFilterStep#filter(Function)}. */ -public interface TermsAggregationFieldStep> { +public interface TermsAggregationFieldStep> { /** * Target the given field in the terms aggregation. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationOptionsStep.java index 22fbf84f1ca..eb899180394 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TermsAggregationOptionsStep.java @@ -6,7 +6,7 @@ import java.util.function.Function; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; /** * The final step in a "terms" aggregation definition, where optional parameters can be set. @@ -19,7 +19,7 @@ public interface TermsAggregationOptionsStep< SR, S extends TermsAggregationOptionsStep, - PDF extends SearchPredicateFactory, + PDF extends TypedSearchPredicateFactory, F, A> extends AggregationFinalStep, AggregationFilterStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TypedSearchAggregationFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TypedSearchAggregationFactory.java new file mode 100644 index 00000000000..16a3038d0b1 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/TypedSearchAggregationFactory.java @@ -0,0 +1,166 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.search.engine.search.aggregation.dsl; + +import java.util.function.Function; + +import org.hibernate.search.engine.search.common.NamedValues; +import org.hibernate.search.util.common.SearchException; +import org.hibernate.search.util.common.annotation.Incubating; + +/** + * A factory for search aggregations. + * + *

Field paths

+ * + * By default, field paths passed to this DSL are interpreted as absolute, + * i.e. relative to the index root. + *

+ * However, a new, "relative" factory can be created with {@link #withRoot(String)}: + * the new factory interprets paths as relative to the object field passed as argument to the method. + *

+ * This can be useful when calling reusable methods that can apply the same aggregation + * on different object fields that have same structure (same sub-fields). + *

+ * Such a factory can also transform relative paths into absolute paths using {@link #toAbsolutePath(String)}; + * this can be useful for native aggregations in particular. + * + *

Field references

+ * + * A {@link org.hibernate.search.engine.search.reference field reference} is always represented by the absolute field path and, + * if applicable, i.e. when a field reference is typed, a combination of the {@link org.hibernate.search.engine.search.common.ValueModel} and the type. + *

+ * Field references are usually accessed from the generated Hibernate Search's static metamodel classes that describe the index structure. + * Such reference provides the information on which search capabilities the particular index field possesses, and allows switching between different + * {@link org.hibernate.search.engine.search.common.ValueModel value model representations}. + * + * @param Scope root type. + * + * @author Emmanuel Bernard emmanuel@hibernate.org + */ +public interface TypedSearchAggregationFactory { + + /** + * Perform aggregation in range buckets. + *

+ * Given a field and one or more ranges of values, + * this aggregation creates one bucket per range, + * and puts in each bucket every document for which + * the given field has a value that falls into the corresponding range. + *

+ * For each bucket, the document count is computed, + * or more complex metrics or sub-aggregations for backends that support it. + * + * @return The next step. + */ + RangeAggregationFieldStep range(); + + /** + * Perform aggregation in term buckets. + *

+ * Given a field, + * this aggregation creates one bucket per term of that field in the index, + * and puts in each bucket every document for which + * the given field matches the corresponding term. + *

+ * For each bucket, the document count is computed, + * or more complex metrics or sub-aggregations for backends that support it. + * + * @return The next step. + */ + TermsAggregationFieldStep terms(); + + /** + * Perform the sum metric aggregation. + * + * @return The next step. + */ + @Incubating + SumAggregationFieldStep sum(); + + /** + * Perform the min metric aggregation. + * + * @return The next step. + */ + @Incubating + MinAggregationFieldStep min(); + + /** + * Perform the max metric aggregation. + * + * @return The next step. + */ + @Incubating + MaxAggregationFieldStep max(); + + /** + * Perform the count metric aggregation. + * + * @return The next step. + */ + @Incubating + CountAggregationFieldStep count(); + + /** + * Perform the count distinct metric aggregation. + * + * @return The next step. + */ + @Incubating + CountDistinctAggregationFieldStep countDistinct(); + + /** + * Perform the avg metric aggregation. + * + * @return the next step. + */ + @Incubating + AvgAggregationFieldStep avg(); + + /** + * Delegating aggregation that creates the actual aggregation at query create time and provides access to query parameters. + *

+ * Which aggregation exactly to create is defined by a function passed to the arguments of this aggregation. + * + * @param aggregationCreator The function creating an actual aggregation. + * @return A final DSL step in a parameterized aggregation definition. + */ + @Incubating + AggregationFinalStep withParameters( + Function> aggregationCreator); + + /** + * Extend the current factory with the given extension, + * resulting in an extended factory offering different types of aggregations. + * + * @param extension The extension to the aggregation DSL. + * @param The type of factory provided by the extension. + * @return The extended factory. + * @throws SearchException If the extension cannot be applied (wrong underlying backend, ...). + */ + T extension(SearchAggregationFactoryExtension extension); + + /** + * Create a new aggregation factory whose root for all paths passed to the DSL + * will be the given object field. + *

+ * See here for more information. + * + * @param objectFieldPath The path from the current root to an object field that will become the new root. + * @return A new aggregation factory using the given object field as root. + */ + @Incubating + TypedSearchAggregationFactory withRoot(String objectFieldPath); + + /** + * @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 aggregations for example. + * Note the path is returned even if the field doesn't exist. + */ + @Incubating + String toAbsolutePath(String relativeFieldPath); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationFieldStepImpl.java index e6fef4958f9..757d27634f0 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationFieldStepImpl.java @@ -10,10 +10,10 @@ import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.impl.Contracts; -public class AvgAggregationFieldStepImpl> +public class AvgAggregationFieldStepImpl> implements AvgAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationOptionsStepImpl.java index f3f0107bc70..4daba642002 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/AvgAggregationOptionsStepImpl.java @@ -12,9 +12,9 @@ import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; -class AvgAggregationOptionsStepImpl, F> +class AvgAggregationOptionsStepImpl, F> implements AvgAggregationOptionsStep, PDF, F> { private final FieldMetricAggregationBuilder builder; private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationFieldStepImpl.java index 40ae2f5d268..4a2ee3c98dd 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationFieldStepImpl.java @@ -9,9 +9,9 @@ import org.hibernate.search.engine.search.aggregation.dsl.spi.SearchAggregationDslContext; import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.SearchFilterableAggregationBuilder; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; -public class CountAggregationFieldStepImpl> +public class CountAggregationFieldStepImpl> implements CountAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationOptionsStepImpl.java index 17c8d374869..58cb8bad195 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountAggregationOptionsStepImpl.java @@ -12,9 +12,9 @@ import org.hibernate.search.engine.search.aggregation.spi.SearchFilterableAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; -class CountAggregationOptionsStepImpl> +class CountAggregationOptionsStepImpl> implements CountAggregationOptionsStep, PDF> { private final SearchFilterableAggregationBuilder builder; private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationFieldStepImpl.java index 239db8baf53..fd67730f29f 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationFieldStepImpl.java @@ -9,9 +9,9 @@ import org.hibernate.search.engine.search.aggregation.dsl.spi.SearchAggregationDslContext; import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.SearchFilterableAggregationBuilder; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; -public class CountDistinctAggregationFieldStepImpl> +public class CountDistinctAggregationFieldStepImpl> implements CountDistinctAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationOptionsStepImpl.java index 9bc23a51cb2..293349b2e5a 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/CountDistinctAggregationOptionsStepImpl.java @@ -12,9 +12,9 @@ import org.hibernate.search.engine.search.aggregation.spi.SearchFilterableAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; -class CountDistinctAggregationOptionsStepImpl> +class CountDistinctAggregationOptionsStepImpl> implements CountDistinctAggregationOptionsStep, PDF> { private final SearchFilterableAggregationBuilder builder; private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationFieldStepImpl.java index fc960180ff6..787f624b00e 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationFieldStepImpl.java @@ -10,10 +10,10 @@ import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.impl.Contracts; -public class MaxAggregationFieldStepImpl> +public class MaxAggregationFieldStepImpl> implements MaxAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationOptionsStepImpl.java index f1b35a74b97..94be31e94fe 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MaxAggregationOptionsStepImpl.java @@ -12,9 +12,9 @@ import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; -class MaxAggregationOptionsStepImpl, F> +class MaxAggregationOptionsStepImpl, F> implements MaxAggregationOptionsStep, PDF, F> { private final FieldMetricAggregationBuilder builder; private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationFieldStepImpl.java index edd21456f76..45e4503e5ec 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationFieldStepImpl.java @@ -10,10 +10,10 @@ import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.impl.Contracts; -public class MinAggregationFieldStepImpl> +public class MinAggregationFieldStepImpl> implements MinAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationOptionsStepImpl.java index bcbd2a66241..6cc90fecb00 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/MinAggregationOptionsStepImpl.java @@ -12,9 +12,9 @@ import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; -class MinAggregationOptionsStepImpl, F> +class MinAggregationOptionsStepImpl, F> implements MinAggregationOptionsStep, PDF, F> { private final FieldMetricAggregationBuilder builder; private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationFieldStepImpl.java index f97b7f07088..dcfb149186d 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationFieldStepImpl.java @@ -10,10 +10,10 @@ import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.RangeAggregationBuilder; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.impl.Contracts; -public class RangeAggregationFieldStepImpl> +public class RangeAggregationFieldStepImpl> implements RangeAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationRangeStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationRangeStepImpl.java index 454a6c00ac2..ff5e3c575f3 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationRangeStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/RangeAggregationRangeStepImpl.java @@ -15,11 +15,11 @@ import org.hibernate.search.engine.search.aggregation.spi.RangeAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.data.Range; import org.hibernate.search.util.common.impl.Contracts; -class RangeAggregationRangeStepImpl, F> +class RangeAggregationRangeStepImpl, F> implements RangeAggregationRangeStep, PDF, F>, RangeAggregationRangeMoreStep, diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationFieldStepImpl.java index 18aa188b708..d1a2e04387f 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationFieldStepImpl.java @@ -10,10 +10,10 @@ import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.impl.Contracts; -public class SumAggregationFieldStepImpl> +public class SumAggregationFieldStepImpl> implements SumAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationOptionsStepImpl.java index 7c3ef7bca3e..ccdbf14d258 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/SumAggregationOptionsStepImpl.java @@ -12,9 +12,9 @@ import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; -class SumAggregationOptionsStepImpl, F> +class SumAggregationOptionsStepImpl, F> implements SumAggregationOptionsStep, PDF, F> { private final FieldMetricAggregationBuilder builder; private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationFieldStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationFieldStepImpl.java index a0d735b13fa..6f4d7ac29af 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationFieldStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationFieldStepImpl.java @@ -12,10 +12,10 @@ import org.hibernate.search.engine.search.aggregation.spi.AggregationTypeKeys; import org.hibernate.search.engine.search.aggregation.spi.TermsAggregationBuilder; import org.hibernate.search.engine.search.common.ValueModel; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.impl.Contracts; -public class TermsAggregationFieldStepImpl> +public class TermsAggregationFieldStepImpl> implements TermsAggregationFieldStep { private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationOptionsStepImpl.java index e0ddea57e2f..687a58cb583 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/impl/TermsAggregationOptionsStepImpl.java @@ -13,10 +13,10 @@ import org.hibernate.search.engine.search.aggregation.spi.TermsAggregationBuilder; 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.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.impl.Contracts; -class TermsAggregationOptionsStepImpl, F> +class TermsAggregationOptionsStepImpl, F> implements TermsAggregationOptionsStep, PDF, F, Map> { private final TermsAggregationBuilder builder; private final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/AbstractSearchAggregationFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/AbstractSearchAggregationFactory.java index ad14244c2f6..d0c71cfa809 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/AbstractSearchAggregationFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/AbstractSearchAggregationFactory.java @@ -29,13 +29,13 @@ import org.hibernate.search.engine.search.aggregation.dsl.impl.WithParametersAggregationFinalStep; import org.hibernate.search.engine.search.aggregation.spi.SearchAggregationIndexScope; import org.hibernate.search.engine.search.common.NamedValues; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; public abstract class AbstractSearchAggregationFactory< SR, S extends ExtendedSearchAggregationFactory, SC extends SearchAggregationIndexScope, - PDF extends SearchPredicateFactory> + PDF extends TypedSearchPredicateFactory> implements ExtendedSearchAggregationFactory { protected final SearchAggregationDslContext dslContext; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/SearchAggregationDslContext.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/SearchAggregationDslContext.java index aaff67aded2..e969ad1e87c 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/SearchAggregationDslContext.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/SearchAggregationDslContext.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.hibernate.search.engine.search.aggregation.spi.SearchAggregationIndexScope; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.engine.search.sort.dsl.FieldSortOptionsStep; /** @@ -21,11 +21,11 @@ public class SearchAggregationDslContext< SR, SC extends SearchAggregationIndexScope, - PDF extends SearchPredicateFactory> { + PDF extends TypedSearchPredicateFactory> { public static < SR, SC extends SearchAggregationIndexScope, - PDF extends SearchPredicateFactory> SearchAggregationDslContext root(SC scope, + PDF extends TypedSearchPredicateFactory> SearchAggregationDslContext root(SC scope, PDF predicateFactory) { return new SearchAggregationDslContext<>( scope, predicateFactory ); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/SearchAggregationFactoryDelegate.java b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/SearchAggregationFactoryDelegate.java new file mode 100644 index 00000000000..f2ffb44101e --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/aggregation/dsl/spi/SearchAggregationFactoryDelegate.java @@ -0,0 +1,88 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.search.engine.search.aggregation.dsl.spi; + +import java.util.function.Function; + +import org.hibernate.search.engine.search.aggregation.dsl.AggregationFinalStep; +import org.hibernate.search.engine.search.aggregation.dsl.AvgAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.CountAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.CountDistinctAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.MaxAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.MinAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.RangeAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactory; +import org.hibernate.search.engine.search.aggregation.dsl.SearchAggregationFactoryExtension; +import org.hibernate.search.engine.search.aggregation.dsl.SumAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.TermsAggregationFieldStep; +import org.hibernate.search.engine.search.aggregation.dsl.TypedSearchAggregationFactory; +import org.hibernate.search.engine.search.common.NamedValues; +import org.hibernate.search.engine.search.common.NonStaticMetamodelScope; +import org.hibernate.search.util.common.annotation.Incubating; + +@Incubating +public record SearchAggregationFactoryDelegate(TypedSearchAggregationFactory delegate) + implements SearchAggregationFactory { + @Override + public RangeAggregationFieldStep range() { + return delegate.range(); + } + + @Override + public TermsAggregationFieldStep terms() { + return delegate.terms(); + } + + @Override + public SumAggregationFieldStep sum() { + return delegate.sum(); + } + + @Override + public MinAggregationFieldStep min() { + return delegate().min(); + } + + @Override + public MaxAggregationFieldStep max() { + return delegate.max(); + } + + @Override + public CountAggregationFieldStep count() { + return delegate.count(); + } + + @Override + public CountDistinctAggregationFieldStep countDistinct() { + return delegate.countDistinct(); + } + + @Override + public AvgAggregationFieldStep avg() { + return delegate.avg(); + } + + @Override + public AggregationFinalStep withParameters( + Function> aggregationCreator) { + return delegate.withParameters( aggregationCreator ); + } + + @Override + public T extension(SearchAggregationFactoryExtension extension) { + return delegate.extension( extension ); + } + + @Override + public SearchAggregationFactory withRoot(String objectFieldPath) { + return new SearchAggregationFactoryDelegate( delegate.withRoot( objectFieldPath ) ); + } + + @Override + public String toAbsolutePath(String relativeFieldPath) { + return delegate.toAbsolutePath( relativeFieldPath ); + } +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/common/NonStaticMetamodelScope.java b/engine/src/main/java/org/hibernate/search/engine/search/common/NonStaticMetamodelScope.java new file mode 100644 index 00000000000..50527531664 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/common/NonStaticMetamodelScope.java @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.search.engine.search.common; + +import org.hibernate.search.util.common.annotation.Incubating; + +/** + * The default root scope, to be used when there is no static metamodel involvied. + */ +@Incubating +public final class NonStaticMetamodelScope { +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/common/spi/MultiIndexSearchIndexIdentifierContext.java b/engine/src/main/java/org/hibernate/search/engine/search/common/spi/MultiIndexSearchIndexIdentifierContext.java index 3580f9c2ecb..388c17abebe 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/common/spi/MultiIndexSearchIndexIdentifierContext.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/common/spi/MultiIndexSearchIndexIdentifierContext.java @@ -22,7 +22,7 @@ public class MultiIndexSearchIndexIdentifierContext private final SearchIndexScope scope; private final List contextByIndex; - public MultiIndexSearchIndexIdentifierContext(AbstractSearchIndexScope scope, + public MultiIndexSearchIndexIdentifierContext(AbstractSearchIndexScope scope, List contextByIndex) { this.scope = scope; this.contextByIndex = contextByIndex; diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinition.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinition.java index 421aee77969..0de1f38f227 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinition.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinition.java @@ -5,7 +5,7 @@ package org.hibernate.search.engine.search.predicate.definition; import org.hibernate.search.engine.search.predicate.SearchPredicate; -import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -25,9 +25,9 @@ public interface PredicateDefinition { /** * Creates a predicate. - * @param context The context, exposing in particular a {@link SearchPredicateFactory}. + * @param context The context, exposing in particular a {@link TypedSearchPredicateFactory}. * @return The created {@link SearchPredicate}. */ - SearchPredicate create(PredicateDefinitionContext context); + SearchPredicate create(PredicateDefinitionContext context); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinitionContext.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinitionContext.java index 2992f94043d..9f447c91244 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinitionContext.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/PredicateDefinitionContext.java @@ -7,28 +7,29 @@ import java.util.Optional; import org.hibernate.search.engine.search.common.NamedValues; +import org.hibernate.search.engine.search.common.NonStaticMetamodelScope; import org.hibernate.search.engine.search.predicate.dsl.NamedPredicateOptionsStep; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; import org.hibernate.search.util.common.SearchException; import org.hibernate.search.util.common.annotation.Incubating; /** - * The context passed to {@link PredicateDefinition#create(PredicateDefinitionContext)}. - * @param Scope root type. + * The context passed to {@link PredicateDefinition#create(PredicateDefinitionContext)}. * @see PredicateDefinition#create(PredicateDefinitionContext) */ @Incubating -public interface PredicateDefinitionContext { +public interface PredicateDefinitionContext extends TypedPredicateDefinitionContext { /** * @return A predicate factory. * If the named predicate was registered on an object field, * this factory expects field paths to be provided relative to that same object field. * This factory is only valid in the present context and must not be used after - * {@link PredicateDefinition#create(PredicateDefinitionContext)} returns. - * @see SearchPredicateFactory + * {@link PredicateDefinition#create(PredicateDefinitionContext)} returns. + * @see TypedSearchPredicateFactory */ - SearchPredicateFactory predicate(); + SearchPredicateFactory predicate(); /** * @param name The name of the parameter. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/TypedPredicateDefinition.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/TypedPredicateDefinition.java new file mode 100644 index 00000000000..cd3f2850032 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/TypedPredicateDefinition.java @@ -0,0 +1,39 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.search.engine.search.predicate.definition; + +import org.hibernate.search.engine.search.predicate.SearchPredicate; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; +import org.hibernate.search.util.common.annotation.Incubating; + +/** + * A component able to define a predicate using the Hibernate Search Predicate DSL. + *

+ * This definition takes advantage of provided metadata + * to pick, configure and create a {@link SearchPredicate}. + *

+ * Used in particular for named predicates, + * where the definition is given a name and assigned to an element in the index schema. + * + * @see SearchPredicate + * + */ +@Incubating +public interface TypedPredicateDefinition { + + /** + * Creates a predicate. + * @param context The context, exposing in particular a {@link TypedSearchPredicateFactory}. + * @return The created {@link SearchPredicate}. + */ + SearchPredicate create(TypedPredicateDefinitionContext context); + + /** + * @return The scope root type. Type that limits allowed field references and other search capabilities used + * within particular search factories. + */ + Class scopeRootType(); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/TypedPredicateDefinitionContext.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/TypedPredicateDefinitionContext.java new file mode 100644 index 00000000000..5fcee814fec --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/definition/TypedPredicateDefinitionContext.java @@ -0,0 +1,93 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.search.engine.search.predicate.definition; + +import java.util.Optional; + +import org.hibernate.search.engine.search.common.NamedValues; +import org.hibernate.search.engine.search.predicate.dsl.NamedPredicateOptionsStep; +import org.hibernate.search.engine.search.predicate.dsl.TypedSearchPredicateFactory; +import org.hibernate.search.util.common.SearchException; +import org.hibernate.search.util.common.annotation.Incubating; + +/** + * The context passed to {@link TypedPredicateDefinition#create(TypedPredicateDefinitionContext)}. + * @param Scope root type. + * @see TypedPredicateDefinition#create(TypedPredicateDefinitionContext) + */ +@Incubating +public interface TypedPredicateDefinitionContext { + + /** + * @return A predicate factory. + * If the named predicate was registered on an object field, + * this factory expects field paths to be provided relative to that same object field. + * This factory is only valid in the present context and must not be used after + * {@link PredicateDefinition#create(PredicateDefinitionContext)} returns. + * @see TypedSearchPredicateFactory + */ + TypedSearchPredicateFactory predicate(); + + /** + * @param name The name of the parameter. + * @return The value provided to {@link NamedPredicateOptionsStep#param(String, Object)} for this parameter. + * @throws SearchException If no value was provided for this parameter. + * @see NamedPredicateOptionsStep#param(String, Object) + * @deprecated Use {@link #params()} instead. + */ + @Deprecated(since = "7.0") + default Object param(String name) { + return params().get( name, Object.class ); + } + + /** + * @param name The name of the parameter. + * @param paramType The type of the parameter. + * @param The type of the parameter. + * @return The value provided to {@link NamedPredicateOptionsStep#param(String, Object)} for this parameter. + * @throws SearchException If no value was provided for this parameter. + * @see NamedPredicateOptionsStep#param(String, Object) + * @deprecated Use {@link #params()} instead. + */ + @Deprecated(since = "7.2") + default T param(String name, Class paramType) { + return params().get( name, paramType ); + } + + /** + * @param name The name of the parameter. + * @return An optional containing the value provided to {@link NamedPredicateOptionsStep#param(String, Object)} + * for this parameter, or {@code Optional.empty()} if no value was provided for this parameter. + * @see NamedPredicateOptionsStep#param(String, Object) + * @deprecated Use {@link #params()} instead. + */ + @Deprecated(since = "7.0") + default Optional paramOptional(String name) { + return params().getOptional( name, Object.class ); + } + + /** + * @param name The name of the parameter. + * @param paramType The type of the parameter. + * @param The type of the parameter. + * @return An optional containing the value provided to {@link NamedPredicateOptionsStep#param(String, Object)} + * for this parameter, or {@code Optional.empty()} if no value was provided for this parameter. + * @see NamedPredicateOptionsStep#param(String, Object) + * @deprecated Use {@link #params()} instead. + */ + @Deprecated(since = "7.2") + default Optional paramOptional(String name, Class paramType) { + return params().getOptional( name, paramType ); + } + + /** + * @return Predicate definition context parameters provided through {@link NamedPredicateOptionsStep#param(String, Object)}. + * + * @see NamedValues#get(String, Class) + * @see NamedValues#getOptional(String, Class) + */ + NamedValues params(); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/BooleanPredicateOptionsCollector.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/BooleanPredicateOptionsCollector.java index 1f2c3c00031..78a9a476443 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/BooleanPredicateOptionsCollector.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/BooleanPredicateOptionsCollector.java @@ -10,7 +10,7 @@ import org.hibernate.search.engine.search.predicate.SearchPredicate; /** - * An object where the clauses and options of a {@link SearchPredicateFactory#bool() boolean predicate} can be set. + * An object where the clauses and options of a {@link TypedSearchPredicateFactory#bool() boolean predicate} can be set. *

* Different types of clauses have different effects, see below. * @@ -167,7 +167,7 @@ default S filter(PredicateFinalStep dslFinalStep) { * Should generally be a lambda expression. * @return {@code this}, for method chaining. */ - S must(Function, ? extends PredicateFinalStep> clauseContributor); + S must(Function, ? extends PredicateFinalStep> clauseContributor); /** * Add a "must not" clause to be defined by the given function. @@ -179,7 +179,7 @@ default S filter(PredicateFinalStep dslFinalStep) { * Should generally be a lambda expression. * @return {@code this}, for method chaining. */ - S mustNot(Function, ? extends PredicateFinalStep> clauseContributor); + S mustNot(Function, ? extends PredicateFinalStep> clauseContributor); /** * Add a "should" clause to be defined by the given function. @@ -191,7 +191,7 @@ default S filter(PredicateFinalStep dslFinalStep) { * Should generally be a lambda expression. * @return {@code this}, for method chaining. */ - S should(Function, ? extends PredicateFinalStep> clauseContributor); + S should(Function, ? extends PredicateFinalStep> clauseContributor); /** * Add a "filter" clause to be defined by the given function. @@ -203,7 +203,7 @@ default S filter(PredicateFinalStep dslFinalStep) { * Should generally be a lambda expression. * @return {@code this}, for method chaining. */ - S filter(Function, ? extends PredicateFinalStep> clauseContributor); + S filter(Function, ? extends PredicateFinalStep> clauseContributor); /** * Checks if this predicate contains at least one clause. diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExtendedSearchPredicateFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExtendedSearchPredicateFactory.java index 111ee223fc6..b8cc920e20f 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExtendedSearchPredicateFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/ExtendedSearchPredicateFactory.java @@ -4,8 +4,11 @@ */ package org.hibernate.search.engine.search.predicate.dsl; +import org.hibernate.search.util.common.SearchException; +import org.hibernate.search.util.common.annotation.Incubating; + /** - * A base interface for subtypes of {@link SearchPredicateFactory} allowing to + * A base interface for subtypes of {@link TypedSearchPredicateFactory} allowing to * easily override the self type for all relevant methods. *

* Warning: Generic parameters of this type are subject to change, @@ -15,9 +18,14 @@ * @param The self type, i.e. the exposed type of this factory. */ public interface ExtendedSearchPredicateFactory> - extends SearchPredicateFactory { + extends TypedSearchPredicateFactory { @Override S withRoot(String objectFieldPath); + /** + * @throws SearchException In case the current factory cannot be rescoped for the {@code scopeRootType}. + */ + @Incubating + ExtendedSearchPredicateFactory withScopeRoot(Class scopeRootType); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericBooleanPredicateClausesStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericBooleanPredicateClausesStep.java index e7f6a93e6ee..3b089058346 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericBooleanPredicateClausesStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericBooleanPredicateClausesStep.java @@ -62,16 +62,16 @@ default S filter(PredicateFinalStep dslFinalStep) { } @Override - S must(Function, ? extends PredicateFinalStep> clauseContributor); + S must(Function, ? extends PredicateFinalStep> clauseContributor); @Override - S mustNot(Function, ? extends PredicateFinalStep> clauseContributor); + S mustNot(Function, ? extends PredicateFinalStep> clauseContributor); @Override - S should(Function, ? extends PredicateFinalStep> clauseContributor); + S should(Function, ? extends PredicateFinalStep> clauseContributor); @Override - S filter(Function, ? extends PredicateFinalStep> clauseContributor); + S filter(Function, ? extends PredicateFinalStep> clauseContributor); @Override default S minimumShouldMatchNumber(int matchingClausesNumber) { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericSimpleBooleanPredicateClausesStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericSimpleBooleanPredicateClausesStep.java index 4255dd5e7dc..0da8349e8e2 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericSimpleBooleanPredicateClausesStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/GenericSimpleBooleanPredicateClausesStep.java @@ -33,7 +33,7 @@ default S add(PredicateFinalStep searchPredicate) { S add(SearchPredicate searchPredicate); @Override - S add(Function, ? extends PredicateFinalStep> clauseContributor); + S add(Function, ? extends PredicateFinalStep> clauseContributor); @Override S with(Consumer contributor); diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateOptionsStep.java index 549672973e0..4c1eef1a5c9 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/KnnPredicateOptionsStep.java @@ -22,7 +22,7 @@ default KnnPredicateOptionsStep filter(PredicateFinalStep searchPredicate) { } KnnPredicateOptionsStep filter( - Function, ? extends PredicateFinalStep> clauseContributor); + Function, ? extends PredicateFinalStep> clauseContributor); /** * @param similarity A similarity limit: documents with vectors distance to which, according to the configured similarity function, diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchAllPredicateOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchAllPredicateOptionsStep.java index fa672272cf5..ee5144b93da 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchAllPredicateOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/MatchAllPredicateOptionsStep.java @@ -61,6 +61,6 @@ default S except(PredicateFinalStep dslFinalStep) { * Should generally be a lambda expression. * @return {@code this}, for method chaining. */ - S except(Function, ? extends PredicateFinalStep> clauseContributor); + S except(Function, ? extends PredicateFinalStep> clauseContributor); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesCollector.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesCollector.java index 03912dc4ec0..d91d0ea5bf7 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesCollector.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesCollector.java @@ -6,10 +6,10 @@ /** * An object where the clauses - * of a {@link SearchPredicateFactory#nested(String) nested predicate} can be set. + * of a {@link TypedSearchPredicateFactory#nested(String) nested predicate} can be set. *

* The resulting nested predicate must match all inner clauses, - * similarly to an {@link SearchPredicateFactory#and() "and" predicate}. + * similarly to an {@link TypedSearchPredicateFactory#and() "and" predicate}. * * @param Scope root type. */ diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesStep.java index af61eb2b7de..4e66dee9b5c 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateClausesStep.java @@ -9,7 +9,7 @@ * clauses can be added. *

* The resulting nested predicate must match all inner clauses, - * similarly to an {@link SearchPredicateFactory#and() "and" predicate}. + * similarly to an {@link TypedSearchPredicateFactory#and() "and" predicate}. * * @param Scope root type. * @param The "self" type (the actual exposed type of this step). diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateFieldStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateFieldStep.java index cda439347be..914e48bed10 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateFieldStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateFieldStep.java @@ -12,7 +12,7 @@ * * @param Scope root type. * @param The type of the next step. - * @deprecated Use {@link SearchPredicateFactory#nested(String)} instead. + * @deprecated Use {@link TypedSearchPredicateFactory#nested(String)} instead. */ @Deprecated(since = "6.2") public interface NestedPredicateFieldStep> { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateNestStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateNestStep.java index 42d5927f5e8..4184e058db4 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateNestStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateNestStep.java @@ -12,7 +12,7 @@ * The step in a "nested" predicate definition where the predicate to nest can be set. * * @param The type of the next step. - * @deprecated Use {@link SearchPredicateFactory#nested(String)} instead. + * @deprecated Use {@link TypedSearchPredicateFactory#nested(String)} instead. */ @Deprecated(since = "6.2") public interface NestedPredicateNestStep> { @@ -65,6 +65,6 @@ default N nest(PredicateFinalStep dslFinalStep) { * Should generally be a lambda expression. * @return The next step. */ - N nest(Function, ? extends PredicateFinalStep> predicateContributor); + N nest(Function, ? extends PredicateFinalStep> predicateContributor); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateOptionsStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateOptionsStep.java index 565b1bfec00..ca4881f67b0 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateOptionsStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/NestedPredicateOptionsStep.java @@ -8,7 +8,7 @@ * The final step in an "nested" predicate definition, where optional parameters can be set. * * @param The "self" type (the actual exposed type of this step). - * @deprecated Use {@link SearchPredicateFactory#nested(String)} instead. + * @deprecated Use {@link TypedSearchPredicateFactory#nested(String)} instead. */ @Deprecated(since = "6.2") public interface NestedPredicateOptionsStep> 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 2e29a4c24c5..cfcbf4fc1b6 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 @@ -4,15 +4,7 @@ */ package org.hibernate.search.engine.search.predicate.dsl; -import java.util.function.Consumer; -import java.util.function.Function; - -import org.hibernate.search.engine.backend.types.ObjectStructure; -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.engine.search.common.NonStaticMetamodelScope; import org.hibernate.search.util.common.annotation.Incubating; /** @@ -43,333 +35,8 @@ * Such reference provides the information on which search capabilities the particular index field possesses, and allows switching between different * {@link org.hibernate.search.engine.search.common.ValueModel value model representations}. * - * @param Scope root type. */ -public interface SearchPredicateFactory { - - /** - * Match all documents. - * - * @return The initial step of a DSL where the "match all" predicate can be defined. - * @see MatchAllPredicateOptionsStep - */ - MatchAllPredicateOptionsStep matchAll(); - - /** - * Match none of the documents. - * - * @return The initial step of a DSL where the "match none" predicate can be defined. - * @see MatchNonePredicateFinalStep - */ - MatchNonePredicateFinalStep matchNone(); - - /** - * Match documents where the identifier is among the given values. - * - * @return The initial step of a DSL allowing the definition of an "id" predicate. - * @see MatchIdPredicateMatchingStep - */ - MatchIdPredicateMatchingStep id(); - - /** - * Match documents if they match a combination of boolean clauses. - * - * @return The initial step of a DSL where the "boolean" predicate can be defined. - * @see BooleanPredicateClausesStep - */ - BooleanPredicateClausesStep bool(); - - /** - * Match documents if they match a combination of boolean clauses, - * which will be defined by the given consumer. - *

- * Best used with lambda expressions. - * - * @param clauseContributor A consumer that will add clauses to the step passed in parameter. - * Should generally be a lambda expression. - * @return The final step of the boolean predicate definition. - * @deprecated Use {@code .bool().with(...)} instead. - * @see BooleanPredicateClausesStep#with(Consumer) - */ - @Deprecated(since = "6.2") - PredicateFinalStep bool(Consumer> clauseContributor); - - /** - * Match documents if they match all inner clauses. - * - * @return The initial step of a DSL where predicates that must match can be added and options can be set. - * @see GenericSimpleBooleanPredicateClausesStep - */ - SimpleBooleanPredicateClausesStep and(); - - /** - * Match documents if they match all previously-built {@link SearchPredicate}. - * - * @return The step of a DSL where options can be set. - */ - SimpleBooleanPredicateOptionsStep and( - SearchPredicate firstSearchPredicate, - SearchPredicate... otherSearchPredicates); - - /** - * Match documents if they match all clauses. - * - * @return The step of a DSL where options can be set. - */ - SimpleBooleanPredicateOptionsStep and(PredicateFinalStep firstSearchPredicate, - PredicateFinalStep... otherSearchPredicates); - - /** - * Match documents if they match any inner clause. - * - * @return The initial step of a DSL where predicates that should match can be added and options can be set. - * @see GenericSimpleBooleanPredicateClausesStep - */ - SimpleBooleanPredicateClausesStep or(); - - /** - * Match documents if they match any previously-built {@link SearchPredicate}. - * - * @return The step of a DSL where options can be set. - */ - SimpleBooleanPredicateOptionsStep or(SearchPredicate firstSearchPredicate, - SearchPredicate... otherSearchPredicates); - - /** - * Match documents if they match any clause. - * - * @return The step of a DSL where options can be set. - */ - SimpleBooleanPredicateOptionsStep or(PredicateFinalStep firstSearchPredicate, - PredicateFinalStep... otherSearchPredicates); - - /** - * Match documents that do not satisfy the passed in previously-built {@link SearchPredicate}. - *

- * Can be used to negate a predicate. - * - * @return The initial and final step of a DSL where the "not" predicate can be defined. - * @see NotPredicateFinalStep - */ - NotPredicateFinalStep not(SearchPredicate searchPredicate); - - /** - * Match documents that do not satisfy the passed in predicate. - *

- * Can be used to negate a predicate. - * - * @return The initial and final step of a DSL where the "not" predicate can be defined. - * @see NotPredicateFinalStep - */ - NotPredicateFinalStep not(PredicateFinalStep searchPredicate); - - /** - * Match documents where targeted fields have a value that "matches" a given single value. - *

- * Note that "value matching" may be exact or approximate depending on the type of the targeted fields: - * numeric fields in particular imply exact matches, - * while analyzed, full-text fields imply approximate matches depending on how they are analyzed. - * - * @return The initial step of a DSL where the "match" predicate can be defined. - * @see MatchPredicateFieldStep - */ - MatchPredicateFieldStep match(); - - /** - * Match documents where targeted fields have a value within lower and upper bounds. - * - * @return The initial step of a DSL where the "range" predicate can be defined. - * @see RangePredicateFieldStep - */ - RangePredicateFieldStep range(); - - /** - * Match documents where targeted fields have a value that contains a given phrase. - * - * @return The initial step of a DSL where the "phrase" predicate can be defined. - * @see PhrasePredicateFieldStep - */ - PhrasePredicateFieldStep phrase(); - - /** - * Match documents where targeted fields contain a term that matches a given pattern, - * such as {@code inter*on} or {@code pa?t}. - *

- * Note that such patterns are not analyzed, - * thus any character that is not a wildcard must match exactly the content of the index - * (including uppercase letters, diacritics, ...). - * - * @return The initial step of a DSL where the "wildcard" predicate can be defined. - * @see WildcardPredicateFieldStep - */ - WildcardPredicateFieldStep wildcard(); - - /** - * Match documents where targeted fields have a value that starts with a given string. - * - * @return The initial step of a DSL where the "prefix" predicate can be defined. - * @see PrefixPredicateFieldStep - */ - PrefixPredicateFieldStep prefix(); - - /** - * Match documents where targeted fields contain a term that matches a given regular expression. - * - * @return The initial step of a DSL where the "regexp" predicate can be defined. - * @see RegexpPredicateFieldStep - */ - RegexpPredicateFieldStep regexp(); - - /** - * Match documents where targeted fields contain a term that matches some terms of a given series of terms. - * - * @return The initial step of a DSL where the "terms" predicate can be defined. - * @see TermsPredicateFieldStep - */ - TermsPredicateFieldStep terms(); - - /** - * Match documents where a {@link ObjectStructure#NESTED nested object} matches a given predicate. - * - * @return The initial step of a DSL where the "nested" predicate can be defined. - * @see NestedPredicateFieldStep - * @deprecated Use {@link #nested(String)} instead. - */ - @Deprecated(since = "6.2") - NestedPredicateFieldStep nested(); - - /** - * 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 objectFieldPath The path to the (nested) object field that must match. - * @return The initial step of a DSL where the "nested" predicate can be defined. - * @see NestedPredicateFieldStep - */ - 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 fieldReference The field reference representing a definition of 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 fieldReference) { - return nested( fieldReference.absolutePath() ); - } - - /** - * Match documents according to a given query string, - * with a simple query language adapted to end users. - *

- * Note that by default, unless the query string contains explicit operators, - * documents will match if any term mentioned in the query string is present in the document (OR operator). - * This makes sense when sorting results by relevance, but is not ideal otherwise. - * See {@link SimpleQueryStringPredicateOptionsStep#defaultOperator(BooleanOperator)} to change this behavior. - * - * @return The initial step of a DSL where the "simple query string" predicate can be defined. - * @see SimpleQueryStringPredicateFieldStep - */ - SimpleQueryStringPredicateFieldStep simpleQueryString(); - - /** - * Match documents according to a given query string, - * using the Lucene's query language. - *

- * Note that by default, unless the query string contains explicit operators, - * documents will match if any term mentioned in the query string is present in the document (OR operator). - * This makes sense when sorting results by relevance, but is not ideal otherwise. - * See {@link QueryStringPredicateOptionsStep#defaultOperator(BooleanOperator)} to change this behavior. - * - * @return The initial step of a DSL where the "query string" predicate can be defined. - * @see QueryStringPredicateFieldStep - */ - QueryStringPredicateFieldStep queryString(); - - /** - * Match documents where a given field exists. - *

- * Fields are considered to exist in a document when they have at least one non-null value in this document. - * - * @return The initial step of a DSL where the "exists" predicate can be defined. - * @see ExistsPredicateFieldStep - */ - ExistsPredicateFieldStep exists(); - - /** - * Access the different types of spatial predicates. - * - * @return The initial step of a DSL where spatial predicates can be defined. - * @see SpatialPredicateInitialStep - */ - SpatialPredicateInitialStep spatial(); - - /** - * Match documents if they match a combination of defined named predicate clauses. - * - * @param path The path to the named predicate, - * formatted as {@code .}, - * or just {@code } if the predicate was declared at the root. - * @return The initial step of a DSL where named predicate predicates can be defined. - * @see NamedPredicateOptionsStep - */ - @Incubating - NamedPredicateOptionsStep named(String path); - - /** - * Match {@code k} documents whose vector field value is nearest to the given vector. - *

- * "knn" stands for "K-Nearest Neighbors"; it is a form of vector search. - * - * @param k The number of nearest neighbors to look for. - * @return The initial step of a DSL where knn predicate options can be defined. - * @see KnnPredicateVectorStep - * @see KnnPredicateOptionsStep - */ - KnnPredicateFieldStep knn(int k); - - /** - * Delegating predicate that creates the actual predicate at query create time and provides access to query parameters. - *

- * Which predicate exactly to create is defined by a function passed to the arguments of this predicate. - * - * @param predicateCreator The function defining an actual predicate to apply. - * @return A final DSL step in a parameterized predicate definition. - */ - @Incubating - PredicateFinalStep withParameters( - Function predicateCreator); - - /** - * Extend the current factory with the given extension, - * resulting in an extended factory offering different types of predicates. - * - * @param extension The extension to the predicate DSL. - * @param The type of factory provided by the extension. - * @return The extended factory. - * @throws SearchException If the extension cannot be applied (wrong underlying backend, ...). - */ - T extension(SearchPredicateFactoryExtension extension); - - /** - * Create a DSL step allowing multiple attempts to apply extensions one after the other, - * failing only if none of the extensions is supported. - *

- * If you only need to apply a single extension and fail if it is not supported, - * use the simpler {@link #extension(SearchPredicateFactoryExtension)} method instead. - * - * @return A DSL step. - */ - SearchPredicateFactoryExtensionIfSupportedStep extension(); +public interface SearchPredicateFactory extends TypedSearchPredicateFactory { /** * Create a new predicate factory whose root for all paths passed to the DSL @@ -381,15 +48,8 @@ PredicateFinalStep withParameters( * @param objectFieldPath The path from the current root to an object field that will become the new root. * @return A new predicate factory using the given object field as root. */ + @Override @Incubating - SearchPredicateFactory withRoot(String objectFieldPath); - - /** - * @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 predicates for example. - * Note the path is returned even if the field doesn't exist. - */ - @Incubating - String toAbsolutePath(String relativeFieldPath); + SearchPredicateFactory withRoot(String objectFieldPath); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtension.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtension.java index 77ee8c42cd6..f267b9942ab 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtension.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtension.java @@ -15,9 +15,9 @@ * and pass it to another API. * * @param The type of extended predicate factories. Should generally extend - * {@link SearchPredicateFactory}. + * {@link TypedSearchPredicateFactory}. * - * @see SearchPredicateFactory#extension(SearchPredicateFactoryExtension) + * @see TypedSearchPredicateFactory#extension(SearchPredicateFactoryExtension) * @see ExtendedSearchPredicateFactory */ public interface SearchPredicateFactoryExtension { @@ -27,10 +27,10 @@ public interface SearchPredicateFactoryExtension { *

* WARNING: this method is not API, see comments at the type level. * - * @param original The original, non-extended {@link SearchPredicateFactory}. + * @param original The original, non-extended {@link TypedSearchPredicateFactory}. * @return An optional containing the extended search predicate factory ({@link T}) in case * of success, or an empty optional otherwise. */ - Optional extendOptional(SearchPredicateFactory original); + Optional extendOptional(TypedSearchPredicateFactory original); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedMoreStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedMoreStep.java index 52a14e107b2..3c4153537af 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedMoreStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedMoreStep.java @@ -10,16 +10,16 @@ /** * The second and later step when attempting to apply multiple extensions - * to a {@link SearchPredicateFactory}. + * to a {@link TypedSearchPredicateFactory}. * - * @see SearchPredicateFactory#extension() + * @see TypedSearchPredicateFactory#extension() */ public interface SearchPredicateFactoryExtensionIfSupportedMoreStep extends SearchPredicateFactoryExtensionIfSupportedStep { /** * If no extension passed to {@link #ifSupported(SearchPredicateFactoryExtension, Function)} - * was supported so far, apply the given consumer to the current (non-extended) {@link SearchPredicateFactory}; + * was supported so far, apply the given consumer to the current (non-extended) {@link TypedSearchPredicateFactory}; * otherwise return the predicate created in the first succeeding {@code ifSupported} call. * * @param predicateContributor A function called if no extension was successfully applied; @@ -29,7 +29,7 @@ public interface SearchPredicateFactoryExtensionIfSupportedMoreStep * @return The final step in the DSL of the resulting predicate. */ PredicateFinalStep orElse( - Function, ? extends PredicateFinalStep> predicateContributor); + Function, ? extends PredicateFinalStep> predicateContributor); /** * If no extension passed to {@link #ifSupported(SearchPredicateFactoryExtension, Function)} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedStep.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedStep.java index ecbc144c4ee..f22320a88f9 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SearchPredicateFactoryExtensionIfSupportedStep.java @@ -8,9 +8,9 @@ /** * The initial step when attempting to apply multiple extensions - * to a {@link SearchPredicateFactory}. + * to a {@link TypedSearchPredicateFactory}. * - * @see SearchPredicateFactory#extension() + * @see TypedSearchPredicateFactory#extension() */ public interface SearchPredicateFactoryExtensionIfSupportedStep { diff --git a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleBooleanPredicateClausesCollector.java b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleBooleanPredicateClausesCollector.java index ff1ffd83bc0..3be391cd940 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleBooleanPredicateClausesCollector.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/predicate/dsl/SimpleBooleanPredicateClausesCollector.java @@ -12,7 +12,7 @@ /** * An object where the clauses and options of a simple boolean predicate - * ({@link SearchPredicateFactory#and() and}, {@link SearchPredicateFactory#or() or}) + * ({@link TypedSearchPredicateFactory#and() and}, {@link TypedSearchPredicateFactory#or() or}) * can be set. * *

Clauses

@@ -22,15 +22,15 @@ * or any clause: *