Fix match_phrase_prefix on boosted fields (#21623)
This change fixes the match_phrase_prefix on fields that define a boost in their mapping. Fixes #21613
This commit is contained in:
parent
914664d89a
commit
09fbb4d06d
|
@ -25,6 +25,7 @@ import org.apache.lucene.queries.ExtendedCommonTermsQuery;
|
|||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.BoostQuery;
|
||||
import org.apache.lucene.search.FuzzyQuery;
|
||||
import org.apache.lucene.search.MultiPhraseQuery;
|
||||
import org.apache.lucene.search.MultiTermQuery;
|
||||
|
@ -303,31 +304,38 @@ public class MatchQuery {
|
|||
|
||||
public Query createPhrasePrefixQuery(String field, String queryText, int phraseSlop, int maxExpansions) {
|
||||
final Query query = createFieldQuery(getAnalyzer(), Occur.MUST, field, queryText, true, phraseSlop);
|
||||
float boost = 1;
|
||||
Query innerQuery = query;
|
||||
while (innerQuery instanceof BoostQuery) {
|
||||
BoostQuery bq = (BoostQuery) innerQuery;
|
||||
boost *= bq.getBoost();
|
||||
innerQuery = bq.getQuery();
|
||||
}
|
||||
final MultiPhrasePrefixQuery prefixQuery = new MultiPhrasePrefixQuery();
|
||||
prefixQuery.setMaxExpansions(maxExpansions);
|
||||
prefixQuery.setSlop(phraseSlop);
|
||||
if (query instanceof PhraseQuery) {
|
||||
PhraseQuery pq = (PhraseQuery)query;
|
||||
if (innerQuery instanceof PhraseQuery) {
|
||||
PhraseQuery pq = (PhraseQuery) innerQuery;
|
||||
Term[] terms = pq.getTerms();
|
||||
int[] positions = pq.getPositions();
|
||||
for (int i = 0; i < terms.length; i++) {
|
||||
prefixQuery.add(new Term[] {terms[i]}, positions[i]);
|
||||
}
|
||||
return prefixQuery;
|
||||
} else if (query instanceof MultiPhraseQuery) {
|
||||
MultiPhraseQuery pq = (MultiPhraseQuery)query;
|
||||
return boost == 1 ? prefixQuery : new BoostQuery(prefixQuery, boost);
|
||||
} else if (innerQuery instanceof MultiPhraseQuery) {
|
||||
MultiPhraseQuery pq = (MultiPhraseQuery) innerQuery;
|
||||
Term[][] terms = pq.getTermArrays();
|
||||
int[] positions = pq.getPositions();
|
||||
for (int i = 0; i < terms.length; i++) {
|
||||
prefixQuery.add(terms[i], positions[i]);
|
||||
}
|
||||
return prefixQuery;
|
||||
} else if (query instanceof TermQuery) {
|
||||
prefixQuery.add(((TermQuery) query).getTerm());
|
||||
return prefixQuery;
|
||||
} else if (query instanceof AllTermQuery) {
|
||||
prefixQuery.add(((AllTermQuery) query).getTerm());
|
||||
return prefixQuery;
|
||||
return boost == 1 ? prefixQuery : new BoostQuery(prefixQuery, boost);
|
||||
} else if (innerQuery instanceof TermQuery) {
|
||||
prefixQuery.add(((TermQuery) innerQuery).getTerm());
|
||||
return boost == 1 ? prefixQuery : new BoostQuery(prefixQuery, boost);
|
||||
} else if (innerQuery instanceof AllTermQuery) {
|
||||
prefixQuery.add(((AllTermQuery) innerQuery).getTerm());
|
||||
return boost == 1 ? prefixQuery : new BoostQuery(prefixQuery, boost);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.query;
|
|||
import org.apache.lucene.queries.ExtendedCommonTermsQuery;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.BoostQuery;
|
||||
import org.apache.lucene.search.FuzzyQuery;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||
|
@ -29,11 +30,15 @@ import org.apache.lucene.search.PhraseQuery;
|
|||
import org.apache.lucene.search.PointRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.compress.CompressedXContent;
|
||||
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
|
||||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.search.MatchQuery;
|
||||
import org.elasticsearch.index.search.MatchQuery.Type;
|
||||
import org.elasticsearch.index.search.MatchQuery.ZeroTermsQuery;
|
||||
|
@ -458,4 +463,35 @@ public class MatchQueryBuilderTests extends AbstractQueryTestCase<MatchQueryBuil
|
|||
"}";
|
||||
expectThrows(IllegalStateException.class, () -> parseQuery(json2));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
|
||||
mapperService.merge("t_boost", new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef("t_boost",
|
||||
"string_boost", "type=text,boost=4").string()), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
}
|
||||
|
||||
public void testMatchPhrasePrefixWithBoost() throws Exception {
|
||||
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||
QueryShardContext context = createShardContext();
|
||||
assumeTrue("test runs only when the index version is on or after V_5_0_0_alpha1",
|
||||
context.indexVersionCreated().onOrAfter(Version.V_5_0_0_alpha1));
|
||||
|
||||
{
|
||||
// field boost is applied on a single term query
|
||||
MatchPhrasePrefixQueryBuilder builder = new MatchPhrasePrefixQueryBuilder("string_boost", "foo");
|
||||
Query query = builder.toQuery(context);
|
||||
assertThat(query, instanceOf(BoostQuery.class));
|
||||
assertThat(((BoostQuery) query).getBoost(), equalTo(4f));
|
||||
Query innerQuery = ((BoostQuery) query).getQuery();
|
||||
assertThat(innerQuery, instanceOf(MultiPhrasePrefixQuery.class));
|
||||
}
|
||||
|
||||
{
|
||||
// field boost is ignored on phrase query
|
||||
MatchPhrasePrefixQueryBuilder builder = new MatchPhrasePrefixQueryBuilder("string_boost", "foo bar");
|
||||
Query query = builder.toQuery(context);
|
||||
assertThat(query, instanceOf(MultiPhrasePrefixQuery.class));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue