diff --git a/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java b/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java
index 88b045d2a5e..d360a9d68bd 100644
--- a/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java
+++ b/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java
@@ -28,6 +28,7 @@ import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.SynonymQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.join.ToParentBlockJoinQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
@@ -88,6 +89,13 @@ public class CustomFieldQuery extends FieldQuery {
flatten(boostingQuery.getMatch(), reader, flatQueries, boost);
//flatten negative query with negative boost
flatten(boostingQuery.getContext(), reader, flatQueries, boostingQuery.getBoost());
+ } else if (sourceQuery instanceof SynonymQuery) {
+ // SynonymQuery should be handled by the parent class directly.
+ // This statement should be removed when https://issues.apache.org/jira/browse/LUCENE-7484 is merged.
+ SynonymQuery synQuery = (SynonymQuery) sourceQuery;
+ for (Term term : synQuery.getTerms()) {
+ flatten(new TermQuery(term), reader, flatQueries, boost);
+ }
} else {
super.flatten(sourceQuery, reader, flatQueries, boost);
}
diff --git a/core/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java b/core/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java
index 19904be38b3..14cd65335f4 100644
--- a/core/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java
+++ b/core/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java
@@ -2907,4 +2907,45 @@ public class HighlighterSearchIT extends ESIntegTestCase {
assertThat(field.getFragments().length, equalTo(1));
assertThat(field.getFragments()[0].string(), equalTo("brown"));
}
+
+ public void testSynonyms() throws IOException {
+ Builder builder = Settings.builder()
+ .put(indexSettings())
+ .put("index.analysis.analyzer.synonym.tokenizer", "whitespace")
+ .putArray("index.analysis.analyzer.synonym.filter", "synonym", "lowercase")
+ .put("index.analysis.filter.synonym.type", "synonym")
+ .putArray("index.analysis.filter.synonym.synonyms", "fast,quick");
+
+ assertAcked(prepareCreate("test").setSettings(builder.build())
+ .addMapping("type1", "field1",
+ "type=text,term_vector=with_positions_offsets,search_analyzer=synonym," +
+ "analyzer=english,index_options=offsets"));
+ ensureGreen();
+
+ client().prepareIndex("test", "type1", "0").setSource(
+ "field1", "The quick brown fox jumps over the lazy dog").get();
+ refresh();
+ for (String highlighterType : new String[] {"plain", "postings", "fvh"}) {
+ logger.info("--> highlighting (type=" + highlighterType + ") and searching on field1");
+ SearchSourceBuilder source = searchSource()
+ .query(matchQuery("field1", "quick brown fox").operator(Operator.AND))
+ .highlighter(
+ highlight()
+ .field("field1")
+ .order("score")
+ .preTags("")
+ .postTags("")
+ .highlighterType(highlighterType));
+ SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet();
+ assertHighlight(searchResponse, 0, "field1", 0, 1,
+ equalTo("The quick brown fox jumps over the lazy dog"));
+
+ source = searchSource()
+ .query(matchQuery("field1", "fast brown fox").operator(Operator.AND))
+ .highlighter(highlight().field("field1").order("score").preTags("").postTags(""));
+ searchResponse = client().search(searchRequest("test").source(source)).actionGet();
+ assertHighlight(searchResponse, 0, "field1", 0, 1,
+ equalTo("The quick brown fox jumps over the lazy dog"));
+ }
+ }
}