Don't allow `fuzziness` for `multi_match` types cross_fields, phrase and phrase_prefix

Currently `fuzziness` is not supported for the `cross_fields` type
of the `multi_match` query since it complicates the logic that
blends the term queries that cross_fields uses internally. At the
moment using this combination is silently ignored, which can lead to
confusions. Instead we should throw an exception in this case.
The same is true for phrase and phrase_prefix type.

Closes #7764
This commit is contained in:
Christoph Büscher 2016-05-13 11:08:46 +02:00
parent 786a6a00d9
commit a40c397c67
4 changed files with 61 additions and 1 deletions

View File

@ -655,6 +655,11 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
throw new ParsingException(parser.getTokenLocation(), "No fields specified for multi_match query"); throw new ParsingException(parser.getTokenLocation(), "No fields specified for multi_match query");
} }
if (fuzziness != null && (type == Type.CROSS_FIELDS || type == Type.PHRASE || type == Type.PHRASE_PREFIX)) {
throw new ParsingException(parser.getTokenLocation(),
"Fuziness not allowed for type [" + type.parseField.getPreferredName() + "]");
}
return new MultiMatchQueryBuilder(value) return new MultiMatchQueryBuilder(value)
.fields(fieldsBoosts) .fields(fieldsBoosts)
.type(type) .type(type)

View File

@ -31,9 +31,11 @@ import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PointRangeQuery; import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermQuery;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.lucene.all.AllTermQuery; import org.elasticsearch.common.lucene.all.AllTermQuery;
import org.elasticsearch.common.lucene.search.MatchNoDocsQuery; import org.elasticsearch.common.lucene.search.MatchNoDocsQuery;
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery; import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type;
import org.elasticsearch.index.search.MatchQuery; import org.elasticsearch.index.search.MatchQuery;
import java.io.IOException; import java.io.IOException;
@ -80,7 +82,7 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase<MultiMatc
if (randomBoolean()) { if (randomBoolean()) {
query.slop(randomIntBetween(0, 5)); query.slop(randomIntBetween(0, 5));
} }
if (randomBoolean()) { if (randomBoolean() && (query.type() == Type.BEST_FIELDS || query.type() == Type.MOST_FIELDS)) {
query.fuzziness(randomFuzziness(fieldName)); query.fuzziness(randomFuzziness(fieldName));
} }
if (randomBoolean()) { if (randomBoolean()) {
@ -254,4 +256,39 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase<MultiMatc
assertEquals(json, MultiMatchQueryBuilder.Type.MOST_FIELDS, parsed.type()); assertEquals(json, MultiMatchQueryBuilder.Type.MOST_FIELDS, parsed.type());
assertEquals(json, Operator.OR, parsed.operator()); assertEquals(json, Operator.OR, parsed.operator());
} }
/**
* `fuzziness` is not allowed for `cross_fields`, `phrase` and `phrase_prefix` and should throw an error
*/
public void testFuzzinessNotAllowedTypes() throws IOException {
String[] notAllowedTypes = new String[]{ Type.CROSS_FIELDS.parseField().getPreferredName(),
Type.PHRASE.parseField().getPreferredName(), Type.PHRASE_PREFIX.parseField().getPreferredName()};
for (String type : notAllowedTypes) {
String json =
"{\n" +
" \"multi_match\" : {\n" +
" \"query\" : \"quick brown fox\",\n" +
" \"fields\" : [ \"title^1.0\", \"title.original^1.0\", \"title.shingles^1.0\" ],\n" +
" \"type\" : \"" + type + "\",\n" +
" \"fuzziness\" : 1" +
" }\n" +
"}";
ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(json));
assertEquals("Fuziness not allowed for type [" + type +"]", e.getMessage());
}
}
public void testQueryParameterArrayException() throws IOException {
String json =
"{\n" +
" \"multi_match\" : {\n" +
" \"query\" : [\"quick\", \"brown\", \"fox\"]\n" +
" \"fields\" : [ \"title^1.0\", \"title.original^1.0\", \"title.shingles^1.0\" ]" +
" }\n" +
"}";
ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(json));
assertEquals("[multi_match] unknown token [START_ARRAY] after [query]", e.getMessage());
}
} }

View File

@ -126,6 +126,9 @@ in favour of `query` and `no_match_query`.
* The `exists` query will now fail if the `_field_names` field is disabled. * The `exists` query will now fail if the `_field_names` field is disabled.
* The `multi_match` query will fail if `fuzziness` is used for `cross_fields`, `phrase` or `phrase_prefix` type.
This parameter was undocumented and silently ignored before for these types of `multi_match`.
* Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoPolygonQuery. Use parameter validation_method instead. * Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoPolygonQuery. Use parameter validation_method instead.
* Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoDistanceRangeQuery. Use parameter validation_method instead. * Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoDistanceRangeQuery. Use parameter validation_method instead.
@ -133,6 +136,7 @@ in favour of `query` and `no_match_query`.
* Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoDistanceQuery. Use parameter validation_method instead. * Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoDistanceQuery. Use parameter validation_method instead.
* Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoBoundingBoxQuery. Use parameter validation_method instead. * Deprecated support for the coerce, normalize, ignore_malformed parameters in GeoBoundingBoxQuery. Use parameter validation_method instead.
==== Top level `filter` parameter ==== Top level `filter` parameter
Removed support for the deprecated top level `filter` in the search api, Removed support for the deprecated top level `filter` in the search api,

View File

@ -239,6 +239,13 @@ Also, accepts `analyzer`, `boost`, `slop` and `zero_terms_query` as explained
in <<query-dsl-match-query>>. Type `phrase_prefix` additionally accepts in <<query-dsl-match-query>>. Type `phrase_prefix` additionally accepts
`max_expansions`. `max_expansions`.
[IMPORTANT]
[[phrase-fuzziness]]
.`phrase`, `phrase_prefix` and `fuzziness`
===================================================
The `fuzziness` parameter cannot be used with the `phrase` or `phrase_prefix` type.
===================================================
[[type-cross-fields]] [[type-cross-fields]]
==== `cross_fields` ==== `cross_fields`
@ -432,3 +439,10 @@ per-term `blended` queries. It accepts:
`last_name:will` `last_name:will`
`0.0 < n < 1.0`:: Take the single best score plus +tie_breaker+ multiplied `0.0 < n < 1.0`:: Take the single best score plus +tie_breaker+ multiplied
by each of the scores from other matching fields. by each of the scores from other matching fields.
[IMPORTANT]
[[crossfields-fuzziness]]
.`cross_fields` and `fuzziness`
===================================================
The `fuzziness` parameter cannot be used with the `cross_fields` type.
===================================================