percolator: fixed issue where in indices created before 6.1 if minimum should match has been specified on a disjunction,

the query would be marked as verified candidate match. This is wrong as it can only marked as verified candidate match
on indices created on or after 6.1, due to the use of the CoveringQuery.
This commit is contained in:
Martijn van Groningen 2017-11-10 11:53:17 +01:00
parent b4048b4e7f
commit 1bd31e9b53
No known key found for this signature in database
GPG Key ID: AB236F4FCF2AF12A
2 changed files with 48 additions and 4 deletions

View File

@ -493,10 +493,12 @@ final class QueryAnalyzer {
Version version) {
// Keep track of the msm for each clause:
int[] msmPerClause = new int[disjunctions.size()];
String[] rangeFieldNames = new String[disjunctions.size()];
boolean verified = otherClauses == false;
if (version.before(Version.V_6_1_0)) {
verified &= requiredShouldClauses <= 1;
}
Set<QueryExtraction> terms = new HashSet<>();
for (int i = 0; i < disjunctions.size(); i++) {
Query disjunct = disjunctions.get(i);
@ -513,9 +515,7 @@ final class QueryAnalyzer {
int msm = 0;
if (version.onOrAfter(Version.V_6_1_0)) {
Set<String> seenRangeFields = new HashSet<>();
// Figure out what the combined msm is for this disjunction:
// (sum the lowest required clauses, otherwise we're too strict and queries may not match)
Arrays.sort(msmPerClause);

View File

@ -224,6 +224,50 @@ public class QueryAnalyzerTests extends ESTestCase {
assertThat(terms.get(2).bytes(), equalTo(termQuery3.getTerm().bytes()));
}
public void testExtractQueryMetadata_booleanQuery_msm() {
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.setMinimumNumberShouldMatch(2);
TermQuery termQuery1 = new TermQuery(new Term("_field", "_term1"));
builder.add(termQuery1, BooleanClause.Occur.SHOULD);
TermQuery termQuery2 = new TermQuery(new Term("_field", "_term2"));
builder.add(termQuery2, BooleanClause.Occur.SHOULD);
TermQuery termQuery3 = new TermQuery(new Term("_field", "_term3"));
builder.add(termQuery3, BooleanClause.Occur.SHOULD);
BooleanQuery booleanQuery = builder.build();
Result result = analyze(booleanQuery, Version.CURRENT);
assertThat(result.verified, is(true));
assertThat(result.minimumShouldMatch, equalTo(2));
List<QueryExtraction> extractions = new ArrayList<>(result.extractions);
extractions.sort(Comparator.comparing(extraction -> extraction.term));
assertThat(extractions.size(), equalTo(3));
assertThat(extractions.get(0).term, equalTo(new Term("_field", "_term1")));
assertThat(extractions.get(1).term, equalTo(new Term("_field", "_term2")));
assertThat(extractions.get(2).term, equalTo(new Term("_field", "_term3")));
}
public void testExtractQueryMetadata_booleanQuery_msm_pre6dot1() {
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.setMinimumNumberShouldMatch(2);
TermQuery termQuery1 = new TermQuery(new Term("_field", "_term1"));
builder.add(termQuery1, BooleanClause.Occur.SHOULD);
TermQuery termQuery2 = new TermQuery(new Term("_field", "_term2"));
builder.add(termQuery2, BooleanClause.Occur.SHOULD);
TermQuery termQuery3 = new TermQuery(new Term("_field", "_term3"));
builder.add(termQuery3, BooleanClause.Occur.SHOULD);
BooleanQuery booleanQuery = builder.build();
Result result = analyze(booleanQuery, Version.V_6_0_0);
assertThat(result.verified, is(false));
assertThat(result.minimumShouldMatch, equalTo(1));
List<QueryExtraction> extractions = new ArrayList<>(result.extractions);
extractions.sort(Comparator.comparing(extraction -> extraction.term));
assertThat(extractions.size(), equalTo(3));
assertThat(extractions.get(0).term, equalTo(new Term("_field", "_term1")));
assertThat(extractions.get(1).term, equalTo(new Term("_field", "_term2")));
assertThat(extractions.get(2).term, equalTo(new Term("_field", "_term3")));
}
public void testExtractQueryMetadata_booleanQuery_onlyShould() {
BooleanQuery.Builder builder = new BooleanQuery.Builder();
TermQuery termQuery1 = new TermQuery(new Term("_field", "_term1"));