Fix auto fuzziness in query_string query (#42897)

Setting `auto` after the fuzzy operator (e.g. `"query": "foo~auto"`) in the `query_string`
does not take the length of the term into account when computing the distance and always use
a max distance of 1. This change fixes this disrepancy by ensuring that the term is passed when
the fuzziness is computed.
This commit is contained in:
Jim Ferenczi 2019-06-10 09:31:23 +02:00 committed by jimczi
parent 25218733e6
commit 39cb1abc9d
2 changed files with 30 additions and 20 deletions

View File

@ -423,7 +423,8 @@ public class QueryStringQueryParser extends XQueryParser {
if (fuzzySlop.image.length() == 1) { if (fuzzySlop.image.length() == 1) {
return getFuzzyQuery(field, termImage, fuzziness.asDistance(termImage)); return getFuzzyQuery(field, termImage, fuzziness.asDistance(termImage));
} }
return getFuzzyQuery(field, termImage, Fuzziness.build(fuzzySlop.image.substring(1)).asFloat()); float distance = Fuzziness.build(fuzzySlop.image.substring(1)).asDistance(termImage);
return getFuzzyQuery(field, termImage, distance);
} }
@Override @Override

View File

@ -787,27 +787,36 @@ public class QueryStringQueryBuilderTests extends FullTextQueryTestCase<QueryStr
} }
public void testToQueryFuzzyQueryAutoFuziness() throws Exception { public void testToQueryFuzzyQueryAutoFuziness() throws Exception {
int length = randomIntBetween(1, 10); for (int i = 0; i < 3; i++) {
StringBuilder queryString = new StringBuilder(); final int expectedEdits;
for (int i = 0; i < length; i++) { String queryString;
queryString.append("a"); switch (i) {
} case 0:
queryString.append("~"); queryString = randomAlphaOfLengthBetween(1, 2);
expectedEdits = 0;
break;
int expectedEdits; case 1:
if (length <= 2) { queryString = randomAlphaOfLengthBetween(3, 5);
expectedEdits = 0; expectedEdits = 1;
} else if (3 <= length && length <= 5) { break;
expectedEdits = 1;
} else {
expectedEdits = 2;
}
Query query = queryStringQuery(queryString.toString()).defaultField(STRING_FIELD_NAME).fuzziness(Fuzziness.AUTO) default:
.toQuery(createShardContext()); queryString = randomAlphaOfLengthBetween(6, 20);
assertThat(query, instanceOf(FuzzyQuery.class)); expectedEdits = 2;
FuzzyQuery fuzzyQuery = (FuzzyQuery) query; break;
assertEquals(expectedEdits, fuzzyQuery.getMaxEdits()); }
for (int j = 0; j < 2; j++) {
Query query = queryStringQuery(queryString + (j == 0 ? "~" : "~auto"))
.defaultField(STRING_FIELD_NAME)
.fuzziness(Fuzziness.AUTO)
.toQuery(createShardContext());
assertThat(query, instanceOf(FuzzyQuery.class));
FuzzyQuery fuzzyQuery = (FuzzyQuery) query;
assertEquals(expectedEdits, fuzzyQuery.getMaxEdits());
}
}
} }
public void testFuzzyNumeric() throws Exception { public void testFuzzyNumeric() throws Exception {