diff --git a/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java b/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java index 331547d1c33..6c5acf6c8ba 100644 --- a/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java +++ b/engine/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java @@ -66,14 +66,21 @@ public Query createQuery() { final int size = fieldsContext.size(); final ConversionContext conversionContext = new ContextualExceptionBridgeHelper(); if ( size == 1 ) { - return queryCustomizer.setWrappedQuery( createQuery( fieldsContext.getFirst(), conversionContext ) ).createQuery(); + FieldContext fieldContext = fieldsContext.getFirst(); + return queryCustomizer.setWrappedQuery( + fieldContext.getFieldCustomizer().setWrappedQuery( + createQuery( fieldContext, conversionContext ) + ).createQuery() + ).createQuery(); } else { BooleanQuery.Builder aggregatedFieldsQueryBuilder = new BooleanQuery.Builder(); for ( FieldContext fieldContext : fieldsContext ) { aggregatedFieldsQueryBuilder.add( - createQuery( fieldContext, conversionContext ), - BooleanClause.Occur.SHOULD + fieldContext.getFieldCustomizer().setWrappedQuery( + createQuery( fieldContext, conversionContext ) ) + .createQuery(), + BooleanClause.Occur.SHOULD ); } BooleanQuery aggregatedFieldsQuery = aggregatedFieldsQueryBuilder.build(); @@ -82,7 +89,6 @@ public Query createQuery() { } private Query createQuery(FieldContext fieldContext, ConversionContext conversionContext) { - final Query perFieldQuery; final DocumentBuilderIndexedEntity documentBuilder = queryContext.getDocumentBuilder(); final boolean applyTokenization; @@ -107,19 +113,17 @@ private Query createQuery(FieldContext fieldContext, ConversionContext conversio final String searchTerm = buildSearchTerm( fieldContext, documentBuilder, conversionContext ); if ( !applyTokenization || BridgeAdaptorUtils.unwrapAdaptorOnly( fieldBridge, IgnoreAnalyzerBridge.class ) != null ) { - perFieldQuery = createTermQuery( fieldContext, searchTerm ); + return createTermQuery( fieldContext, searchTerm ); + } + + // we need to build differentiated queries depending on if the search terms should be analyzed + // locally or not + if ( queryContext.getQueryAnalyzerReference().is( RemoteAnalyzerReference.class ) ) { + return createRemoteQuery( fieldContext, searchTerm ); } else { - // we need to build differentiated queries depending of if the search terms should be analyzed - // locally or not - if ( queryContext.getQueryAnalyzerReference().is( RemoteAnalyzerReference.class ) ) { - perFieldQuery = createRemoteQuery( fieldContext, searchTerm ); - } - else { - perFieldQuery = createLuceneQuery( fieldContext, searchTerm ); - } + return createLuceneQuery( fieldContext, searchTerm ); } - return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery(); } private void validateNullValueIsSearchable(FieldContext fieldContext) { diff --git a/engine/src/test/java/org/hibernate/search/test/dsl/BoostDSLTest.java b/engine/src/test/java/org/hibernate/search/test/dsl/BoostDSLTest.java new file mode 100644 index 00000000000..fc16da3547f --- /dev/null +++ b/engine/src/test/java/org/hibernate/search/test/dsl/BoostDSLTest.java @@ -0,0 +1,112 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.test.dsl; + +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; +import org.hibernate.search.query.dsl.QueryBuilder; +import org.hibernate.search.testsupport.TestForIssue; +import org.hibernate.search.testsupport.junit.SearchFactoryHolder; +import org.hibernate.search.testsupport.junit.SearchITHelper; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +/** + * @author Guillaume Smet + */ +@TestForIssue(jiraKey = "HSEARCH-2983") +public class BoostDSLTest { + + @Rule + public final SearchFactoryHolder sfHolder = new SearchFactoryHolder( Coffee.class, CoffeeBrand.class ); + + private final SearchITHelper helper = new SearchITHelper( sfHolder ); + + @Before + public void setUp() throws Exception { + indexTestData(); + } + + @Test + public void testBoostOnTermQuery() { + QueryBuilder qb = helper.queryBuilder( Coffee.class ); + + Query query = qb.bool() + .should( qb.keyword().onField( "name" ).boostedTo( 40f ).matching( "Kazaar" ).createQuery() ) + .should( qb.keyword().onField( "summary" ).boostedTo( 1f ).matching( "VELVETY" ).createQuery() ) + .createQuery(); + + helper.assertThat( query ).from( Coffee.class ) + .sort( new Sort( SortField.FIELD_SCORE ) ) + .matchesExactlyIds( "Kazaar", "Dharkan" ); + + query = qb.bool() + .should( qb.keyword().onField( "name" ).boostedTo( 1f ).matching( "Kazaar" ).createQuery() ) + .should( qb.keyword().onField( "summary" ).boostedTo( 40f ).matching( "VELVETY" ).createQuery() ) + .createQuery(); + + helper.assertThat( query ).from( Coffee.class ) + .sort( new Sort( SortField.FIELD_SCORE ) ) + .matchesExactlyIds( "Dharkan", "Kazaar" ); + } + + @Test + public void testBoostOnNumericQuery() { + QueryBuilder qb = helper.queryBuilder( Coffee.class ); + + Query query = qb.bool() + .should( qb.keyword().onField( "name" ).boostedTo( 40f ).matching( "Kazaar" ).createQuery() ) + .should( qb.keyword().onField( "intensity" ).boostedTo( 1f ).matching( 11 ).createQuery() ) + .createQuery(); + + helper.assertThat( query ).from( Coffee.class ) + .sort( new Sort( SortField.FIELD_SCORE ) ) + .matchesExactlyIds( "Kazaar", "Dharkan" ); + + query = qb.bool() + .should( qb.keyword().onField( "name" ).boostedTo( 1f ).matching( "Kazaar" ).createQuery() ) + .should( qb.keyword().onField( "intensity" ).boostedTo( 40f ).matching( 11 ).createQuery() ) + .createQuery(); + + helper.assertThat( query ).from( Coffee.class ) + .sort( new Sort( SortField.FIELD_SCORE ) ) + .matchesExactlyIds( "Dharkan", "Kazaar" ); + } + + private void indexTestData() { + createCoffee( + "Kazaar", + "EXCEPTIONALLY INTENSE AND SYRUPY", + "A daring blend of two Robustas from Brazil and Guatemala, specially prepared for Nespresso, and a separately roasted Arabica from South America, Kazaar is a coffee of exceptional intensity. Its powerful bitterness and notes of pepper are balanced by a full and creamy texture.", + 12 + ); + createCoffee( + "Dharkan", + "LONG ROASTED AND VELVETY", + "This blend of Arabicas from Latin America and Asia fully unveils its character thanks to the technique of long roasting at a low temperature. Its powerful personality reveals intense roasted notes together with hints of bitter cocoa powder and toasted cereals that express themselves in a silky and velvety txture.", + 11 + ); + createCoffee( + "Ristretto", + "POWERFUL AND CONTRASTING", + "A blend of South American and East African Arabicas, with a touch of Robusta, roasted separately to create the subtle fruity note of this full-bodied, intense espresso.", + 10 + ); + } + + private void createCoffee(String name, String summary, String description, int intensity) { + Coffee coffee = new Coffee(); + coffee.setId( name ); + coffee.setName( name ); + coffee.setSummary( summary ); + coffee.setDescription( description ); + coffee.setIntensity( intensity ); + helper.add( coffee ); + } +} diff --git a/engine/src/test/java/org/hibernate/search/test/dsl/Coffee.java b/engine/src/test/java/org/hibernate/search/test/dsl/Coffee.java index e7b3df556d4..0fb9082914a 100644 --- a/engine/src/test/java/org/hibernate/search/test/dsl/Coffee.java +++ b/engine/src/test/java/org/hibernate/search/test/dsl/Coffee.java @@ -48,6 +48,7 @@ public void setId(String id) { public void setDescription(String description) { this.description = description; } private String description; + @Field public int getIntensity() { return intensity; } public void setIntensity(int intensity) { this.intensity = intensity; } private int intensity; diff --git a/engine/src/test/java/org/hibernate/search/test/dsl/SimpleQueryStringDSLTest.java b/engine/src/test/java/org/hibernate/search/test/dsl/SimpleQueryStringDSLTest.java index 9309dba40ec..0b5720d512c 100644 --- a/engine/src/test/java/org/hibernate/search/test/dsl/SimpleQueryStringDSLTest.java +++ b/engine/src/test/java/org/hibernate/search/test/dsl/SimpleQueryStringDSLTest.java @@ -406,10 +406,10 @@ private void indexTestData() { ); } - private void createCoffee(String title, String summary, String description, int intensity, CoffeeBrand brand) { + private void createCoffee(String name, String summary, String description, int intensity, CoffeeBrand brand) { Coffee coffee = new Coffee(); - coffee.setId( title ); - coffee.setName( title ); + coffee.setId( name ); + coffee.setName( name ); coffee.setSummary( summary ); coffee.setDescription( description ); coffee.setIntensity( intensity );