parent
4b69846ba2
commit
2f4b759df7
|
@ -129,7 +129,7 @@ public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
||||||
fields.add(fieldMapper.names().indexName());
|
fields.add(fieldMapper.names().indexName());
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
||||||
fields.add(fieldMapper.names().name());
|
fields.add(fieldMapper.names().indexName());
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
|
||||||
fields.add(fieldMapper.names().indexName());
|
fields.add(fieldMapper.names().indexName());
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,20 @@ public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> simpleMatchToFullName(String pattern) {
|
||||||
|
Set<String> fields = Sets.newHashSet();
|
||||||
|
for (FieldMapper fieldMapper : fieldMappers) {
|
||||||
|
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
||||||
|
fields.add(fieldMapper.names().fullName());
|
||||||
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
||||||
|
fields.add(fieldMapper.names().fullName());
|
||||||
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
|
||||||
|
fields.add(fieldMapper.names().fullName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}, and last
|
* Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}, and last
|
||||||
* by {@link #name(String)}.
|
* by {@link #name(String)}.
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.io.FastStringReader;
|
import org.elasticsearch.common.io.FastStringReader;
|
||||||
import org.elasticsearch.common.lucene.search.vectorhighlight.SimpleBoundaryScanner2;
|
import org.elasticsearch.common.lucene.search.vectorhighlight.SimpleBoundaryScanner2;
|
||||||
|
import org.elasticsearch.common.regex.Regex;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.text.StringText;
|
import org.elasticsearch.common.text.StringText;
|
||||||
import org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor;
|
import org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor;
|
||||||
|
@ -109,9 +110,19 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
|
||||||
} else {
|
} else {
|
||||||
encoder = Encoders.DEFAULT;
|
encoder = Encoders.DEFAULT;
|
||||||
}
|
}
|
||||||
FieldMapper mapper = documentMapper.mappers().smartNameFieldMapper(field.field());
|
|
||||||
|
Set<String> fieldNamesToHighlight;
|
||||||
|
if (Regex.isSimpleMatchPattern(field.field())) {
|
||||||
|
fieldNamesToHighlight = documentMapper.mappers().simpleMatchToFullName(field.field());
|
||||||
|
} else {
|
||||||
|
fieldNamesToHighlight = ImmutableSet.of(field.field());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String fieldName : fieldNamesToHighlight) {
|
||||||
|
|
||||||
|
FieldMapper mapper = documentMapper.mappers().smartNameFieldMapper(fieldName);
|
||||||
if (mapper == null) {
|
if (mapper == null) {
|
||||||
MapperService.SmartNameFieldMappers fullMapper = context.mapperService().smartName(field.field());
|
MapperService.SmartNameFieldMappers fullMapper = context.mapperService().smartName(fieldName);
|
||||||
if (fullMapper == null || !fullMapper.hasDocMapper()) {
|
if (fullMapper == null || !fullMapper.hasDocMapper()) {
|
||||||
//Save skipping missing fields
|
//Save skipping missing fields
|
||||||
continue;
|
continue;
|
||||||
|
@ -131,13 +142,13 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
|
||||||
useFastVectorHighlighter = mapper.fieldType().storeTermVectors() && mapper.fieldType().storeTermVectorOffsets() && mapper.fieldType().storeTermVectorPositions();
|
useFastVectorHighlighter = mapper.fieldType().storeTermVectors() && mapper.fieldType().storeTermVectorOffsets() && mapper.fieldType().storeTermVectorPositions();
|
||||||
} else if (field.highlighterType().equals("fast-vector-highlighter") || field.highlighterType().equals("fvh")) {
|
} else if (field.highlighterType().equals("fast-vector-highlighter") || field.highlighterType().equals("fvh")) {
|
||||||
if (!(mapper.fieldType().storeTermVectors() && mapper.fieldType().storeTermVectorOffsets() && mapper.fieldType().storeTermVectorPositions())) {
|
if (!(mapper.fieldType().storeTermVectors() && mapper.fieldType().storeTermVectorOffsets() && mapper.fieldType().storeTermVectorPositions())) {
|
||||||
throw new ElasticSearchIllegalArgumentException("the field [" + field.field() + "] should be indexed with term vector with position offsets to be used with fast vector highlighter");
|
throw new ElasticSearchIllegalArgumentException("the field [" + fieldName + "] should be indexed with term vector with position offsets to be used with fast vector highlighter");
|
||||||
}
|
}
|
||||||
useFastVectorHighlighter = true;
|
useFastVectorHighlighter = true;
|
||||||
} else if (field.highlighterType().equals("highlighter") || field.highlighterType().equals("plain")) {
|
} else if (field.highlighterType().equals("highlighter") || field.highlighterType().equals("plain")) {
|
||||||
useFastVectorHighlighter = false;
|
useFastVectorHighlighter = false;
|
||||||
} else {
|
} else {
|
||||||
throw new ElasticSearchIllegalArgumentException("unknown highlighter type [" + field.highlighterType() + "] for the field [" + field.field() + "]");
|
throw new ElasticSearchIllegalArgumentException("unknown highlighter type [" + field.highlighterType() + "] for the field [" + fieldName + "]");
|
||||||
}
|
}
|
||||||
if (!useFastVectorHighlighter) {
|
if (!useFastVectorHighlighter) {
|
||||||
MapperHighlightEntry entry = cache.mappers.get(mapper);
|
MapperHighlightEntry entry = cache.mappers.get(mapper);
|
||||||
|
@ -158,7 +169,7 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
|
||||||
} else if ("span".equals(field.fragmenter())) {
|
} else if ("span".equals(field.fragmenter())) {
|
||||||
fragmenter = new SimpleSpanFragmenter(queryScorer, field.fragmentCharSize());
|
fragmenter = new SimpleSpanFragmenter(queryScorer, field.fragmentCharSize());
|
||||||
} else {
|
} else {
|
||||||
throw new ElasticSearchIllegalArgumentException("unknown fragmenter option [" + field.fragmenter() + "] for the field [" + field.field() + "]");
|
throw new ElasticSearchIllegalArgumentException("unknown fragmenter option [" + field.fragmenter() + "] for the field [" + fieldName + "]");
|
||||||
}
|
}
|
||||||
Formatter formatter = new SimpleHTMLFormatter(field.preTags()[0], field.postTags()[0]);
|
Formatter formatter = new SimpleHTMLFormatter(field.preTags()[0], field.postTags()[0]);
|
||||||
|
|
||||||
|
@ -179,7 +190,7 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
|
||||||
hitContext.reader().document(hitContext.docId(), fieldVisitor);
|
hitContext.reader().document(hitContext.docId(), fieldVisitor);
|
||||||
textsToHighlight = fieldVisitor.fields().get(mapper.names().indexName());
|
textsToHighlight = fieldVisitor.fields().get(mapper.names().indexName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new FetchPhaseExecutionException(context, "Failed to highlight field [" + field.field() + "]", e);
|
throw new FetchPhaseExecutionException(context, "Failed to highlight field [" + fieldName + "]", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SearchLookup lookup = context.lookup();
|
SearchLookup lookup = context.lookup();
|
||||||
|
@ -204,7 +215,7 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new FetchPhaseExecutionException(context, "Failed to highlight field [" + field.field() + "]", e);
|
throw new FetchPhaseExecutionException(context, "Failed to highlight field [" + fieldName + "]", e);
|
||||||
}
|
}
|
||||||
if (field.scoreOrdered()) {
|
if (field.scoreOrdered()) {
|
||||||
Collections.sort(fragsList, new Comparator<TextFragment>() {
|
Collections.sort(fragsList, new Comparator<TextFragment>() {
|
||||||
|
@ -230,7 +241,7 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragments != null && fragments.length > 0) {
|
if (fragments != null && fragments.length > 0) {
|
||||||
HighlightField highlightField = new HighlightField(field.field(), StringText.convertFromStringArray(fragments));
|
HighlightField highlightField = new HighlightField(fieldName, StringText.convertFromStringArray(fragments));
|
||||||
highlightFields.put(highlightField.name(), highlightField);
|
highlightFields.put(highlightField.name(), highlightField);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -311,11 +322,12 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
|
||||||
entry.fragListBuilder, entry.fragmentsBuilder, field.preTags(), field.postTags(), encoder);
|
entry.fragListBuilder, entry.fragmentsBuilder, field.preTags(), field.postTags(), encoder);
|
||||||
|
|
||||||
if (fragments != null && fragments.length > 0) {
|
if (fragments != null && fragments.length > 0) {
|
||||||
HighlightField highlightField = new HighlightField(field.field(), StringText.convertFromStringArray(fragments));
|
HighlightField highlightField = new HighlightField(fieldName, StringText.convertFromStringArray(fragments));
|
||||||
highlightFields.put(highlightField.name(), highlightField);
|
highlightFields.put(highlightField.name(), highlightField);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new FetchPhaseExecutionException(context, "Failed to highlight field [" + field.field() + "]", e);
|
throw new FetchPhaseExecutionException(context, "Failed to highlight field [" + fieldName + "]", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,30 @@ public class HighlighterSearchTests extends AbstractNodesTests {
|
||||||
assertThat(search.hits().hits()[0].highlightFields().get("titleTV").fragments()[1].string(), equalTo("<em>highlight</em> other text"));
|
assertThat(search.hits().hits()[0].highlightFields().get("titleTV").fragments()[1].string(), equalTo("<em>highlight</em> other text"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHighlightingOnWildcardFields() throws Exception {
|
||||||
|
client.admin().indices().prepareDelete().execute().actionGet();
|
||||||
|
client.admin().indices().prepareCreate("test").execute().actionGet();
|
||||||
|
client.admin().cluster().prepareHealth("test").setWaitForGreenStatus().execute().actionGet();
|
||||||
|
|
||||||
|
client.prepareIndex("test", "type1")
|
||||||
|
.setSource("field1", "this is a test", "field2", "this is another test")
|
||||||
|
.setRefresh(true).execute().actionGet();
|
||||||
|
|
||||||
|
logger.info("--> highlighting and searching on field*");
|
||||||
|
SearchSourceBuilder source = searchSource()
|
||||||
|
.query(termQuery("field1", "test"))
|
||||||
|
.from(0).size(60).explain(true)
|
||||||
|
.highlight(highlight().field("field*").order("score").preTags("<xxx>").postTags("</xxx>"));
|
||||||
|
|
||||||
|
SearchResponse searchResponse = client.search(searchRequest("test").source(source).searchType(QUERY_THEN_FETCH).scroll(timeValueMinutes(10))).actionGet();
|
||||||
|
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
|
||||||
|
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
|
||||||
|
|
||||||
|
assertThat(searchResponse.hits().getAt(0).highlightFields().get("field1").fragments()[0].string(), equalTo("this is a <xxx>test</xxx>"));
|
||||||
|
assertThat(searchResponse.hits().getAt(0).highlightFields().get("field2").fragments()[0].string(), equalTo("this is another <xxx>test</xxx>"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPlainHighlighter() throws Exception {
|
public void testPlainHighlighter() throws Exception {
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue