From e874dee3bc919cf51e3b84a7ef63815c622d2ae2 Mon Sep 17 00:00:00 2001 From: Jim Ferenczi Date: Mon, 10 Oct 2016 17:46:19 +0200 Subject: [PATCH] Handle SynonymQuery extraction for the FastVectorHighlighter (#20829) SynonymQuery was ignored by the FastVectorHighlighter. This change adds the support for SynonymQuery in the FVH. Although this change should be implemented in Lucene directly which is why https://issues.apache.org/jira/browse/LUCENE-7484 has been opened. In the meantime this PR handles the issue on ES side and could be removed when LUCENE-7484 gets merged. Fixes #20781 --- .../vectorhighlight/CustomFieldQuery.java | 8 ++++ .../highlight/HighlighterSearchIT.java | 41 +++++++++++++++++++ 2 files changed, 49 insertions(+) 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")); + } + } }