diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index cab778eefdd..d4ac6374bd2 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -186,6 +186,8 @@ New Features (ehatcher) * SOLR-1974: Add LimitTokenCountFilterFactory. (koji) + +* SOLR-1966: QueryElevationComponent can now return just the included results in the elevation file (gsingers, yonik) Optimizations ---------------------- diff --git a/solr/src/common/org/apache/solr/common/params/QueryElevationParams.java b/solr/src/common/org/apache/solr/common/params/QueryElevationParams.java new file mode 100644 index 00000000000..517eec4d7b8 --- /dev/null +++ b/solr/src/common/org/apache/solr/common/params/QueryElevationParams.java @@ -0,0 +1,13 @@ +package org.apache.solr.common.params; + + +/** + * Parameters used with the QueryElevationComponent + * + **/ +public interface QueryElevationParams { + + String ENABLE = "enableElevation"; + String EXCLUSIVE = "exclusive"; + String FORCE_ELEVATION = "forceElevation"; +} diff --git a/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java b/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java index 91881a22834..1d004dc0634 100644 --- a/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java @@ -29,6 +29,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.WeakHashMap; + +import org.apache.solr.common.params.QueryElevationParams; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,22 +79,20 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore // Constants used in solrconfig.xml static final String FIELD_TYPE = "queryFieldType"; static final String CONFIG_FILE = "config-file"; - static final String FORCE_ELEVATION = "forceElevation"; static final String EXCLUDE = "exclude"; // Runtime param -- should be in common? - static final String ENABLE = "enableElevation"; - + private SolrParams initArgs = null; private Analyzer analyzer = null; private String idField = null; + boolean forceElevation = false; - // For each IndexReader, keep a query->elevation map // When the configuration is loaded from the data directory. // The key is null if loaded from the config directory, and // is never re-loaded. - final Map> elevationCache = + final Map> elevationCache = new WeakHashMap>(); class ElevationObj { @@ -160,7 +160,7 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore } idField = StringHelper.intern(sf.getName()); - forceElevation = initArgs.getBool( FORCE_ELEVATION, forceElevation ); + forceElevation = initArgs.getBool( QueryElevationParams.FORCE_ELEVATION, forceElevation ); try { synchronized( elevationCache ) { elevationCache.clear(); @@ -316,12 +316,13 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore SolrQueryRequest req = rb.req; SolrParams params = req.getParams(); // A runtime param can skip - if( !params.getBool( ENABLE, true ) ) { + if( !params.getBool( QueryElevationParams.ENABLE, true ) ) { return; } + boolean exclusive = params.getBool(QueryElevationParams.EXCLUSIVE, false); // A runtime parameter can alter the config value for forceElevation - boolean force = params.getBool( FORCE_ELEVATION, forceElevation ); + boolean force = params.getBool( QueryElevationParams.FORCE_ELEVATION, forceElevation ); Query query = rb.getQuery(); String qstr = rb.getQueryString(); @@ -342,15 +343,21 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore if( booster != null ) { // Change the query to insert forced documents - BooleanQuery newq = new BooleanQuery( true ); - newq.add( query, BooleanClause.Occur.SHOULD ); - newq.add( booster.include, BooleanClause.Occur.SHOULD ); - if( booster.exclude != null ) { - for( BooleanClause bq : booster.exclude ) { - newq.add( bq ); + if (exclusive == true){ + //we only want these results + rb.setQuery(booster.include); + } else { + BooleanQuery newq = new BooleanQuery( true ); + newq.add( query, BooleanClause.Occur.SHOULD ); + newq.add( booster.include, BooleanClause.Occur.SHOULD ); + if( booster.exclude != null ) { + for( BooleanClause bq : booster.exclude ) { + newq.add( bq ); + } } + rb.setQuery( newq ); } - rb.setQuery( newq ); + // if the sort is 'score desc' use a custom sorting method to // insert documents in their proper place diff --git a/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java b/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java index f74af30c2f4..516581da446 100644 --- a/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java +++ b/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java @@ -29,6 +29,7 @@ import org.apache.lucene.util.BytesRef; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.MapSolrParams; +import org.apache.solr.common.params.QueryElevationParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.SolrCore; import org.apache.solr.handler.component.QueryElevationComponent.ElevationObj; @@ -198,10 +199,19 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 { ,"//result/doc[3]/str[@name='id'][.='b']" ,"//result/doc[4]/str[@name='id'][.='c']" ); - + + //Test exclusive (not to be confused with exclusion) + args.put(QueryElevationParams.EXCLUSIVE, "true"); + booster.setTopQueryResults( reader, query, new String[] { "x" }, new String[] {} ); + assertQ( null, req + ,"//*[@numFound='1']" + ,"//result/doc[1]/str[@name='id'][.='x']" + ); + // Test exclusion booster.elevationCache.clear(); args.remove( CommonParams.SORT ); + args.remove( QueryElevationParams.EXCLUSIVE); booster.setTopQueryResults( reader, query, new String[] { "x" }, new String[] { "a" } ); assertQ( null, req ,"//*[@numFound='3']" @@ -209,6 +219,7 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 { ,"//result/doc[2]/str[@name='id'][.='b']" ,"//result/doc[3]/str[@name='id'][.='c']" ); + } // write a test file to boost some docs