mirror of https://github.com/apache/lucene.git
SOLR-5127: Multiple highlight fields and wildcards are now supported e.g. hl.fl=title,text_*
(Sven-S. Porst, Daniel Debray, Simon Endele, Christine Poerschke)
This commit is contained in:
parent
e62a3ff46c
commit
f9ca49a8d5
|
@ -215,6 +215,9 @@ Bug Fixes
|
|||
|
||||
* SOLR-10472: Fixed uninversion (aka: FieldCache) bugs with the numeric PointField classes, and CurrencyField (hossman)
|
||||
|
||||
* SOLR-5127: Multiple highlight fields and wildcards are now supported e.g. hl.fl=title,text_*
|
||||
(Sven-S. Porst, Daniel Debray, Simon Endele, Christine Poerschke)
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ import org.apache.solr.search.DocList;
|
|||
import org.apache.solr.util.SolrPluginUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class SolrHighlighter
|
||||
{
|
||||
|
@ -60,27 +60,19 @@ public abstract class SolrHighlighter
|
|||
if (emptyArray(defaultFields)) {
|
||||
String defaultSearchField = request.getSchema().getDefaultSearchFieldName();
|
||||
fields = null == defaultSearchField ? new String[]{} : new String[]{defaultSearchField};
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fields = defaultFields;
|
||||
}
|
||||
}
|
||||
else if (fields.length == 1) {
|
||||
if (fields[0].contains("*")) {
|
||||
// create a Java regular expression from the wildcard string
|
||||
String fieldRegex = fields[0].replaceAll("\\*", ".*");
|
||||
Collection<String> storedHighlightFieldNames = request.getSearcher().getDocFetcher().getStoredHighlightFieldNames();
|
||||
List<String> storedFieldsToHighlight = new ArrayList<>();
|
||||
for (String storedFieldName: storedHighlightFieldNames) {
|
||||
if (storedFieldName.matches(fieldRegex)) {
|
||||
storedFieldsToHighlight.add(storedFieldName);
|
||||
}
|
||||
}
|
||||
fields = storedFieldsToHighlight.toArray(new String[storedFieldsToHighlight.size()]);
|
||||
} else {
|
||||
// if there's a single request/handler value, it may be a space/comma separated list
|
||||
fields = SolrPluginUtils.split(fields[0]);
|
||||
Set<String> expandedFields = new LinkedHashSet<String>();
|
||||
Collection<String> storedHighlightFieldNames = request.getSearcher().getDocFetcher().getStoredHighlightFieldNames();
|
||||
for (String field : fields) {
|
||||
expandWildcardsInHighlightFields(
|
||||
expandedFields,
|
||||
storedHighlightFieldNames,
|
||||
SolrPluginUtils.split(field));
|
||||
}
|
||||
fields = expandedFields.toArray(new String[]{});
|
||||
}
|
||||
|
||||
// Trim them now in case they haven't been yet. Not needed for all code-paths above but do it here.
|
||||
|
@ -94,6 +86,25 @@ public abstract class SolrHighlighter
|
|||
return (arr == null || arr.length == 0 || arr[0] == null || arr[0].trim().length() == 0);
|
||||
}
|
||||
|
||||
static private void expandWildcardsInHighlightFields (
|
||||
Set<String> expandedFields,
|
||||
Collection<String> storedHighlightFieldNames,
|
||||
String... fields) {
|
||||
for (String field : fields) {
|
||||
if (field.contains("*")) {
|
||||
// create a Java regular expression from the wildcard string
|
||||
String fieldRegex = field.replaceAll("\\*", ".*");
|
||||
for (String storedFieldName : storedHighlightFieldNames) {
|
||||
if (storedFieldName.matches(fieldRegex)) {
|
||||
expandedFields.add(storedFieldName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
expandedFields.add(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of Highlighted query fragments for each item in a list
|
||||
* of documents, or returns null if highlighting is disabled.
|
||||
|
|
|
@ -20,7 +20,9 @@ import java.io.IOException;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
|
@ -35,6 +37,7 @@ import org.apache.solr.common.params.HighlightParams;
|
|||
import org.apache.solr.handler.component.HighlightComponent;
|
||||
import org.apache.solr.handler.component.ResponseBuilder;
|
||||
import org.apache.solr.handler.component.SearchComponent;
|
||||
import org.apache.solr.request.LocalSolrQueryRequest;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.search.DocSet;
|
||||
|
@ -868,6 +871,8 @@ public class HighlighterTest extends SolrTestCaseJ4 {
|
|||
"text", "test", // static not stored
|
||||
"foo_s", "test", // dynamic stored
|
||||
"foo_sI", "test", // dynamic not stored
|
||||
"bar_s", "test", // dynamic stored
|
||||
"bar_sI", "test", // dynamic not stored
|
||||
"weight", "1.0")); // stored but not text
|
||||
assertU(commit());
|
||||
assertU(optimize());
|
||||
|
@ -898,6 +903,21 @@ public class HighlighterTest extends SolrTestCaseJ4 {
|
|||
assertEquals("Expected to highlight on field \"foo_s\"", "foo_s",
|
||||
highlightFieldNames.get(0));
|
||||
request.close();
|
||||
|
||||
// SOLR-5127
|
||||
args.put("hl.fl", (random().nextBoolean() ? "foo_*,bar_*" : "bar_*,foo_*"));
|
||||
lrf = h.getRequestFactory("standard", 0, 10, args);
|
||||
// hl.fl ordering need not be preserved in output
|
||||
final Set<String> highlightedSetExpected = new HashSet<String>();
|
||||
highlightedSetExpected.add("foo_s");
|
||||
highlightedSetExpected.add("bar_s");
|
||||
try (LocalSolrQueryRequest localRequest = lrf.makeRequest("test")) {
|
||||
highlighter = HighlightComponent.getHighlighter(h.getCore());
|
||||
final Set<String> highlightedSetActual = new HashSet<String>(
|
||||
Arrays.asList(highlighter.getHighlightFields(null,
|
||||
localRequest, new String[] {})));
|
||||
assertEquals(highlightedSetExpected, highlightedSetActual);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -99,6 +99,19 @@ public class TestPostingsSolrHighlighter extends SolrTestCaseJ4 {
|
|||
"//lst[@name='highlighting']/lst[@name='102']/arr[@name='text3']/str='crappier <em>document</em>'");
|
||||
}
|
||||
|
||||
// SOLR-5127
|
||||
public void testMultipleFieldsViaWildcard() {
|
||||
assertQ("highlighting text and text3*",
|
||||
req("q", (random().nextBoolean() ? "text:document text3:document" : "text3:document text:document"),
|
||||
"sort", "id asc", "hl", "true",
|
||||
"hl.fl", (random().nextBoolean() ? "text,text3*" : "text3*,text")),
|
||||
"count(//lst[@name='highlighting']/*)=2",
|
||||
"//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='<em>document</em> one'",
|
||||
"//lst[@name='highlighting']/lst[@name='101']/arr[@name='text3']/str='crappy <em>document</em>'",
|
||||
"//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second <em>document</em>'",
|
||||
"//lst[@name='highlighting']/lst[@name='102']/arr[@name='text3']/str='crappier <em>document</em>'");
|
||||
}
|
||||
|
||||
public void testMisconfiguredField() {
|
||||
ignoreException("was indexed without offsets");
|
||||
try {
|
||||
|
|
|
@ -179,6 +179,19 @@ public class TestUnifiedSolrHighlighter extends SolrTestCaseJ4 {
|
|||
"//lst[@name='highlighting']/lst[@name='102']/arr[@name='text3']/str='crappier <em>document</em>'");
|
||||
}
|
||||
|
||||
// SOLR-5127
|
||||
public void testMultipleFieldsViaWildcard() {
|
||||
assertQ("highlighting text and text3*",
|
||||
req("q", (random().nextBoolean() ? "text:document text3:document" : "text3:document text:document"),
|
||||
"sort", "id asc", "hl", "true",
|
||||
"hl.fl", (random().nextBoolean() ? "text,text3*" : "text3*,text")),
|
||||
"count(//lst[@name='highlighting']/*)=2",
|
||||
"//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='<em>document</em> one'",
|
||||
"//lst[@name='highlighting']/lst[@name='101']/arr[@name='text3']/str='crappy <em>document</em>'",
|
||||
"//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second <em>document</em>'",
|
||||
"//lst[@name='highlighting']/lst[@name='102']/arr[@name='text3']/str='crappier <em>document</em>'");
|
||||
}
|
||||
|
||||
public void testTags() {
|
||||
assertQ("different pre/post tags",
|
||||
req("q", "text:document", "sort", "id asc", "hl", "true", "hl.tag.pre", "[", "hl.tag.post", "]"),
|
||||
|
|
Loading…
Reference in New Issue