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) {
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

View File

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