Don't reset TokenStreams twice when highlighting.

When using PlainHighlighter, TokenStreams are resetted both before highlighting
and at the beginning of highlighting, causing issues with analyzers that read
in reset() such as PatternAnalyzer. This commit removes the call to reset which
was performed before passing the TokenStream to the highlighter.

Close #3200
This commit is contained in:
Adrien Grand 2013-07-08 10:41:48 +02:00
parent 759a13f1de
commit c37de66fb6
2 changed files with 38 additions and 2 deletions

View File

@ -127,7 +127,6 @@ public class PlainHighlighter implements Highlighter {
String text = textToHighlight.toString(); String text = textToHighlight.toString();
Analyzer analyzer = context.mapperService().documentMapper(hitContext.hit().type()).mappers().indexAnalyzer(); Analyzer analyzer = context.mapperService().documentMapper(hitContext.hit().type()).mappers().indexAnalyzer();
TokenStream tokenStream = analyzer.tokenStream(mapper.names().indexName(), new FastStringReader(text)); TokenStream tokenStream = analyzer.tokenStream(mapper.names().indexName(), new FastStringReader(text));
tokenStream.reset();
if (!tokenStream.hasAttribute(CharTermAttribute.class) || !tokenStream.hasAttribute(OffsetAttribute.class)) { if (!tokenStream.hasAttribute(CharTermAttribute.class) || !tokenStream.hasAttribute(OffsetAttribute.class)) {
// can't perform highlighting if the stream has no terms (binary token stream) or no offsets // can't perform highlighting if the stream has no terms (binary token stream) or no offsets
continue; continue;

View File

@ -1469,7 +1469,7 @@ public class HighlighterSearchTests extends AbstractSharedClusterTest {
ensureGreen(); ensureGreen();
client().prepareIndex("test", "type1", "1") client().prepareIndex("test", "test", "1")
.setSource(jsonBuilder().startObject() .setSource(jsonBuilder().startObject()
.field("text", "elasticsearch test") .field("text", "elasticsearch test")
.field("byte", 25) .field("byte", 25)
@ -1497,4 +1497,41 @@ public class HighlighterSearchTests extends AbstractSharedClusterTest {
assertThat(response.getFailedShards(), equalTo(0)); assertThat(response.getFailedShards(), equalTo(0));
} }
@Test
// https://github.com/elasticsearch/elasticsearch/issues/3200
public void testResetTwice() throws Exception {
prepareCreate("test")
.setSettings(ImmutableSettings.builder()
.put("analysis.analyzer.my_analyzer.type", "pattern")
.put("analysis.analyzer.my_analyzer.pattern", "\\s+")
.build())
.addMapping("type", jsonBuilder()
.startObject()
.startObject("type")
.startObject("properties")
.startObject("text")
.field("type", "string")
.field("analyzer", "my_analyzer")
.endObject()
.endObject()
.endObject()
.endObject())
.execute().actionGet();
ensureGreen();
client().prepareIndex("test", "type", "1")
.setSource(jsonBuilder().startObject()
.field("text", "elasticsearch test")
.endObject())
.setRefresh(true)
.execute().actionGet();
SearchResponse response = client().prepareSearch("test")
.setQuery(QueryBuilders.matchQuery("text", "test").type(MatchQueryBuilder.Type.BOOLEAN))
.addHighlightedField("text").execute().actionGet();
assertThat(response.getHits().totalHits(), equalTo(1L));
// PatternAnalyzer will throw an exception if it is resetted twice
assertThat(response.getFailedShards(), equalTo(0));
}
} }