Fix FiltersFunctionScoreQuery highlighting (#21827)

This is a cleanup of the fix pushed in https://github.com/elastic/elasticsearch/pull/20400.
FiltersFunctionScoreQuery sub query should be extracted in CustomQueryScorer.extract (and not in CustomQueryScorer.extractUnknownQuery).
This does not fix any bug in this branch (it's just a cleanup) but the intent is first to clean up and then to backport in 2.x where there is a real bug.
The bug is in 2.x only because the backport of https://github.com/elastic/elasticsearch/pull/20400 in 2.x mistakenly renamed the FiltersFunctionScoreQuery to FunctionScoreQuery.
This leads to incorrect highlighting on FiltersFunctionScoreQuery in 2.x.
This commit is contained in:
Jim Ferenczi 2016-11-28 17:56:24 +01:00 committed by GitHub
parent 145d0813b5
commit 8affb7c845
2 changed files with 24 additions and 5 deletions

View File

@ -24,7 +24,6 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.QueryScorer; import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.WeightedSpanTerm; import org.apache.lucene.search.highlight.WeightedSpanTerm;
import org.apache.lucene.search.highlight.WeightedSpanTermExtractor; import org.apache.lucene.search.highlight.WeightedSpanTermExtractor;
import org.apache.lucene.spatial.geopoint.search.GeoPointInBBoxQuery;
import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery; import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery; import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
import org.elasticsearch.index.query.HasChildQueryBuilder; import org.elasticsearch.index.query.HasChildQueryBuilder;
@ -78,10 +77,7 @@ public final class CustomQueryScorer extends QueryScorer {
@Override @Override
protected void extractUnknownQuery(Query query, protected void extractUnknownQuery(Query query,
Map<String, WeightedSpanTerm> terms) throws IOException { Map<String, WeightedSpanTerm> terms) throws IOException {
if (query instanceof FiltersFunctionScoreQuery) { if (terms.isEmpty()) {
query = ((FiltersFunctionScoreQuery) query).getSubQuery();
extract(query, 1F, terms);
} else if (terms.isEmpty()) {
extractWeightedTerms(terms, query, 1F); extractWeightedTerms(terms, query, 1F);
} }
} }
@ -92,6 +88,8 @@ public final class CustomQueryScorer extends QueryScorer {
return; return;
} else if (query instanceof FunctionScoreQuery) { } else if (query instanceof FunctionScoreQuery) {
super.extract(((FunctionScoreQuery) query).getSubQuery(), boost, terms); super.extract(((FunctionScoreQuery) query).getSubQuery(), boost, terms);
} else if (query instanceof FiltersFunctionScoreQuery) {
super.extract(((FiltersFunctionScoreQuery) query).getSubQuery(), boost, terms);
} else { } else {
super.extract(query, boost, terms); super.extract(query, boost, terms);
} }

View File

@ -39,6 +39,7 @@ import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.RandomScoreFunctionBuilder;
import org.elasticsearch.index.search.MatchQuery; import org.elasticsearch.index.search.MatchQuery;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.RestStatus;
@ -2935,6 +2936,26 @@ public class HighlighterSearchIT extends ESIntegTestCase {
assertThat(field.getFragments()[0].string(), equalTo("<em>brown</em>")); assertThat(field.getFragments()[0].string(), equalTo("<em>brown</em>"));
} }
public void testFiltersFunctionScoreQueryHighlight() throws Exception {
client().prepareIndex("test", "type", "1")
.setSource(jsonBuilder().startObject().field("text", "brown").field("enable", "yes").endObject())
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.get();
FunctionScoreQueryBuilder.FilterFunctionBuilder filterBuilder =
new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("enable", "yes"),
new RandomScoreFunctionBuilder());
SearchResponse searchResponse = client().prepareSearch()
.setQuery(new FunctionScoreQueryBuilder(QueryBuilders.prefixQuery("text", "bro"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {filterBuilder}))
.highlighter(new HighlightBuilder()
.field(new Field("text")))
.get();
assertHitCount(searchResponse, 1);
HighlightField field = searchResponse.getHits().getAt(0).highlightFields().get("text");
assertThat(field.getFragments().length, equalTo(1));
assertThat(field.getFragments()[0].string(), equalTo("<em>brown</em>"));
}
public void testSynonyms() throws IOException { public void testSynonyms() throws IOException {
Builder builder = Settings.builder() Builder builder = Settings.builder()
.put(indexSettings()) .put(indexSettings())