diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextMatchPredicateBuilder.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextMatchPredicateBuilder.java index a313d609323..8faaabe8088 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextMatchPredicateBuilder.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextMatchPredicateBuilder.java @@ -34,13 +34,11 @@ class LuceneTextMatchPredicateBuilder private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() ); - private final QueryBuilder queryBuilder; private final LuceneAnalysisDefinitionRegistry analysisDefinitionRegistry; private Integer maxEditDistance; private Integer prefixLength; - private Analyzer overrideAnalyzer; - private boolean ignoreAnalyzer = false; + private Analyzer analyzer; LuceneTextMatchPredicateBuilder( LuceneSearchContext searchContext, @@ -49,7 +47,7 @@ class LuceneTextMatchPredicateBuilder LuceneConverterCompatibilityChecker converterChecker, LuceneTextFieldCodec codec, QueryBuilder queryBuilder) { super( searchContext, absoluteFieldPath, converter, rawConverter, converterChecker, codec ); - this.queryBuilder = queryBuilder; + this.analyzer = ( queryBuilder == null ) ? null : queryBuilder.getAnalyzer(); this.analysisDefinitionRegistry = searchContext.getAnalysisDefinitionRegistry(); } @@ -61,27 +59,26 @@ public void fuzzy(int maxEditDistance, int exactPrefixLength) { @Override public void analyzer(String analyzerName) { - this.overrideAnalyzer = analysisDefinitionRegistry.getAnalyzerDefinition( analyzerName ); - if ( overrideAnalyzer == null ) { + this.analyzer = analysisDefinitionRegistry.getAnalyzerDefinition( analyzerName ); + if ( analyzer == null ) { throw log.unknownAnalyzer( analyzerName, EventContexts.fromIndexFieldAbsolutePath( absoluteFieldPath ) ); } } @Override public void ignoreAnalyzer() { - this.ignoreAnalyzer = true; + this.analyzer = AnalyzerUtils.KEYWORD_ANALYZER; } @Override protected Query doBuild(LuceneSearchPredicateContext context) { - if ( queryBuilder != null ) { + if ( analyzer != null ) { QueryBuilder effectiveQueryBuilder; if ( maxEditDistance != null ) { - effectiveQueryBuilder = new FuzzyQueryBuilder( getAnalyzer(), maxEditDistance, prefixLength ); + effectiveQueryBuilder = new FuzzyQueryBuilder( analyzer, maxEditDistance, prefixLength ); } else { - queryBuilder.setAnalyzer( getAnalyzer() ); - effectiveQueryBuilder = queryBuilder; + effectiveQueryBuilder = new QueryBuilder( analyzer ); } Query analyzed = effectiveQueryBuilder.createBooleanQuery( absoluteFieldPath, value ); @@ -106,14 +103,4 @@ protected Query doBuild(LuceneSearchPredicateContext context) { } } } - - private Analyzer getAnalyzer() { - if ( ignoreAnalyzer ) { - return AnalyzerUtils.KEYWORD_ANALYZER; - } - if ( overrideAnalyzer != null ) { - return overrideAnalyzer; - } - return queryBuilder.getAnalyzer(); - } } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextPhrasePredicateBuilder.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextPhrasePredicateBuilder.java index 2876732369d..1221c372fc2 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextPhrasePredicateBuilder.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/predicate/impl/LuceneTextPhrasePredicateBuilder.java @@ -35,13 +35,11 @@ class LuceneTextPhrasePredicateBuilder extends AbstractLuceneSearchPredicateBuil protected final String absoluteFieldPath; protected final LuceneTextFieldCodec codec; - private final QueryBuilder queryBuilder; private final LuceneAnalysisDefinitionRegistry analysisDefinitionRegistry; private int slop; private String phrase; - private Analyzer overrideAnalyzer; - private boolean ignoreAnalyzer = false; + private Analyzer analyzer; LuceneTextPhrasePredicateBuilder( LuceneSearchContext searchContext, String absoluteFieldPath, @@ -49,7 +47,7 @@ class LuceneTextPhrasePredicateBuilder extends AbstractLuceneSearchPredicateBuil QueryBuilder queryBuilder) { this.absoluteFieldPath = absoluteFieldPath; this.codec = codec; - this.queryBuilder = queryBuilder; + this.analyzer = ( queryBuilder == null ) ? null : queryBuilder.getAnalyzer(); this.analysisDefinitionRegistry = searchContext.getAnalysisDefinitionRegistry(); } @@ -65,28 +63,21 @@ public void phrase(String phrase) { @Override public void analyzer(String analyzerName) { - this.overrideAnalyzer = analysisDefinitionRegistry.getAnalyzerDefinition( analyzerName ); - if ( overrideAnalyzer == null ) { + this.analyzer = analysisDefinitionRegistry.getAnalyzerDefinition( analyzerName ); + if ( analyzer == null ) { throw log.unknownAnalyzer( analyzerName, EventContexts.fromIndexFieldAbsolutePath( absoluteFieldPath ) ); } } @Override public void ignoreAnalyzer() { - this.ignoreAnalyzer = true; + this.analyzer = AnalyzerUtils.KEYWORD_ANALYZER; } @Override protected Query doBuild(LuceneSearchPredicateContext context) { - if ( queryBuilder != null ) { - if ( ignoreAnalyzer ) { - queryBuilder.setAnalyzer( AnalyzerUtils.KEYWORD_ANALYZER ); - } - else if ( overrideAnalyzer != null ) { - queryBuilder.setAnalyzer( overrideAnalyzer ); - } - - Query analyzed = queryBuilder.createPhraseQuery( absoluteFieldPath, phrase, slop ); + if ( analyzer != null ) { + Query analyzed = new QueryBuilder( analyzer ).createPhraseQuery( absoluteFieldPath, phrase, slop ); if ( analyzed == null ) { // Either the value was an empty string // or the analysis removed all tokens (that can happen if the value contained only stopwords, for example) diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/MatchSearchPredicateIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/MatchSearchPredicateIT.java index ca8189855de..f6802bac1d5 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/MatchSearchPredicateIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/MatchSearchPredicateIT.java @@ -916,6 +916,22 @@ public void analyzerIgnore_fuzzy() { .hasDocRefHitsAnyOrder( INDEX_NAME, DOCUMENT_1, DOCUMENT_2, DOCUMENT_3 ); } + @Test + public void analyzerOverride_normalizedStringField() { + StubMappingSearchScope scope = indexManager.createSearchScope(); + String absoluteFieldPath = indexMapping.normalizedStringField.relativeFieldName; + + IndexSearchQuery query = scope.query() + .asReference() + // the matching parameter will be tokenized even if the field has a normalizer + .predicate( f -> f.match().onField( absoluteFieldPath ).matching( "Auster Coe" ) + .analyzer( OverrideAnalysisDefinitions.ANALYZER_WHITESPACE_LOWERCASE.name ) ) + .toQuery(); + + assertThat( query ) + .hasDocRefHitsAnyOrder( INDEX_NAME, DOCUMENT_2, DOCUMENT_3 ); + } + @Test public void multiFields() { StubMappingSearchScope scope = indexManager.createSearchScope();