mirror of
https://github.com/apache/lucene.git
synced 2025-02-08 19:15:06 +00:00
SOLR-6281: Made PostingsSolrHighlighter more configurable
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1614702 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3f4b2b472f
commit
0ffce18e13
@ -314,6 +314,8 @@ Other Changes
|
|||||||
|
|
||||||
* SOLR-6290: Harden and speed up CollectionsAPIAsyncDistributedZkTest. (Mark Miller, shalin)
|
* SOLR-6290: Harden and speed up CollectionsAPIAsyncDistributedZkTest. (Mark Miller, shalin)
|
||||||
|
|
||||||
|
* SOLR-6281: Made PostingsSolrHighlighter more configurable via subclass extension. (David Smiley)
|
||||||
|
|
||||||
================== 4.9.0 ==================
|
================== 4.9.0 ==================
|
||||||
|
|
||||||
Versions of Major Components
|
Versions of Major Components
|
||||||
|
@ -17,13 +17,6 @@ package org.apache.solr.highlight;
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.BreakIterator;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.index.StoredDocument;
|
import org.apache.lucene.index.StoredDocument;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
@ -47,6 +40,13 @@ import org.apache.solr.search.DocList;
|
|||||||
import org.apache.solr.search.SolrIndexSearcher;
|
import org.apache.solr.search.SolrIndexSearcher;
|
||||||
import org.apache.solr.util.plugin.PluginInfoInitialized;
|
import org.apache.solr.util.plugin.PluginInfoInitialized;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.BreakIterator;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Highlighter impl that uses {@link PostingsHighlighter}
|
* Highlighter impl that uses {@link PostingsHighlighter}
|
||||||
* <p>
|
* <p>
|
||||||
@ -119,86 +119,32 @@ public class PostingsSolrHighlighter extends SolrHighlighter implements PluginIn
|
|||||||
final SolrParams params = req.getParams();
|
final SolrParams params = req.getParams();
|
||||||
|
|
||||||
// if highlighting isnt enabled, then why call doHighlighting?
|
// if highlighting isnt enabled, then why call doHighlighting?
|
||||||
if (isHighlightingEnabled(params)) {
|
if (!isHighlightingEnabled(params))
|
||||||
SolrIndexSearcher searcher = req.getSearcher();
|
|
||||||
int[] docIDs = toDocIDs(docs);
|
|
||||||
|
|
||||||
// fetch the unique keys
|
|
||||||
String[] keys = getUniqueKeys(searcher, docIDs);
|
|
||||||
|
|
||||||
// query-time parameters
|
|
||||||
int maxLength = params.getInt(HighlightParams.MAX_CHARS, PostingsHighlighter.DEFAULT_MAX_LENGTH);
|
|
||||||
String[] fieldNames = getHighlightFields(query, req, defaultFields);
|
|
||||||
|
|
||||||
int maxPassages[] = new int[fieldNames.length];
|
|
||||||
for (int i = 0; i < fieldNames.length; i++) {
|
|
||||||
maxPassages[i] = params.getFieldInt(fieldNames[i], HighlightParams.SNIPPETS, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
final IndexSchema schema = req.getSchema();
|
|
||||||
|
|
||||||
PostingsHighlighter highlighter = new PostingsHighlighter(maxLength) {
|
|
||||||
@Override
|
|
||||||
protected Passage[] getEmptyHighlight(String fieldName, BreakIterator bi, int maxPassages) {
|
|
||||||
boolean defaultSummary = params.getFieldBool(fieldName, HighlightParams.DEFAULT_SUMMARY, true);
|
|
||||||
if (defaultSummary) {
|
|
||||||
return super.getEmptyHighlight(fieldName, bi, maxPassages);
|
|
||||||
} else {
|
|
||||||
return new Passage[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected PassageFormatter getFormatter(String fieldName) {
|
|
||||||
String preTag = params.getFieldParam(fieldName, HighlightParams.TAG_PRE, "<em>");
|
|
||||||
String postTag = params.getFieldParam(fieldName, HighlightParams.TAG_POST, "</em>");
|
|
||||||
String ellipsis = params.getFieldParam(fieldName, HighlightParams.TAG_ELLIPSIS, "... ");
|
|
||||||
String encoder = params.getFieldParam(fieldName, HighlightParams.ENCODER, "simple");
|
|
||||||
return new DefaultPassageFormatter(preTag, postTag, ellipsis, "html".equals(encoder));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected PassageScorer getScorer(String fieldName) {
|
|
||||||
float k1 = params.getFieldFloat(fieldName, HighlightParams.SCORE_K1, 1.2f);
|
|
||||||
float b = params.getFieldFloat(fieldName, HighlightParams.SCORE_B, 0.75f);
|
|
||||||
float pivot = params.getFieldFloat(fieldName, HighlightParams.SCORE_PIVOT, 87f);
|
|
||||||
return new PassageScorer(k1, b, pivot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BreakIterator getBreakIterator(String field) {
|
|
||||||
String language = params.getFieldParam(field, HighlightParams.BS_LANGUAGE);
|
|
||||||
String country = params.getFieldParam(field, HighlightParams.BS_COUNTRY);
|
|
||||||
String variant = params.getFieldParam(field, HighlightParams.BS_VARIANT);
|
|
||||||
Locale locale = parseLocale(language, country, variant);
|
|
||||||
String type = params.getFieldParam(field, HighlightParams.BS_TYPE);
|
|
||||||
return parseBreakIterator(type, locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected char getMultiValuedSeparator(String field) {
|
|
||||||
String sep = params.getFieldParam(field, HighlightParams.MULTI_VALUED_SEPARATOR, " ");
|
|
||||||
if (sep.length() != 1) {
|
|
||||||
throw new IllegalArgumentException(HighlightParams.MULTI_VALUED_SEPARATOR + " must be exactly one character.");
|
|
||||||
}
|
|
||||||
return sep.charAt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Analyzer getIndexAnalyzer(String field) {
|
|
||||||
if (params.getFieldBool(field, HighlightParams.HIGHLIGHT_MULTI_TERM, false)) {
|
|
||||||
return schema.getIndexAnalyzer();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Map<String,String[]> snippets = highlighter.highlightFields(fieldNames, query, searcher, docIDs, maxPassages);
|
|
||||||
return encodeSnippets(keys, fieldNames, snippets);
|
|
||||||
} else {
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
SolrIndexSearcher searcher = req.getSearcher();
|
||||||
|
int[] docIDs = toDocIDs(docs);
|
||||||
|
|
||||||
|
// fetch the unique keys
|
||||||
|
String[] keys = getUniqueKeys(searcher, docIDs);
|
||||||
|
|
||||||
|
// query-time parameters
|
||||||
|
String[] fieldNames = getHighlightFields(query, req, defaultFields);
|
||||||
|
|
||||||
|
int maxPassages[] = new int[fieldNames.length];
|
||||||
|
for (int i = 0; i < fieldNames.length; i++) {
|
||||||
|
maxPassages[i] = params.getFieldInt(fieldNames[i], HighlightParams.SNIPPETS, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PostingsHighlighter highlighter = getHighlighter(req);
|
||||||
|
Map<String,String[]> snippets = highlighter.highlightFields(fieldNames, query, searcher, docIDs, maxPassages);
|
||||||
|
return encodeSnippets(keys, fieldNames, snippets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates an instance of the Lucene PostingsHighlighter. Provided for subclass extension so that
|
||||||
|
* a subclass can return a subclass of {@link PostingsSolrHighlighter.SolrExtendedPostingsHighlighter}. */
|
||||||
|
protected PostingsHighlighter getHighlighter(SolrQueryRequest req) {
|
||||||
|
return new SolrExtendedPostingsHighlighter(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,6 +208,74 @@ public class PostingsSolrHighlighter extends SolrHighlighter implements PluginIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** From {@link #getHighlighter(org.apache.solr.request.SolrQueryRequest)}. */
|
||||||
|
public class SolrExtendedPostingsHighlighter extends PostingsHighlighter {
|
||||||
|
protected final SolrParams params;
|
||||||
|
protected final IndexSchema schema;
|
||||||
|
|
||||||
|
public SolrExtendedPostingsHighlighter(SolrQueryRequest req) {
|
||||||
|
super(req.getParams().getInt(HighlightParams.MAX_CHARS, PostingsHighlighter.DEFAULT_MAX_LENGTH));
|
||||||
|
this.params = req.getParams();
|
||||||
|
this.schema = req.getSchema();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Passage[] getEmptyHighlight(String fieldName, BreakIterator bi, int maxPassages) {
|
||||||
|
boolean defaultSummary = params.getFieldBool(fieldName, HighlightParams.DEFAULT_SUMMARY, true);
|
||||||
|
if (defaultSummary) {
|
||||||
|
return super.getEmptyHighlight(fieldName, bi, maxPassages);
|
||||||
|
} else {
|
||||||
|
//TODO reuse logic of DefaultSolrHighlighter.alternateField
|
||||||
|
return new Passage[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PassageFormatter getFormatter(String fieldName) {
|
||||||
|
String preTag = params.getFieldParam(fieldName, HighlightParams.TAG_PRE, "<em>");
|
||||||
|
String postTag = params.getFieldParam(fieldName, HighlightParams.TAG_POST, "</em>");
|
||||||
|
String ellipsis = params.getFieldParam(fieldName, HighlightParams.TAG_ELLIPSIS, "... ");
|
||||||
|
String encoder = params.getFieldParam(fieldName, HighlightParams.ENCODER, "simple");
|
||||||
|
return new DefaultPassageFormatter(preTag, postTag, ellipsis, "html".equals(encoder));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PassageScorer getScorer(String fieldName) {
|
||||||
|
float k1 = params.getFieldFloat(fieldName, HighlightParams.SCORE_K1, 1.2f);
|
||||||
|
float b = params.getFieldFloat(fieldName, HighlightParams.SCORE_B, 0.75f);
|
||||||
|
float pivot = params.getFieldFloat(fieldName, HighlightParams.SCORE_PIVOT, 87f);
|
||||||
|
return new PassageScorer(k1, b, pivot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BreakIterator getBreakIterator(String field) {
|
||||||
|
String language = params.getFieldParam(field, HighlightParams.BS_LANGUAGE);
|
||||||
|
String country = params.getFieldParam(field, HighlightParams.BS_COUNTRY);
|
||||||
|
String variant = params.getFieldParam(field, HighlightParams.BS_VARIANT);
|
||||||
|
Locale locale = parseLocale(language, country, variant);
|
||||||
|
String type = params.getFieldParam(field, HighlightParams.BS_TYPE);
|
||||||
|
return parseBreakIterator(type, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected char getMultiValuedSeparator(String field) {
|
||||||
|
String sep = params.getFieldParam(field, HighlightParams.MULTI_VALUED_SEPARATOR, " ");
|
||||||
|
if (sep.length() != 1) {
|
||||||
|
throw new IllegalArgumentException(HighlightParams.MULTI_VALUED_SEPARATOR + " must be exactly one character.");
|
||||||
|
}
|
||||||
|
return sep.charAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Analyzer getIndexAnalyzer(String field) {
|
||||||
|
if (params.getFieldBool(field, HighlightParams.HIGHLIGHT_MULTI_TERM, false)) {
|
||||||
|
return schema.getIndexAnalyzer();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** parse a break iterator type for the specified locale */
|
/** parse a break iterator type for the specified locale */
|
||||||
protected BreakIterator parseBreakIterator(String type, Locale locale) {
|
protected BreakIterator parseBreakIterator(String type, Locale locale) {
|
||||||
if (type == null || "SENTENCE".equals(type)) {
|
if (type == null || "SENTENCE".equals(type)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user