SOLR-5858, SOLR-4812: Allow queryparser to be defined for highlight query, and edismax and dismax to be used for this purpose

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1578800 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Alan Woodward 2014-03-18 09:46:48 +00:00
parent c5263086b4
commit 7e8e19b7c0
6 changed files with 66 additions and 21 deletions

View File

@ -101,6 +101,9 @@ System Requirements
* LUCENE-4747, LUCENE-5514: Move to Java 7 as minimum Java version. * LUCENE-4747, LUCENE-5514: Move to Java 7 as minimum Java version.
(Robert Muir, Uwe Schindler) (Robert Muir, Uwe Schindler)
* SOLR-5858: Add a hl.qparser parameter to allow you to define a queryparser
for hl.q highlight queries. If no queryparser is defined, Solr will use
the overall query's defType. (Alan Woodward)
New Features New Features
---------------------- ----------------------
@ -177,6 +180,9 @@ Bug Fixes
* SOLR-5550: shards.info is not returned by a short circuited distributed query. * SOLR-5550: shards.info is not returned by a short circuited distributed query.
(Timothy Potter, shalin) (Timothy Potter, shalin)
* SOLR-5858, SOLR-4812: edismax and dismax query parsers can be used for parsing
highlight queries. (Alan Woodward, Tien Nguyen Manh)
Optimizations Optimizations
---------------------- ----------------------
* SOLR-1880: Distributed Search skips GET_FIELDS stage if EXECUTE_QUERY * SOLR-1880: Distributed Search skips GET_FIELDS stage if EXECUTE_QUERY

View File

@ -17,6 +17,7 @@
package org.apache.solr.handler.component; package org.apache.solr.handler.component;
import com.google.common.base.Objects;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.CommonParams;
@ -24,22 +25,24 @@ import org.apache.solr.common.params.HighlightParams;
import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrCore;
import org.apache.solr.highlight.DefaultSolrHighlighter;
import org.apache.solr.highlight.PostingsSolrHighlighter; import org.apache.solr.highlight.PostingsSolrHighlighter;
import org.apache.solr.highlight.SolrHighlighter; import org.apache.solr.highlight.SolrHighlighter;
import org.apache.solr.highlight.DefaultSolrHighlighter;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.QParser; import org.apache.solr.search.QParser;
import org.apache.solr.search.QParserPlugin;
import org.apache.solr.search.QueryParsing;
import org.apache.solr.search.SyntaxError; import org.apache.solr.search.SyntaxError;
import org.apache.solr.util.SolrPluginUtils; import org.apache.solr.util.SolrPluginUtils;
import org.apache.solr.util.plugin.PluginInfoInitialized; import org.apache.solr.util.plugin.PluginInfoInitialized;
import org.apache.solr.util.plugin.SolrCoreAware; import org.apache.solr.util.plugin.SolrCoreAware;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrCore;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.Map;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* TODO! * TODO!
@ -69,9 +72,11 @@ public class HighlightComponent extends SearchComponent implements PluginInfoIni
rb.doHighlights = highlighter.isHighlightingEnabled(params); rb.doHighlights = highlighter.isHighlightingEnabled(params);
if(rb.doHighlights){ if(rb.doHighlights){
String hlq = params.get(HighlightParams.Q); String hlq = params.get(HighlightParams.Q);
String hlparser = Objects.firstNonNull(params.get(HighlightParams.QPARSER),
params.get(QueryParsing.DEFTYPE, QParserPlugin.DEFAULT_QTYPE));
if(hlq != null){ if(hlq != null){
try { try {
QParser parser = QParser.getParser(hlq, null, rb.req); QParser parser = QParser.getParser(hlq, hlparser, rb.req);
rb.setHighlightQuery(parser.getHighlightQuery()); rb.setHighlightQuery(parser.getHighlightQuery());
} catch (SyntaxError e) { } catch (SyntaxError e) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e); throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);

View File

@ -91,11 +91,13 @@ public class DisMaxQParser extends QParser {
protected String[] boostParams; protected String[] boostParams;
protected List<Query> boostQueries; protected List<Query> boostQueries;
protected Query altUserQuery; protected Query altUserQuery;
protected QParser altQParser;
private boolean parsed = false;
@Override @Override
public Query parse() throws SyntaxError { public Query parse() throws SyntaxError {
parsed = true;
SolrParams solrParams = SolrParams.wrapDefaults(localParams, params); SolrParams solrParams = SolrParams.wrapDefaults(localParams, params);
queryFields = parseQueryFields(req.getSchema(), solrParams); queryFields = parseQueryFields(req.getSchema(), solrParams);
@ -263,6 +265,8 @@ public class DisMaxQParser extends QParser {
@Override @Override
public Query getHighlightQuery() throws SyntaxError { public Query getHighlightQuery() throws SyntaxError {
if (!parsed)
parse();
return parsedUserQuery == null ? altUserQuery : parsedUserQuery; return parsedUserQuery == null ? altUserQuery : parsedUserQuery;
} }

View File

@ -17,16 +17,6 @@
package org.apache.solr.search; package org.apache.solr.search;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.StopFilterFactory; import org.apache.lucene.analysis.core.StopFilterFactory;
import org.apache.lucene.analysis.util.TokenFilterFactory; import org.apache.lucene.analysis.util.TokenFilterFactory;
@ -52,6 +42,16 @@ import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.FieldType; import org.apache.solr.schema.FieldType;
import org.apache.solr.util.SolrPluginUtils; import org.apache.solr.util.SolrPluginUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* Query parser that generates DisjunctionMaxQueries based on user configuration. * Query parser that generates DisjunctionMaxQueries based on user configuration.
* See Wiki page http://wiki.apache.org/solr/ExtendedDisMax * See Wiki page http://wiki.apache.org/solr/ExtendedDisMax
@ -100,6 +100,7 @@ public class ExtendedDismaxQParser extends QParser {
private Query parsedUserQuery; private Query parsedUserQuery;
private Query altUserQuery; private Query altUserQuery;
private List<Query> boostQueries; private List<Query> boostQueries;
private boolean parsed = false;
public ExtendedDismaxQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) { public ExtendedDismaxQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
@ -109,6 +110,8 @@ public class ExtendedDismaxQParser extends QParser {
@Override @Override
public Query parse() throws SyntaxError { public Query parse() throws SyntaxError {
parsed = true;
/* the main query we will execute. we disable the coord because /* the main query we will execute. we disable the coord because
* this query is an artificial construct * this query is an artificial construct
@ -565,6 +568,8 @@ public class ExtendedDismaxQParser extends QParser {
@Override @Override
public Query getHighlightQuery() throws SyntaxError { public Query getHighlightQuery() throws SyntaxError {
if (!parsed)
parse();
return parsedUserQuery == null ? altUserQuery : parsedUserQuery; return parsedUserQuery == null ? altUserQuery : parsedUserQuery;
} }

View File

@ -21,11 +21,10 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer; import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.handler.component.HighlightComponent;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.util.*;
import org.apache.solr.common.params.HighlightParams; import org.apache.solr.common.params.HighlightParams;
import org.apache.solr.handler.component.HighlightComponent;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.util.TestHarness;
import org.junit.After; import org.junit.After;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -848,7 +847,7 @@ public class HighlighterTest extends SolrTestCaseJ4 {
} }
public void testHlQParameter() { public void testHlQParameter() {
assertU(adoc("title", "Apache Software Foundation", "id", "1")); assertU(adoc("title", "Apache Software Foundation", "t_text", "apache software foundation", "id", "1"));
assertU(commit()); assertU(commit());
assertQ("hl.q parameter overrides q parameter", assertQ("hl.q parameter overrides q parameter",
req("q", "title:Apache", "hl", "true", "hl.fl", "title", "hl.q", "title:Software"), req("q", "title:Apache", "hl", "true", "hl.fl", "title", "hl.q", "title:Software"),
@ -858,6 +857,31 @@ public class HighlighterTest extends SolrTestCaseJ4 {
req("q", "title:Apache", "hl", "true", "hl.fl", "title", "hl.q", "{!v=$qq}", "qq", "title:Foundation"), req("q", "title:Apache", "hl", "true", "hl.fl", "title", "hl.q", "{!v=$qq}", "qq", "title:Foundation"),
"//lst[@name='highlighting']/lst[@name='1']" + "//lst[@name='highlighting']/lst[@name='1']" +
"/arr[@name='title']/str='Apache Software <em>Foundation</em>'"); "/arr[@name='title']/str='Apache Software <em>Foundation</em>'");
assertQ("hl.q parameter uses localparam parser definition correctly",
req("q", "Apache", "defType", "edismax", "qf", "title t_text", "hl", "true", "hl.fl", "title", "hl.q", "{!edismax}Software"),
"//lst[@name='highlighting']/lst[@name='1']" +
"/arr[@name='title']/str='Apache <em>Software</em> Foundation'");
assertQ("hl.q parameter uses defType correctly",
req("q", "Apache", "defType", "edismax", "qf", "title t_text", "hl", "true", "hl.fl", "title", "hl.q", "Software"),
"//lst[@name='highlighting']/lst[@name='1']" +
"/arr[@name='title']/str='Apache <em>Software</em> Foundation'");
assertQ("hl.q parameter uses hl.qparser param correctly",
req("q", "t_text:Apache", "qf", "title t_text", "hl", "true", "hl.fl", "title", "hl.q", "Software", "hl.qparser", "edismax"),
"//lst[@name='highlighting']/lst[@name='1']" +
"/arr[@name='title']/str='Apache <em>Software</em> Foundation'");
}
public void testHlQEdismaxParameter() {
assertU(adoc("title", "Apache Software Foundation", "id", "1"));
assertU(commit());
assertQ("hl.q parameter overrides q parameter",
req("q", "title:Apache", "hl", "true", "hl.fl", "title", "hl.q", "{!edismax qf=title v=Software}"),
"//lst[@name='highlighting']/lst[@name='1']" +
"/arr[@name='title']/str='Apache <em>Software</em> Foundation'");
assertQ("hl.q parameter overrides q parameter",
req("q", "title:Apache", "hl", "true", "hl.fl", "title", "hl.q", "{!v=$qq}", "qq", "title:Foundation"),
"//lst[@name='highlighting']/lst[@name='1']" +
"/arr[@name='title']/str='Apache Software <em>Foundation</em>'");
} }
@Test @Test

View File

@ -24,6 +24,7 @@ package org.apache.solr.common.params;
public interface HighlightParams { public interface HighlightParams {
public static final String HIGHLIGHT = "hl"; public static final String HIGHLIGHT = "hl";
public static final String Q = HIGHLIGHT+".q"; public static final String Q = HIGHLIGHT+".q";
public static final String QPARSER = HIGHLIGHT+".qparser";
public static final String FIELDS = HIGHLIGHT+".fl"; public static final String FIELDS = HIGHLIGHT+".fl";
public static final String SNIPPETS = HIGHLIGHT+".snippets"; public static final String SNIPPETS = HIGHLIGHT+".snippets";
public static final String FRAGSIZE = HIGHLIGHT+".fragsize"; public static final String FRAGSIZE = HIGHLIGHT+".fragsize";