Expose `fuzzy_transpositions` parameter in fuzzy queries (#26870)
Add fuzzy_transpositions parameter to multi_match and query_string queries. Add fuzzy_transpositions, fuzzy_prefix_length and fuzzy_max_expansions parameters to simple_query_string query.
This commit is contained in:
parent
c5a0e77fc6
commit
9c95e91471
|
@ -57,6 +57,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
public static final int DEFAULT_MAX_EXPANSIONS = FuzzyQuery.defaultMaxExpansions;
|
public static final int DEFAULT_MAX_EXPANSIONS = FuzzyQuery.defaultMaxExpansions;
|
||||||
public static final boolean DEFAULT_LENIENCY = MatchQuery.DEFAULT_LENIENCY;
|
public static final boolean DEFAULT_LENIENCY = MatchQuery.DEFAULT_LENIENCY;
|
||||||
public static final MatchQuery.ZeroTermsQuery DEFAULT_ZERO_TERMS_QUERY = MatchQuery.DEFAULT_ZERO_TERMS_QUERY;
|
public static final MatchQuery.ZeroTermsQuery DEFAULT_ZERO_TERMS_QUERY = MatchQuery.DEFAULT_ZERO_TERMS_QUERY;
|
||||||
|
public static final boolean DEFAULT_FUZZY_TRANSPOSITIONS = FuzzyQuery.defaultTranspositions;
|
||||||
|
|
||||||
private static final ParseField SLOP_FIELD = new ParseField("slop");
|
private static final ParseField SLOP_FIELD = new ParseField("slop");
|
||||||
private static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
|
private static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
|
||||||
|
@ -74,6 +75,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
private static final ParseField QUERY_FIELD = new ParseField("query");
|
private static final ParseField QUERY_FIELD = new ParseField("query");
|
||||||
private static final ParseField FIELDS_FIELD = new ParseField("fields");
|
private static final ParseField FIELDS_FIELD = new ParseField("fields");
|
||||||
private static final ParseField GENERATE_SYNONYMS_PHRASE_QUERY = new ParseField("auto_generate_synonyms_phrase_query");
|
private static final ParseField GENERATE_SYNONYMS_PHRASE_QUERY = new ParseField("auto_generate_synonyms_phrase_query");
|
||||||
|
private static final ParseField FUZZY_TRANSPOSITIONS_FIELD = new ParseField("fuzzy_transpositions");
|
||||||
|
|
||||||
|
|
||||||
private final Object value;
|
private final Object value;
|
||||||
|
@ -93,6 +95,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
private Float cutoffFrequency = null;
|
private Float cutoffFrequency = null;
|
||||||
private MatchQuery.ZeroTermsQuery zeroTermsQuery = DEFAULT_ZERO_TERMS_QUERY;
|
private MatchQuery.ZeroTermsQuery zeroTermsQuery = DEFAULT_ZERO_TERMS_QUERY;
|
||||||
private boolean autoGenerateSynonymsPhraseQuery = true;
|
private boolean autoGenerateSynonymsPhraseQuery = true;
|
||||||
|
private boolean fuzzyTranspositions = DEFAULT_FUZZY_TRANSPOSITIONS;
|
||||||
|
|
||||||
public enum Type implements Writeable {
|
public enum Type implements Writeable {
|
||||||
|
|
||||||
|
@ -226,6 +229,9 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
if (in.getVersion().onOrAfter(Version.V_6_1_0)) {
|
if (in.getVersion().onOrAfter(Version.V_6_1_0)) {
|
||||||
autoGenerateSynonymsPhraseQuery = in.readBoolean();
|
autoGenerateSynonymsPhraseQuery = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
fuzzyTranspositions = in.readBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -253,6 +259,9 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
if (out.getVersion().onOrAfter(Version.V_6_1_0)) {
|
if (out.getVersion().onOrAfter(Version.V_6_1_0)) {
|
||||||
out.writeBoolean(autoGenerateSynonymsPhraseQuery);
|
out.writeBoolean(autoGenerateSynonymsPhraseQuery);
|
||||||
}
|
}
|
||||||
|
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
out.writeBoolean(fuzzyTranspositions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object value() {
|
public Object value() {
|
||||||
|
@ -535,6 +544,22 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
return autoGenerateSynonymsPhraseQuery;
|
return autoGenerateSynonymsPhraseQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean fuzzyTranspositions() {
|
||||||
|
return fuzzyTranspositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether transpositions are supported in fuzzy queries.<p>
|
||||||
|
* The default metric used by fuzzy queries to determine a match is the Damerau-Levenshtein
|
||||||
|
* distance formula which supports transpositions. Setting transposition to false will
|
||||||
|
* switch to classic Levenshtein distance.<br>
|
||||||
|
* If not set, Damerau-Levenshtein distance metric will be used.
|
||||||
|
*/
|
||||||
|
public MultiMatchQueryBuilder fuzzyTranspositions(boolean fuzzyTranspositions) {
|
||||||
|
this.fuzzyTranspositions = fuzzyTranspositions;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(NAME);
|
builder.startObject(NAME);
|
||||||
|
@ -573,6 +598,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
}
|
}
|
||||||
builder.field(ZERO_TERMS_QUERY_FIELD.getPreferredName(), zeroTermsQuery.toString());
|
builder.field(ZERO_TERMS_QUERY_FIELD.getPreferredName(), zeroTermsQuery.toString());
|
||||||
builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), autoGenerateSynonymsPhraseQuery);
|
builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), autoGenerateSynonymsPhraseQuery);
|
||||||
|
builder.field(FUZZY_TRANSPOSITIONS_FIELD.getPreferredName(), fuzzyTranspositions);
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -595,6 +621,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
boolean lenient = DEFAULT_LENIENCY;
|
boolean lenient = DEFAULT_LENIENCY;
|
||||||
MatchQuery.ZeroTermsQuery zeroTermsQuery = DEFAULT_ZERO_TERMS_QUERY;
|
MatchQuery.ZeroTermsQuery zeroTermsQuery = DEFAULT_ZERO_TERMS_QUERY;
|
||||||
boolean autoGenerateSynonymsPhraseQuery = true;
|
boolean autoGenerateSynonymsPhraseQuery = true;
|
||||||
|
boolean fuzzyTranspositions = DEFAULT_FUZZY_TRANSPOSITIONS;
|
||||||
|
|
||||||
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
|
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
|
||||||
String queryName = null;
|
String queryName = null;
|
||||||
|
@ -659,6 +686,8 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
queryName = parser.text();
|
queryName = parser.text();
|
||||||
} else if (GENERATE_SYNONYMS_PHRASE_QUERY.match(currentFieldName)) {
|
} else if (GENERATE_SYNONYMS_PHRASE_QUERY.match(currentFieldName)) {
|
||||||
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
|
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
|
||||||
|
} else if (FUZZY_TRANSPOSITIONS_FIELD.match(currentFieldName)) {
|
||||||
|
fuzzyTranspositions = parser.booleanValue();
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(),
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
"[" + NAME + "] query does not support [" + currentFieldName + "]");
|
"[" + NAME + "] query does not support [" + currentFieldName + "]");
|
||||||
|
@ -700,7 +729,8 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
.zeroTermsQuery(zeroTermsQuery)
|
.zeroTermsQuery(zeroTermsQuery)
|
||||||
.autoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery)
|
.autoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery)
|
||||||
.boost(boost)
|
.boost(boost)
|
||||||
.queryName(queryName);
|
.queryName(queryName)
|
||||||
|
.fuzzyTranspositions(fuzzyTranspositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseFieldAndBoost(XContentParser parser, Map<String, Float> fieldsBoosts) throws IOException {
|
private static void parseFieldAndBoost(XContentParser parser, Map<String, Float> fieldsBoosts) throws IOException {
|
||||||
|
@ -755,6 +785,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
multiMatchQuery.setLenient(lenient);
|
multiMatchQuery.setLenient(lenient);
|
||||||
multiMatchQuery.setZeroTermsQuery(zeroTermsQuery);
|
multiMatchQuery.setZeroTermsQuery(zeroTermsQuery);
|
||||||
multiMatchQuery.setAutoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
multiMatchQuery.setAutoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
||||||
|
multiMatchQuery.setTranspositions(fuzzyTranspositions);
|
||||||
|
|
||||||
if (useDisMax != null) { // backwards foobar
|
if (useDisMax != null) { // backwards foobar
|
||||||
boolean typeUsesDismax = type.tieBreaker() != 1.0f;
|
boolean typeUsesDismax = type.tieBreaker() != 1.0f;
|
||||||
|
@ -775,7 +806,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
protected int doHashCode() {
|
protected int doHashCode() {
|
||||||
return Objects.hash(value, fieldsBoosts, type, operator, analyzer, slop, fuzziness,
|
return Objects.hash(value, fieldsBoosts, type, operator, analyzer, slop, fuzziness,
|
||||||
prefixLength, maxExpansions, minimumShouldMatch, fuzzyRewrite, useDisMax, tieBreaker, lenient,
|
prefixLength, maxExpansions, minimumShouldMatch, fuzzyRewrite, useDisMax, tieBreaker, lenient,
|
||||||
cutoffFrequency, zeroTermsQuery, autoGenerateSynonymsPhraseQuery);
|
cutoffFrequency, zeroTermsQuery, autoGenerateSynonymsPhraseQuery, fuzzyTranspositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -796,6 +827,7 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
Objects.equals(lenient, other.lenient) &&
|
Objects.equals(lenient, other.lenient) &&
|
||||||
Objects.equals(cutoffFrequency, other.cutoffFrequency) &&
|
Objects.equals(cutoffFrequency, other.cutoffFrequency) &&
|
||||||
Objects.equals(zeroTermsQuery, other.zeroTermsQuery) &&
|
Objects.equals(zeroTermsQuery, other.zeroTermsQuery) &&
|
||||||
Objects.equals(autoGenerateSynonymsPhraseQuery, other.autoGenerateSynonymsPhraseQuery);
|
Objects.equals(autoGenerateSynonymsPhraseQuery, other.autoGenerateSynonymsPhraseQuery) &&
|
||||||
|
Objects.equals(fuzzyTranspositions, other.fuzzyTranspositions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
public static final Fuzziness DEFAULT_FUZZINESS = Fuzziness.AUTO;
|
public static final Fuzziness DEFAULT_FUZZINESS = Fuzziness.AUTO;
|
||||||
public static final Operator DEFAULT_OPERATOR = Operator.OR;
|
public static final Operator DEFAULT_OPERATOR = Operator.OR;
|
||||||
public static final MultiMatchQueryBuilder.Type DEFAULT_TYPE = MultiMatchQueryBuilder.Type.BEST_FIELDS;
|
public static final MultiMatchQueryBuilder.Type DEFAULT_TYPE = MultiMatchQueryBuilder.Type.BEST_FIELDS;
|
||||||
|
public static final boolean DEFAULT_FUZZY_TRANSPOSITIONS = FuzzyQuery.defaultTranspositions;
|
||||||
|
|
||||||
private static final ParseField QUERY_FIELD = new ParseField("query");
|
private static final ParseField QUERY_FIELD = new ParseField("query");
|
||||||
private static final ParseField FIELDS_FIELD = new ParseField("fields");
|
private static final ParseField FIELDS_FIELD = new ParseField("fields");
|
||||||
|
@ -104,6 +105,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
.withAllDeprecated("Set [default_field] to `*` instead");
|
.withAllDeprecated("Set [default_field] to `*` instead");
|
||||||
private static final ParseField TYPE_FIELD = new ParseField("type");
|
private static final ParseField TYPE_FIELD = new ParseField("type");
|
||||||
private static final ParseField GENERATE_SYNONYMS_PHRASE_QUERY = new ParseField("auto_generate_synonyms_phrase_query");
|
private static final ParseField GENERATE_SYNONYMS_PHRASE_QUERY = new ParseField("auto_generate_synonyms_phrase_query");
|
||||||
|
private static final ParseField FUZZY_TRANSPOSITIONS_FIELD = new ParseField("fuzzy_transpositions");
|
||||||
|
|
||||||
private final String queryString;
|
private final String queryString;
|
||||||
|
|
||||||
|
@ -161,6 +163,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
|
|
||||||
private boolean autoGenerateSynonymsPhraseQuery = true;
|
private boolean autoGenerateSynonymsPhraseQuery = true;
|
||||||
|
|
||||||
|
private boolean fuzzyTranspositions = DEFAULT_FUZZY_TRANSPOSITIONS;
|
||||||
|
|
||||||
public QueryStringQueryBuilder(String queryString) {
|
public QueryStringQueryBuilder(String queryString) {
|
||||||
if (queryString == null) {
|
if (queryString == null) {
|
||||||
throw new IllegalArgumentException("query text missing");
|
throw new IllegalArgumentException("query text missing");
|
||||||
|
@ -226,6 +230,9 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
if (in.getVersion().onOrAfter(Version.V_6_1_0)) {
|
if (in.getVersion().onOrAfter(Version.V_6_1_0)) {
|
||||||
autoGenerateSynonymsPhraseQuery = in.readBoolean();
|
autoGenerateSynonymsPhraseQuery = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
fuzzyTranspositions = in.readBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -281,6 +288,9 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
if (out.getVersion().onOrAfter(Version.V_6_1_0)) {
|
if (out.getVersion().onOrAfter(Version.V_6_1_0)) {
|
||||||
out.writeBoolean(autoGenerateSynonymsPhraseQuery);
|
out.writeBoolean(autoGenerateSynonymsPhraseQuery);
|
||||||
}
|
}
|
||||||
|
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
out.writeBoolean(fuzzyTranspositions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String queryString() {
|
public String queryString() {
|
||||||
|
@ -648,6 +658,22 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
return autoGenerateSynonymsPhraseQuery;
|
return autoGenerateSynonymsPhraseQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean fuzzyTranspositions() {
|
||||||
|
return fuzzyTranspositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether transpositions are supported in fuzzy queries.<p>
|
||||||
|
* The default metric used by fuzzy queries to determine a match is the Damerau-Levenshtein
|
||||||
|
* distance formula which supports transpositions. Setting transposition to false will
|
||||||
|
* switch to classic Levenshtein distance.<br>
|
||||||
|
* If not set, Damerau-Levenshtein distance metric will be used.
|
||||||
|
*/
|
||||||
|
public QueryStringQueryBuilder fuzzyTranspositions(boolean fuzzyTranspositions) {
|
||||||
|
this.fuzzyTranspositions = fuzzyTranspositions;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(NAME);
|
builder.startObject(NAME);
|
||||||
|
@ -706,6 +732,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
}
|
}
|
||||||
builder.field(ESCAPE_FIELD.getPreferredName(), this.escape);
|
builder.field(ESCAPE_FIELD.getPreferredName(), this.escape);
|
||||||
builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), autoGenerateSynonymsPhraseQuery);
|
builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), autoGenerateSynonymsPhraseQuery);
|
||||||
|
builder.field(FUZZY_TRANSPOSITIONS_FIELD.getPreferredName(), fuzzyTranspositions);
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -739,6 +766,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
String rewrite = null;
|
String rewrite = null;
|
||||||
Map<String, Float> fieldsAndWeights = null;
|
Map<String, Float> fieldsAndWeights = null;
|
||||||
boolean autoGenerateSynonymsPhraseQuery = true;
|
boolean autoGenerateSynonymsPhraseQuery = true;
|
||||||
|
boolean fuzzyTranspositions = DEFAULT_FUZZY_TRANSPOSITIONS;
|
||||||
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
|
@ -813,6 +842,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
queryName = parser.text();
|
queryName = parser.text();
|
||||||
} else if (GENERATE_SYNONYMS_PHRASE_QUERY.match(currentFieldName)) {
|
} else if (GENERATE_SYNONYMS_PHRASE_QUERY.match(currentFieldName)) {
|
||||||
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
|
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
|
||||||
|
} else if (FUZZY_TRANSPOSITIONS_FIELD.match(currentFieldName)) {
|
||||||
|
fuzzyTranspositions = parser.booleanValue();
|
||||||
} else if (AUTO_GENERATE_PHRASE_QUERIES_FIELD.match(currentFieldName)) {
|
} else if (AUTO_GENERATE_PHRASE_QUERIES_FIELD.match(currentFieldName)) {
|
||||||
// ignore, deprecated setting
|
// ignore, deprecated setting
|
||||||
} else if (LOWERCASE_EXPANDED_TERMS_FIELD.match(currentFieldName)) {
|
} else if (LOWERCASE_EXPANDED_TERMS_FIELD.match(currentFieldName)) {
|
||||||
|
@ -866,6 +897,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
queryStringQuery.boost(boost);
|
queryStringQuery.boost(boost);
|
||||||
queryStringQuery.queryName(queryName);
|
queryStringQuery.queryName(queryName);
|
||||||
queryStringQuery.autoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
queryStringQuery.autoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
||||||
|
queryStringQuery.fuzzyTranspositions(fuzzyTranspositions);
|
||||||
return queryStringQuery;
|
return queryStringQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,7 +932,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
Objects.equals(timeZone.getID(), other.timeZone.getID()) &&
|
Objects.equals(timeZone.getID(), other.timeZone.getID()) &&
|
||||||
Objects.equals(escape, other.escape) &&
|
Objects.equals(escape, other.escape) &&
|
||||||
Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates) &&
|
Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates) &&
|
||||||
Objects.equals(autoGenerateSynonymsPhraseQuery, other.autoGenerateSynonymsPhraseQuery);
|
Objects.equals(autoGenerateSynonymsPhraseQuery, other.autoGenerateSynonymsPhraseQuery) &&
|
||||||
|
Objects.equals(fuzzyTranspositions, other.fuzzyTranspositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -909,7 +942,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
quoteFieldSuffix, allowLeadingWildcard, analyzeWildcard,
|
quoteFieldSuffix, allowLeadingWildcard, analyzeWildcard,
|
||||||
enablePositionIncrements, fuzziness, fuzzyPrefixLength,
|
enablePositionIncrements, fuzziness, fuzzyPrefixLength,
|
||||||
fuzzyMaxExpansions, fuzzyRewrite, phraseSlop, type, tieBreaker, rewrite, minimumShouldMatch, lenient,
|
fuzzyMaxExpansions, fuzzyRewrite, phraseSlop, type, tieBreaker, rewrite, minimumShouldMatch, lenient,
|
||||||
timeZone == null ? 0 : timeZone.getID(), escape, maxDeterminizedStates, autoGenerateSynonymsPhraseQuery);
|
timeZone == null ? 0 : timeZone.getID(), escape, maxDeterminizedStates, autoGenerateSynonymsPhraseQuery,
|
||||||
|
fuzzyTranspositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -979,6 +1013,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
||||||
queryParser.setTimeZone(timeZone);
|
queryParser.setTimeZone(timeZone);
|
||||||
queryParser.setMaxDeterminizedStates(maxDeterminizedStates);
|
queryParser.setMaxDeterminizedStates(maxDeterminizedStates);
|
||||||
queryParser.setAutoGenerateMultiTermSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
queryParser.setAutoGenerateMultiTermSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
||||||
|
queryParser.setFuzzyTranspositions(fuzzyTranspositions);
|
||||||
|
|
||||||
Query query;
|
Query query;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
|
import org.apache.lucene.search.FuzzyQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
|
@ -89,6 +90,12 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
public static final Operator DEFAULT_OPERATOR = Operator.OR;
|
public static final Operator DEFAULT_OPERATOR = Operator.OR;
|
||||||
/** Default for search flags to use. */
|
/** Default for search flags to use. */
|
||||||
public static final int DEFAULT_FLAGS = SimpleQueryStringFlag.ALL.value;
|
public static final int DEFAULT_FLAGS = SimpleQueryStringFlag.ALL.value;
|
||||||
|
/** Default for prefix length in fuzzy queries.*/
|
||||||
|
public static final int DEFAULT_FUZZY_PREFIX_LENGTH = FuzzyQuery.defaultPrefixLength;
|
||||||
|
/** Default number of terms fuzzy queries will expand to.*/
|
||||||
|
public static final int DEFAULT_FUZZY_MAX_EXPANSIONS = FuzzyQuery.defaultMaxExpansions;
|
||||||
|
/** Default for using transpositions in fuzzy queries.*/
|
||||||
|
public static final boolean DEFAULT_FUZZY_TRANSPOSITIONS = FuzzyQuery.defaultTranspositions;
|
||||||
|
|
||||||
/** Name for (de-)serialization. */
|
/** Name for (de-)serialization. */
|
||||||
public static final String NAME = "simple_query_string";
|
public static final String NAME = "simple_query_string";
|
||||||
|
@ -109,6 +116,9 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
private static final ParseField ALL_FIELDS_FIELD = new ParseField("all_fields")
|
private static final ParseField ALL_FIELDS_FIELD = new ParseField("all_fields")
|
||||||
.withAllDeprecated("Set [fields] to `*` instead");
|
.withAllDeprecated("Set [fields] to `*` instead");
|
||||||
private static final ParseField GENERATE_SYNONYMS_PHRASE_QUERY = new ParseField("auto_generate_synonyms_phrase_query");
|
private static final ParseField GENERATE_SYNONYMS_PHRASE_QUERY = new ParseField("auto_generate_synonyms_phrase_query");
|
||||||
|
private static final ParseField FUZZY_PREFIX_LENGTH_FIELD = new ParseField("fuzzy_prefix_length");
|
||||||
|
private static final ParseField FUZZY_MAX_EXPANSIONS_FIELD = new ParseField("fuzzy_max_expansions");
|
||||||
|
private static final ParseField FUZZY_TRANSPOSITIONS_FIELD = new ParseField("fuzzy_transpositions");
|
||||||
|
|
||||||
/** Query text to parse. */
|
/** Query text to parse. */
|
||||||
private final String queryText;
|
private final String queryText;
|
||||||
|
@ -182,6 +192,11 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
if (in.getVersion().onOrAfter(Version.V_6_1_0)) {
|
if (in.getVersion().onOrAfter(Version.V_6_1_0)) {
|
||||||
settings.autoGenerateSynonymsPhraseQuery(in.readBoolean());
|
settings.autoGenerateSynonymsPhraseQuery(in.readBoolean());
|
||||||
}
|
}
|
||||||
|
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
settings.fuzzyPrefixLength(in.readVInt());
|
||||||
|
settings.fuzzyMaxExpansions(in.readVInt());
|
||||||
|
settings.fuzzyTranspositions(in.readBoolean());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -220,6 +235,11 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
if (out.getVersion().onOrAfter(Version.V_6_1_0)) {
|
if (out.getVersion().onOrAfter(Version.V_6_1_0)) {
|
||||||
out.writeBoolean(settings.autoGenerateSynonymsPhraseQuery());
|
out.writeBoolean(settings.autoGenerateSynonymsPhraseQuery());
|
||||||
}
|
}
|
||||||
|
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
out.writeVInt(settings.fuzzyPrefixLength());
|
||||||
|
out.writeVInt(settings.fuzzyMaxExpansions());
|
||||||
|
out.writeBoolean(settings.fuzzyTranspositions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the text to parse the query from. */
|
/** Returns the text to parse the query from. */
|
||||||
|
@ -395,6 +415,39 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
return settings.autoGenerateSynonymsPhraseQuery();
|
return settings.autoGenerateSynonymsPhraseQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SimpleQueryStringBuilder fuzzyPrefixLength(int fuzzyPrefixLength) {
|
||||||
|
this.settings.fuzzyPrefixLength(fuzzyPrefixLength);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fuzzyPrefixLength() {
|
||||||
|
return settings.fuzzyPrefixLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleQueryStringBuilder fuzzyMaxExpansions(int fuzzyMaxExpansions) {
|
||||||
|
this.settings.fuzzyMaxExpansions(fuzzyMaxExpansions);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fuzzyMaxExpansions() {
|
||||||
|
return settings.fuzzyMaxExpansions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fuzzyTranspositions() {
|
||||||
|
return settings.fuzzyTranspositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether transpositions are supported in fuzzy queries.<p>
|
||||||
|
* The default metric used by fuzzy queries to determine a match is the Damerau-Levenshtein
|
||||||
|
* distance formula which supports transpositions. Setting transposition to false will
|
||||||
|
* switch to classic Levenshtein distance.<br>
|
||||||
|
* If not set, Damerau-Levenshtein distance metric will be used.
|
||||||
|
*/
|
||||||
|
public SimpleQueryStringBuilder fuzzyTranspositions(boolean fuzzyTranspositions) {
|
||||||
|
this.settings.fuzzyTranspositions(fuzzyTranspositions);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
|
@ -460,6 +513,9 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
builder.field(MINIMUM_SHOULD_MATCH_FIELD.getPreferredName(), minimumShouldMatch);
|
builder.field(MINIMUM_SHOULD_MATCH_FIELD.getPreferredName(), minimumShouldMatch);
|
||||||
}
|
}
|
||||||
builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), settings.autoGenerateSynonymsPhraseQuery());
|
builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), settings.autoGenerateSynonymsPhraseQuery());
|
||||||
|
builder.field(FUZZY_PREFIX_LENGTH_FIELD.getPreferredName(), settings.fuzzyPrefixLength());
|
||||||
|
builder.field(FUZZY_MAX_EXPANSIONS_FIELD.getPreferredName(), settings.fuzzyMaxExpansions());
|
||||||
|
builder.field(FUZZY_TRANSPOSITIONS_FIELD.getPreferredName(), settings.fuzzyTranspositions());
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -478,6 +534,9 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
boolean analyzeWildcard = SimpleQueryStringBuilder.DEFAULT_ANALYZE_WILDCARD;
|
boolean analyzeWildcard = SimpleQueryStringBuilder.DEFAULT_ANALYZE_WILDCARD;
|
||||||
String quoteFieldSuffix = null;
|
String quoteFieldSuffix = null;
|
||||||
boolean autoGenerateSynonymsPhraseQuery = true;
|
boolean autoGenerateSynonymsPhraseQuery = true;
|
||||||
|
int fuzzyPrefixLenght = SimpleQueryStringBuilder.DEFAULT_FUZZY_PREFIX_LENGTH;
|
||||||
|
int fuzzyMaxExpansions = SimpleQueryStringBuilder.DEFAULT_FUZZY_MAX_EXPANSIONS;
|
||||||
|
boolean fuzzyTranspositions = SimpleQueryStringBuilder.DEFAULT_FUZZY_TRANSPOSITIONS;
|
||||||
|
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
@ -532,6 +591,12 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
// Ignore deprecated option
|
// Ignore deprecated option
|
||||||
} else if (GENERATE_SYNONYMS_PHRASE_QUERY.match(currentFieldName)) {
|
} else if (GENERATE_SYNONYMS_PHRASE_QUERY.match(currentFieldName)) {
|
||||||
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
|
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
|
||||||
|
} else if (FUZZY_PREFIX_LENGTH_FIELD.match(currentFieldName)) {
|
||||||
|
fuzzyPrefixLenght = parser.intValue();
|
||||||
|
} else if (FUZZY_MAX_EXPANSIONS_FIELD.match(currentFieldName)) {
|
||||||
|
fuzzyMaxExpansions = parser.intValue();
|
||||||
|
} else if (FUZZY_TRANSPOSITIONS_FIELD.match(currentFieldName)) {
|
||||||
|
fuzzyTranspositions = parser.booleanValue();
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "[" + SimpleQueryStringBuilder.NAME +
|
throw new ParsingException(parser.getTokenLocation(), "[" + SimpleQueryStringBuilder.NAME +
|
||||||
"] unsupported field [" + parser.currentName() + "]");
|
"] unsupported field [" + parser.currentName() + "]");
|
||||||
|
@ -558,6 +623,9 @@ public class SimpleQueryStringBuilder extends AbstractQueryBuilder<SimpleQuerySt
|
||||||
}
|
}
|
||||||
qb.analyzeWildcard(analyzeWildcard).boost(boost).quoteFieldSuffix(quoteFieldSuffix);
|
qb.analyzeWildcard(analyzeWildcard).boost(boost).quoteFieldSuffix(quoteFieldSuffix);
|
||||||
qb.autoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
qb.autoGenerateSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery);
|
||||||
|
qb.fuzzyPrefixLength(fuzzyPrefixLenght);
|
||||||
|
qb.fuzzyMaxExpansions(fuzzyMaxExpansions);
|
||||||
|
qb.fuzzyTranspositions(fuzzyTranspositions);
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ public class QueryStringQueryParser extends XQueryParser {
|
||||||
private int fuzzyMaxExpansions = FuzzyQuery.defaultMaxExpansions;
|
private int fuzzyMaxExpansions = FuzzyQuery.defaultMaxExpansions;
|
||||||
private MappedFieldType currentFieldType;
|
private MappedFieldType currentFieldType;
|
||||||
private MultiTermQuery.RewriteMethod fuzzyRewriteMethod;
|
private MultiTermQuery.RewriteMethod fuzzyRewriteMethod;
|
||||||
|
private boolean fuzzyTranspositions = FuzzyQuery.defaultTranspositions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param context The query shard context.
|
* @param context The query shard context.
|
||||||
|
@ -236,6 +237,14 @@ public class QueryStringQueryParser extends XQueryParser {
|
||||||
queryBuilder.setAutoGenerateSynonymsPhraseQuery(enable);
|
queryBuilder.setAutoGenerateSynonymsPhraseQuery(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fuzzyTranspositions Sets whether transpositions are supported in fuzzy queries.
|
||||||
|
* Defaults to {@link FuzzyQuery#defaultTranspositions}.
|
||||||
|
*/
|
||||||
|
public void setFuzzyTranspositions(boolean fuzzyTranspositions) {
|
||||||
|
this.fuzzyTranspositions = fuzzyTranspositions;
|
||||||
|
}
|
||||||
|
|
||||||
private Query applyBoost(Query q, Float boost) {
|
private Query applyBoost(Query q, Float boost) {
|
||||||
if (boost != null && boost != 1f) {
|
if (boost != null && boost != 1f) {
|
||||||
return new BoostQuery(q, boost);
|
return new BoostQuery(q, boost);
|
||||||
|
@ -442,7 +451,7 @@ public class QueryStringQueryParser extends XQueryParser {
|
||||||
Analyzer normalizer = forceAnalyzer == null ? queryBuilder.context.getSearchAnalyzer(currentFieldType) : forceAnalyzer;
|
Analyzer normalizer = forceAnalyzer == null ? queryBuilder.context.getSearchAnalyzer(currentFieldType) : forceAnalyzer;
|
||||||
BytesRef term = termStr == null ? null : normalizer.normalize(field, termStr);
|
BytesRef term = termStr == null ? null : normalizer.normalize(field, termStr);
|
||||||
return currentFieldType.fuzzyQuery(term, Fuzziness.fromEdits((int) minSimilarity),
|
return currentFieldType.fuzzyQuery(term, Fuzziness.fromEdits((int) minSimilarity),
|
||||||
getFuzzyPrefixLength(), fuzzyMaxExpansions, FuzzyQuery.defaultTranspositions);
|
getFuzzyPrefixLength(), fuzzyMaxExpansions, fuzzyTranspositions);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
if (lenient) {
|
if (lenient) {
|
||||||
return newLenientFieldQuery(field, e);
|
return newLenientFieldQuery(field, e);
|
||||||
|
@ -455,7 +464,7 @@ public class QueryStringQueryParser extends XQueryParser {
|
||||||
protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) {
|
protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) {
|
||||||
int numEdits = Fuzziness.build(minimumSimilarity).asDistance(term.text());
|
int numEdits = Fuzziness.build(minimumSimilarity).asDistance(term.text());
|
||||||
FuzzyQuery query = new FuzzyQuery(term, numEdits, prefixLength,
|
FuzzyQuery query = new FuzzyQuery(term, numEdits, prefixLength,
|
||||||
fuzzyMaxExpansions, FuzzyQuery.defaultTranspositions);
|
fuzzyMaxExpansions, fuzzyTranspositions);
|
||||||
QueryParsers.setRewriteMethod(query, fuzzyRewriteMethod);
|
QueryParsers.setRewriteMethod(query, fuzzyRewriteMethod);
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.apache.lucene.search.BooleanClause;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.BoostQuery;
|
import org.apache.lucene.search.BoostQuery;
|
||||||
import org.apache.lucene.search.DisjunctionMaxQuery;
|
import org.apache.lucene.search.DisjunctionMaxQuery;
|
||||||
import org.apache.lucene.search.FuzzyQuery;
|
|
||||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.PrefixQuery;
|
import org.apache.lucene.search.PrefixQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
@ -132,8 +131,8 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final BytesRef term = getAnalyzer(ft).normalize(fieldName, text);
|
final BytesRef term = getAnalyzer(ft).normalize(fieldName, text);
|
||||||
Query query = ft.fuzzyQuery(term, Fuzziness.fromEdits(fuzziness), FuzzyQuery.defaultPrefixLength,
|
Query query = ft.fuzzyQuery(term, Fuzziness.fromEdits(fuzziness), settings.fuzzyPrefixLength,
|
||||||
FuzzyQuery.defaultMaxExpansions, FuzzyQuery.defaultTranspositions);
|
settings.fuzzyMaxExpansions, settings.fuzzyTranspositions);
|
||||||
disjuncts.add(wrapWithBoost(query, entry.getValue()));
|
disjuncts.add(wrapWithBoost(query, entry.getValue()));
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
rethrowUnlessLenient(e);
|
rethrowUnlessLenient(e);
|
||||||
|
@ -293,6 +292,12 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
private String quoteFieldSuffix = null;
|
private String quoteFieldSuffix = null;
|
||||||
/** Whether phrase queries should be automatically generated for multi terms synonyms. */
|
/** Whether phrase queries should be automatically generated for multi terms synonyms. */
|
||||||
private boolean autoGenerateSynonymsPhraseQuery = true;
|
private boolean autoGenerateSynonymsPhraseQuery = true;
|
||||||
|
/** Prefix length in fuzzy queries.*/
|
||||||
|
private int fuzzyPrefixLength = SimpleQueryStringBuilder.DEFAULT_FUZZY_PREFIX_LENGTH;
|
||||||
|
/** The number of terms fuzzy queries will expand to.*/
|
||||||
|
private int fuzzyMaxExpansions = SimpleQueryStringBuilder.DEFAULT_FUZZY_MAX_EXPANSIONS;
|
||||||
|
/** Whether transpositions are supported in fuzzy queries.*/
|
||||||
|
private boolean fuzzyTranspositions = SimpleQueryStringBuilder.DEFAULT_FUZZY_TRANSPOSITIONS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates default {@link Settings} object (uses ROOT locale, does
|
* Generates default {@link Settings} object (uses ROOT locale, does
|
||||||
|
@ -306,6 +311,9 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
this.analyzeWildcard = other.analyzeWildcard;
|
this.analyzeWildcard = other.analyzeWildcard;
|
||||||
this.quoteFieldSuffix = other.quoteFieldSuffix;
|
this.quoteFieldSuffix = other.quoteFieldSuffix;
|
||||||
this.autoGenerateSynonymsPhraseQuery = other.autoGenerateSynonymsPhraseQuery;
|
this.autoGenerateSynonymsPhraseQuery = other.autoGenerateSynonymsPhraseQuery;
|
||||||
|
this.fuzzyPrefixLength = other.fuzzyPrefixLength;
|
||||||
|
this.fuzzyMaxExpansions = other.fuzzyMaxExpansions;
|
||||||
|
this.fuzzyTranspositions = other.fuzzyTranspositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Specifies whether to use lenient parsing, defaults to false. */
|
/** Specifies whether to use lenient parsing, defaults to false. */
|
||||||
|
@ -355,9 +363,34 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
return autoGenerateSynonymsPhraseQuery;
|
return autoGenerateSynonymsPhraseQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int fuzzyPrefixLength() {
|
||||||
|
return fuzzyPrefixLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fuzzyPrefixLength(int fuzzyPrefixLength) {
|
||||||
|
this.fuzzyPrefixLength = fuzzyPrefixLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fuzzyMaxExpansions() {
|
||||||
|
return fuzzyMaxExpansions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fuzzyMaxExpansions(int fuzzyMaxExpansions) {
|
||||||
|
this.fuzzyMaxExpansions = fuzzyMaxExpansions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fuzzyTranspositions() {
|
||||||
|
return fuzzyTranspositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fuzzyTranspositions(boolean fuzzyTranspositions) {
|
||||||
|
this.fuzzyTranspositions = fuzzyTranspositions;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(lenient, analyzeWildcard, quoteFieldSuffix, autoGenerateSynonymsPhraseQuery);
|
return Objects.hash(lenient, analyzeWildcard, quoteFieldSuffix, autoGenerateSynonymsPhraseQuery,
|
||||||
|
fuzzyPrefixLength, fuzzyMaxExpansions, fuzzyTranspositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -372,7 +405,10 @@ public class SimpleQueryStringQueryParser extends SimpleQueryParser {
|
||||||
return Objects.equals(lenient, other.lenient) &&
|
return Objects.equals(lenient, other.lenient) &&
|
||||||
Objects.equals(analyzeWildcard, other.analyzeWildcard) &&
|
Objects.equals(analyzeWildcard, other.analyzeWildcard) &&
|
||||||
Objects.equals(quoteFieldSuffix, other.quoteFieldSuffix) &&
|
Objects.equals(quoteFieldSuffix, other.quoteFieldSuffix) &&
|
||||||
Objects.equals(autoGenerateSynonymsPhraseQuery, other.autoGenerateSynonymsPhraseQuery);
|
Objects.equals(autoGenerateSynonymsPhraseQuery, other.autoGenerateSynonymsPhraseQuery) &&
|
||||||
|
Objects.equals(fuzzyPrefixLength, fuzzyPrefixLength) &&
|
||||||
|
Objects.equals(fuzzyMaxExpansions, fuzzyMaxExpansions) &&
|
||||||
|
Objects.equals(fuzzyTranspositions, fuzzyTranspositions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ 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.ParsingException;
|
||||||
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
|
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
|
||||||
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type;
|
import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type;
|
||||||
import org.elasticsearch.index.search.MatchQuery;
|
import org.elasticsearch.index.search.MatchQuery;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
@ -123,6 +124,9 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase<MultiMatc
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
query.autoGenerateSynonymsPhraseQuery(randomBoolean());
|
query.autoGenerateSynonymsPhraseQuery(randomBoolean());
|
||||||
}
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
query.fuzzyTranspositions(randomBoolean());
|
||||||
|
}
|
||||||
// test with fields with boost and patterns delegated to the tests further below
|
// test with fields with boost and patterns delegated to the tests further below
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
@ -241,6 +245,7 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase<MultiMatc
|
||||||
" \"lenient\" : false,\n" +
|
" \"lenient\" : false,\n" +
|
||||||
" \"zero_terms_query\" : \"NONE\",\n" +
|
" \"zero_terms_query\" : \"NONE\",\n" +
|
||||||
" \"auto_generate_synonyms_phrase_query\" : true,\n" +
|
" \"auto_generate_synonyms_phrase_query\" : true,\n" +
|
||||||
|
" \"fuzzy_transpositions\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -252,6 +257,7 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase<MultiMatc
|
||||||
assertEquals(json, 3, parsed.fields().size());
|
assertEquals(json, 3, parsed.fields().size());
|
||||||
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());
|
||||||
|
assertEquals(json, false, parsed.fuzzyTranspositions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -317,4 +323,19 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase<MultiMatc
|
||||||
query.analyzer(null);
|
query.analyzer(null);
|
||||||
query.toQuery(context); // no exception
|
query.toQuery(context); // no exception
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testToFuzzyQuery() throws Exception {
|
||||||
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
|
|
||||||
|
MultiMatchQueryBuilder qb = new MultiMatchQueryBuilder("text").field(STRING_FIELD_NAME);
|
||||||
|
qb.fuzziness(Fuzziness.TWO);
|
||||||
|
qb.prefixLength(2);
|
||||||
|
qb.maxExpansions(5);
|
||||||
|
qb.fuzzyTranspositions(false);
|
||||||
|
|
||||||
|
Query query = qb.toQuery(createShardContext());
|
||||||
|
FuzzyQuery expected = new FuzzyQuery(new Term(STRING_FIELD_NAME, "text"), 2, 2, 5, false);
|
||||||
|
|
||||||
|
assertEquals(expected, query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,9 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
queryStringQueryBuilder.autoGenerateSynonymsPhraseQuery(randomBoolean());
|
queryStringQueryBuilder.autoGenerateSynonymsPhraseQuery(randomBoolean());
|
||||||
}
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
queryStringQueryBuilder.fuzzyTranspositions(randomBoolean());
|
||||||
|
}
|
||||||
queryStringQueryBuilder.type(randomFrom(MultiMatchQueryBuilder.Type.values()));
|
queryStringQueryBuilder.type(randomFrom(MultiMatchQueryBuilder.Type.values()));
|
||||||
return queryStringQueryBuilder;
|
return queryStringQueryBuilder;
|
||||||
}
|
}
|
||||||
|
@ -864,6 +867,7 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
|
||||||
" \"phrase_slop\" : 0,\n" +
|
" \"phrase_slop\" : 0,\n" +
|
||||||
" \"escape\" : false,\n" +
|
" \"escape\" : false,\n" +
|
||||||
" \"auto_generate_synonyms_phrase_query\" : true,\n" +
|
" \"auto_generate_synonyms_phrase_query\" : true,\n" +
|
||||||
|
" \"fuzzy_transpositions\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -873,6 +877,7 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
|
||||||
|
|
||||||
assertEquals(json, "this AND that OR thus", parsed.queryString());
|
assertEquals(json, "this AND that OR thus", parsed.queryString());
|
||||||
assertEquals(json, "content", parsed.defaultField());
|
assertEquals(json, "content", parsed.defaultField());
|
||||||
|
assertEquals(json, false, parsed.fuzzyTranspositions());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExpandedTerms() throws Exception {
|
public void testExpandedTerms() throws Exception {
|
||||||
|
@ -1029,6 +1034,19 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
|
||||||
assertEquals(expectedQuery, query);
|
assertEquals(expectedQuery, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testToFuzzyQuery() throws Exception {
|
||||||
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
|
|
||||||
|
Query query = new QueryStringQueryBuilder("text~2")
|
||||||
|
.field(STRING_FIELD_NAME)
|
||||||
|
.fuzzyPrefixLength(2)
|
||||||
|
.fuzzyMaxExpansions(5)
|
||||||
|
.fuzzyTranspositions(false)
|
||||||
|
.toQuery(createShardContext());
|
||||||
|
FuzzyQuery expected = new FuzzyQuery(new Term(STRING_FIELD_NAME, "text"), 2, 2, 5, false);
|
||||||
|
assertEquals(expected, query);
|
||||||
|
}
|
||||||
|
|
||||||
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
|
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
|
||||||
Settings build = Settings.builder().put(oldIndexSettings)
|
Settings build = Settings.builder().put(oldIndexSettings)
|
||||||
.put(indexSettings)
|
.put(indexSettings)
|
||||||
|
|
|
@ -105,6 +105,15 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
result.autoGenerateSynonymsPhraseQuery(randomBoolean());
|
result.autoGenerateSynonymsPhraseQuery(randomBoolean());
|
||||||
}
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
result.fuzzyPrefixLength(randomIntBetween(0, 5));
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
result.fuzzyMaxExpansions(randomIntBetween(1, 5));
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
result.fuzzyTranspositions(randomBoolean());
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +135,18 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
||||||
|
|
||||||
assertEquals("Wrong default default lenient.", false, qb.lenient());
|
assertEquals("Wrong default default lenient.", false, qb.lenient());
|
||||||
assertEquals("Wrong default default lenient field.", false, SimpleQueryStringBuilder.DEFAULT_LENIENT);
|
assertEquals("Wrong default default lenient field.", false, SimpleQueryStringBuilder.DEFAULT_LENIENT);
|
||||||
|
|
||||||
|
assertEquals("Wrong default default fuzzy prefix length.", FuzzyQuery.defaultPrefixLength, qb.fuzzyPrefixLength());
|
||||||
|
assertEquals("Wrong default default fuzzy prefix length field.",
|
||||||
|
FuzzyQuery.defaultPrefixLength, SimpleQueryStringBuilder.DEFAULT_FUZZY_PREFIX_LENGTH);
|
||||||
|
|
||||||
|
assertEquals("Wrong default default fuzzy max expansions.", FuzzyQuery.defaultMaxExpansions, qb.fuzzyMaxExpansions());
|
||||||
|
assertEquals("Wrong default default fuzzy max expansions field.",
|
||||||
|
FuzzyQuery.defaultMaxExpansions, SimpleQueryStringBuilder.DEFAULT_FUZZY_MAX_EXPANSIONS);
|
||||||
|
|
||||||
|
assertEquals("Wrong default default fuzzy transpositions.", FuzzyQuery.defaultTranspositions, qb.fuzzyTranspositions());
|
||||||
|
assertEquals("Wrong default default fuzzy transpositions field.",
|
||||||
|
FuzzyQuery.defaultTranspositions, SimpleQueryStringBuilder.DEFAULT_FUZZY_TRANSPOSITIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultNullComplainFlags() {
|
public void testDefaultNullComplainFlags() {
|
||||||
|
@ -336,6 +357,9 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
||||||
" \"analyze_wildcard\" : false,\n" +
|
" \"analyze_wildcard\" : false,\n" +
|
||||||
" \"quote_field_suffix\" : \".quote\",\n" +
|
" \"quote_field_suffix\" : \".quote\",\n" +
|
||||||
" \"auto_generate_synonyms_phrase_query\" : true,\n" +
|
" \"auto_generate_synonyms_phrase_query\" : true,\n" +
|
||||||
|
" \"fuzzy_prefix_length\" : 1,\n" +
|
||||||
|
" \"fuzzy_max_expansions\" : 5,\n" +
|
||||||
|
" \"fuzzy_transpositions\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -347,6 +371,9 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
||||||
assertEquals(json, 1, parsed.fields().size());
|
assertEquals(json, 1, parsed.fields().size());
|
||||||
assertEquals(json, "snowball", parsed.analyzer());
|
assertEquals(json, "snowball", parsed.analyzer());
|
||||||
assertEquals(json, ".quote", parsed.quoteFieldSuffix());
|
assertEquals(json, ".quote", parsed.quoteFieldSuffix());
|
||||||
|
assertEquals(json, 1, parsed.fuzzyPrefixLength());
|
||||||
|
assertEquals(json, 5, parsed.fuzzyMaxExpansions());
|
||||||
|
assertEquals(json, false, parsed.fuzzyTranspositions());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMinimumShouldMatch() throws IOException {
|
public void testMinimumShouldMatch() throws IOException {
|
||||||
|
@ -567,6 +594,19 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testToFuzzyQuery() throws Exception {
|
||||||
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
|
|
||||||
|
Query query = new SimpleQueryStringBuilder("text~2")
|
||||||
|
.field(STRING_FIELD_NAME)
|
||||||
|
.fuzzyPrefixLength(2)
|
||||||
|
.fuzzyMaxExpansions(5)
|
||||||
|
.fuzzyTranspositions(false)
|
||||||
|
.toQuery(createShardContext());
|
||||||
|
FuzzyQuery expected = new FuzzyQuery(new Term(STRING_FIELD_NAME, "text"), 2, 2, 5, false);
|
||||||
|
assertEquals(expected, query);
|
||||||
|
}
|
||||||
|
|
||||||
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
|
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
|
||||||
Settings build = Settings.builder().put(oldIndexSettings)
|
Settings build = Settings.builder().put(oldIndexSettings)
|
||||||
.put(indexSettings)
|
.put(indexSettings)
|
||||||
|
|
|
@ -63,6 +63,10 @@ GET /_search
|
||||||
The maximum number of terms that the `fuzzy` query will expand to.
|
The maximum number of terms that the `fuzzy` query will expand to.
|
||||||
Defaults to `50`.
|
Defaults to `50`.
|
||||||
|
|
||||||
|
`transpositions`::
|
||||||
|
|
||||||
|
Whether fuzzy transpositions (`ab` -> `ba`) are supported.
|
||||||
|
Default is `false`.
|
||||||
|
|
||||||
WARNING: This query can be very heavy if `prefix_length` is set to `0` and if
|
WARNING: This query can be very heavy if `prefix_length` is set to `0` and if
|
||||||
`max_expansions` is set to a high number. It could result in every term in the
|
`max_expansions` is set to a high number. It could result in every term in the
|
||||||
|
|
|
@ -137,7 +137,8 @@ follows:
|
||||||
|
|
||||||
Also, accepts `analyzer`, `boost`, `operator`, `minimum_should_match`,
|
Also, accepts `analyzer`, `boost`, `operator`, `minimum_should_match`,
|
||||||
`fuzziness`, `lenient`, `prefix_length`, `max_expansions`, `rewrite`, `zero_terms_query`,
|
`fuzziness`, `lenient`, `prefix_length`, `max_expansions`, `rewrite`, `zero_terms_query`,
|
||||||
`cutoff_frequency` and `auto_generate_synonyms_phrase_query`, as explained in <<query-dsl-match-query, match query>>.
|
`cutoff_frequency`, `auto_generate_synonyms_phrase_query` and `fuzzy_transpositions`,
|
||||||
|
as explained in <<query-dsl-match-query, match query>>.
|
||||||
|
|
||||||
[IMPORTANT]
|
[IMPORTANT]
|
||||||
[[operator-min]]
|
[[operator-min]]
|
||||||
|
|
|
@ -83,6 +83,9 @@ to `AUTO`. See <<fuzziness>> for allowed settings.
|
||||||
|`fuzzy_prefix_length` |Set the prefix length for fuzzy queries. Default
|
|`fuzzy_prefix_length` |Set the prefix length for fuzzy queries. Default
|
||||||
is `0`.
|
is `0`.
|
||||||
|
|
||||||
|
|`fuzzy_transpositions` |Set to `false` to disable fuzzy transpositions (`ab` -> `ba`).
|
||||||
|
Default is `true`.
|
||||||
|
|
||||||
|`phrase_slop` |Sets the default slop for phrases. If zero, then exact
|
|`phrase_slop` |Sets the default slop for phrases. If zero, then exact
|
||||||
phrase matches are required. Default value is `0`.
|
phrase matches are required. Default value is `0`.
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,15 @@ Defaults to `true`.
|
||||||
|`all_fields` | deprecated[6.0.0, set `fields` to `*` instead]
|
|`all_fields` | deprecated[6.0.0, set `fields` to `*` instead]
|
||||||
Perform the query on all fields detected in the mapping that can
|
Perform the query on all fields detected in the mapping that can
|
||||||
be queried.
|
be queried.
|
||||||
|
|
||||||
|
|`fuzzy_prefix_length` |Set the prefix length for fuzzy queries. Default
|
||||||
|
is `0`.
|
||||||
|
|
||||||
|
|`fuzzy_max_expansions` |Controls the number of terms fuzzy queries will
|
||||||
|
expand to. Defaults to `50`
|
||||||
|
|
||||||
|
|`fuzzy_transpositions` |Set to `false` to disable fuzzy transpositions (`ab` -> `ba`).
|
||||||
|
Default is `true`.
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
|
|
Loading…
Reference in New Issue