diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/LuceneAnalysisConfigurationContext.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/LuceneAnalysisConfigurationContext.java index 63af6dc8d38..97dbde482c4 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/LuceneAnalysisConfigurationContext.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/LuceneAnalysisConfigurationContext.java @@ -9,6 +9,8 @@ import org.hibernate.search.backend.lucene.analysis.model.dsl.LuceneAnalyzerTypeStep; import org.hibernate.search.backend.lucene.analysis.model.dsl.LuceneNormalizerTypeStep; +import org.apache.lucene.search.similarities.Similarity; + /** * A context allowing the definition of named analyzers and normalizers in a Lucene backend. */ @@ -30,4 +32,13 @@ public interface LuceneAnalysisConfigurationContext { */ LuceneNormalizerTypeStep normalizer(String name); + /** + * Set the {@link Similarity}. + *

+ * Defaults to {@link org.apache.lucene.search.similarities.BM25Similarity}. + * + * @param similarity The {@link Similarity} to use when indexing and when searching. + */ + void similarity(Similarity similarity); + } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/dsl/impl/LuceneAnalysisConfigurationContextImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/dsl/impl/LuceneAnalysisConfigurationContextImpl.java index 1e2db1bb824..8b31e0b98ff 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/dsl/impl/LuceneAnalysisConfigurationContextImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/dsl/impl/LuceneAnalysisConfigurationContextImpl.java @@ -9,6 +9,7 @@ import java.lang.invoke.MethodHandles; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Optional; import org.hibernate.search.backend.lucene.analysis.impl.LuceneAnalysisComponentFactory; import org.hibernate.search.backend.lucene.analysis.LuceneAnalysisConfigurationContext; @@ -22,7 +23,7 @@ import org.hibernate.search.util.common.logging.impl.LoggerFactory; import org.apache.lucene.analysis.Analyzer; - +import org.apache.lucene.search.similarities.Similarity; public class LuceneAnalysisConfigurationContextImpl @@ -32,6 +33,8 @@ public class LuceneAnalysisConfigurationContextImpl private final LuceneAnalysisComponentFactory factory; + private Similarity similarity; + private final Map analyzers = new LinkedHashMap<>(); private final Map normalizers = new LinkedHashMap<>(); @@ -78,6 +81,11 @@ public LuceneAnalysisConfigurationContext instance(Analyzer instance) { }; } + @Override + public void similarity(Similarity similarity) { + this.similarity = similarity; + } + @Override public void contribute(LuceneAnalysisDefinitionCollector collector) { for ( Map.Entry entry : analyzers.entrySet() ) { @@ -88,6 +96,11 @@ public void contribute(LuceneAnalysisDefinitionCollector collector) { } } + @Override + public Optional getSimilarity() { + return Optional.ofNullable( similarity ); + } + private void addAnalyzer(String name, LuceneAnalyzerBuilder definition) { LuceneAnalysisComponentBuilder existing = analyzers.putIfAbsent( name, definition ); if ( existing != null ) { diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionContributor.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionContributor.java index 789d08d6d0d..ddc96e15abc 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionContributor.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionContributor.java @@ -7,8 +7,14 @@ package org.hibernate.search.backend.lucene.analysis.model.impl; +import java.util.Optional; + +import org.apache.lucene.search.similarities.Similarity; + public interface LuceneAnalysisDefinitionContributor { void contribute(LuceneAnalysisDefinitionCollector collector); + Optional getSimilarity(); + } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionRegistry.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionRegistry.java index 7766273c503..d7016421daa 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionRegistry.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/analysis/model/impl/LuceneAnalysisDefinitionRegistry.java @@ -15,6 +15,8 @@ import org.hibernate.search.util.common.logging.impl.LoggerFactory; import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.search.similarities.BM25Similarity; +import org.apache.lucene.search.similarities.Similarity; /** * A registry of analysis-related definitions for Lucene. @@ -24,17 +26,21 @@ public final class LuceneAnalysisDefinitionRegistry { private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); + private final Similarity similarity; + private final Map analyzerDefinitions; private final Map normalizerDefinitions; public LuceneAnalysisDefinitionRegistry() { // Nothing to do: we're creating an empty registry + similarity = createDefaultSimilarity(); analyzerDefinitions = Collections.emptyMap(); normalizerDefinitions = Collections.emptyMap(); } public LuceneAnalysisDefinitionRegistry(LuceneAnalysisDefinitionContributor contributor) { + similarity = contributor.getSimilarity().orElseGet( LuceneAnalysisDefinitionRegistry::createDefaultSimilarity ); analyzerDefinitions = new TreeMap<>(); normalizerDefinitions = new TreeMap<>(); contributor.contribute( new LuceneAnalysisDefinitionCollector() { @@ -56,6 +62,10 @@ public void collectNormalizer(String name, Analyzer normalizer) { } ); } + public Similarity getSimilarity() { + return similarity; + } + /** * @param name An analyzer name * @return The analyzer definition associated with the given name, @@ -74,4 +84,7 @@ public Analyzer getNormalizerDefinition(String name) { return normalizerDefinitions.get( name ); } + private static Similarity createDefaultSimilarity() { + return new BM25Similarity(); + } } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/cfg/LuceneBackendSettings.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/cfg/LuceneBackendSettings.java index 62c08ced35a..618933af645 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/cfg/LuceneBackendSettings.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/cfg/LuceneBackendSettings.java @@ -10,10 +10,7 @@ import org.hibernate.search.backend.lucene.lowlevel.directory.FileSystemAccessStrategyName; import org.hibernate.search.backend.lucene.lowlevel.directory.LockingStrategyName; import org.hibernate.search.backend.lucene.multitenancy.MultiTenancyStrategyName; -import org.hibernate.search.engine.environment.bean.BeanReference; -import org.apache.lucene.search.similarities.BM25Similarity; -import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.util.Version; /** @@ -96,19 +93,6 @@ private LuceneBackendSettings() { public static final String DIRECTORY_FILESYSTEM_ACCESS_STRATEGY = DIRECTORY_PREFIX + DirectoryRadicals.FILESYSTEM_ACCESS_STRATEGY; - /** - * The {@link org.apache.lucene.search.similarities.Similarity} to be used when indexing and querying. - *

- * Expects the fully qualified name of a concrete implementation of {@link org.apache.lucene.search.similarities.Similarity}, - * or a reference to a bean of that type. - *

- * Defaults to {@link BM25Similarity}. - * - * @see org.hibernate.search.engine.cfg The core documentation of configuration properties, - * which includes a description of the "bean reference" properties and accepted values. - */ - public static final String SIMILARITY = "similarity"; - /** * The multi-tenancy strategy to use. *

@@ -171,8 +155,6 @@ private Defaults() { public static final String DIRECTORY_ROOT = "."; - public static final BeanReference SIMILARITY = BeanReference.of( BM25Similarity.class ); - public static final FileSystemAccessStrategyName DIRECTORY_FILESYSTEM_ACCESS_STRATEGY = FileSystemAccessStrategyName.AUTO; diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendFactory.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendFactory.java index 62bd85d84c8..e8829f0a7a9 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendFactory.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendFactory.java @@ -41,7 +41,6 @@ import org.hibernate.search.util.common.AssertionFailure; import org.hibernate.search.util.common.logging.impl.LoggerFactory; -import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.util.Version; @@ -55,12 +54,6 @@ public class LuceneBackendFactory implements BackendFactory { .as( Version.class, LuceneBackendFactory::parseLuceneVersion ) .build(); - private static final ConfigurationProperty> SIMILARITY = - ConfigurationProperty.forKey( LuceneBackendSettings.SIMILARITY ) - .asBeanReference( Similarity.class ) - .withDefault( LuceneBackendSettings.Defaults.SIMILARITY ) - .build(); - private static final ConfigurationProperty MULTI_TENANCY_STRATEGY = ConfigurationProperty.forKey( LuceneBackendSettings.MULTI_TENANCY_STRATEGY ) .as( MultiTenancyStrategyName.class, MultiTenancyStrategyName::of ) @@ -79,7 +72,6 @@ public BackendImplementor create(String name, BackendBuildContext buildContext, BackendThreads backendThreads = null; BeanHolder directoryProviderHolder = null; - BeanHolder similarityHolder = null; try { backendThreads = new BackendThreads( "Backend " + name ); @@ -88,8 +80,6 @@ public BackendImplementor create(String name, BackendBuildContext buildContext, directoryProviderHolder = getDirectoryProvider( backendContext, buildContext, propertySource ); - similarityHolder = getSimilarity( buildContext, propertySource ); - MultiTenancyStrategy multiTenancyStrategy = getMultiTenancyStrategy( propertySource ); LuceneAnalysisDefinitionRegistry analysisDefinitionRegistry = getAnalysisDefinitionRegistry( @@ -99,7 +89,7 @@ public BackendImplementor create(String name, BackendBuildContext buildContext, return new LuceneBackendImpl( name, backendThreads, - directoryProviderHolder, similarityHolder, + directoryProviderHolder, new LuceneWorkFactoryImpl( multiTenancyStrategy ), analysisDefinitionRegistry, multiTenancyStrategy, @@ -109,7 +99,6 @@ public BackendImplementor create(String name, BackendBuildContext buildContext, } catch (RuntimeException e) { new SuppressingCloser( e ) - .push( BeanHolder::close, similarityHolder ) .push( holder -> holder.get().close(), directoryProviderHolder ) .push( BeanHolder::close, directoryProviderHolder ) .push( BackendThreads::onStop, backendThreads ); @@ -148,12 +137,6 @@ private BeanHolder getDirectoryProvider(EventContex return initializationContext.createDirectoryProvider(); } - private BeanHolder getSimilarity(BackendBuildContext buildContext, - ConfigurationPropertySource propertySource) { - BeanResolver beanResolver = buildContext.getBeanResolver(); - return SIMILARITY.getAndTransform( propertySource, beanResolver::resolve ); - } - private MultiTenancyStrategy getMultiTenancyStrategy(ConfigurationPropertySource propertySource) { MultiTenancyStrategyName multiTenancyStrategyName = MULTI_TENANCY_STRATEGY.get( propertySource ); diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendImpl.java index 700f529040c..d5e38c010e3 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/impl/LuceneBackendImpl.java @@ -45,7 +45,6 @@ public class LuceneBackendImpl implements BackendImplementor, LuceneBackend { private final BackendThreads threads; private final BeanHolder directoryProviderHolder; - private final BeanHolder similarityHolder; private final LuceneAnalysisDefinitionRegistry analysisDefinitionRegistry; @@ -59,7 +58,6 @@ public class LuceneBackendImpl implements BackendImplementor, LuceneBackend { LuceneBackendImpl(String name, BackendThreads threads, BeanHolder directoryProviderHolder, - BeanHolder similarityHolder, LuceneWorkFactory workFactory, LuceneAnalysisDefinitionRegistry analysisDefinitionRegistry, MultiTenancyStrategy multiTenancyStrategy, @@ -68,19 +66,19 @@ public class LuceneBackendImpl implements BackendImplementor, LuceneBackend { this.name = name; this.threads = threads; this.directoryProviderHolder = directoryProviderHolder; - this.similarityHolder = similarityHolder; this.analysisDefinitionRegistry = analysisDefinitionRegistry; + Similarity similarity = analysisDefinitionRegistry.getSimilarity(); this.readOrchestrator = new LuceneSyncWorkOrchestratorImpl( - "Lucene read work orchestrator for backend " + name, similarityHolder.get() + "Lucene read work orchestrator for backend " + name, similarity ); this.multiTenancyStrategy = multiTenancyStrategy; this.timingSource = timingSource; this.eventContext = EventContexts.fromBackendName( name ); this.indexManagerBackendContext = new IndexManagerBackendContext( - eventContext, threads, directoryProviderHolder.get(), similarityHolder.get(), + eventContext, threads, directoryProviderHolder.get(), similarity, workFactory, multiTenancyStrategy, timingSource, analysisDefinitionRegistry, failureHandler, @@ -113,7 +111,6 @@ public CompletableFuture preStop() { public void stop() { try ( Closer closer = new Closer<>() ) { closer.push( LuceneSyncWorkOrchestratorImpl::stop, readOrchestrator ); - closer.push( BeanHolder::close, similarityHolder ); closer.push( holder -> holder.get().close(), directoryProviderHolder ); closer.push( BeanHolder::close, directoryProviderHolder ); closer.push( TimingSource::stop, timingSource ); diff --git a/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/lowlevel/similarity/LuceneSimilarityIT.java b/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/analysis/LuceneSimilarityIT.java similarity index 87% rename from integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/lowlevel/similarity/LuceneSimilarityIT.java rename to integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/analysis/LuceneSimilarityIT.java index 6bda2da502a..b3f11147dd3 100644 --- a/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/lowlevel/similarity/LuceneSimilarityIT.java +++ b/integrationtest/backend/lucene/src/test/java/org/hibernate/search/integrationtest/backend/lucene/analysis/LuceneSimilarityIT.java @@ -4,11 +4,12 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or . */ -package org.hibernate.search.integrationtest.backend.lucene.lowlevel.similarity; +package org.hibernate.search.integrationtest.backend.lucene.analysis; import static org.assertj.core.api.Assertions.assertThat; import static org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMapperUtils.referenceProvider; +import org.hibernate.search.backend.lucene.analysis.LuceneAnalysisConfigurer; import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings; import org.hibernate.search.backend.lucene.index.impl.LuceneIndexManagerImpl; import org.hibernate.search.backend.lucene.index.impl.Shard; @@ -27,6 +28,7 @@ import org.apache.lucene.index.IndexWriter; import org.apache.lucene.search.similarities.BM25Similarity; import org.apache.lucene.search.similarities.ClassicSimilarity; +import org.apache.lucene.search.similarities.Similarity; public class LuceneSimilarityIT { @@ -64,7 +66,7 @@ public void defaults() { @TestForIssue(jiraKey = "HSEARCH-3777") @PortedFromSearch5(original = "org.hibernate.search.test.similarity.SimilarityTest") public void custom() { - setup( ClassicSimilarity.class.getName() ); + setup( new ClassicSimilarity() ); LuceneIndexManagerImpl luceneIndexManager = index.unwrapForTests( LuceneIndexManagerImpl.class ); assertThat( luceneIndexManager.getShardsForTests() ) @@ -86,10 +88,14 @@ public void custom() { .hasTotalHitCount( 1L ); } - private SearchIntegration setup(String similarity) { + private SearchIntegration setup(Similarity similarity) { return setupHelper.start() .withIndex( index ) - .withBackendProperty( LuceneBackendSettings.SIMILARITY, similarity ) + .withBackendProperty( + LuceneBackendSettings.ANALYSIS_CONFIGURER, + similarity == null ? null + : (LuceneAnalysisConfigurer) context -> context.similarity( similarity ) + ) .setup(); } }