|
@@ -26,6 +26,7 @@ import org.apache.lucene.search.BoostQuery;
|
|
|
import org.apache.lucene.search.FuzzyQuery;
|
|
|
import org.apache.lucene.search.Query;
|
|
|
import org.apache.lucene.util.automaton.Operations;
|
|
|
+import org.elasticsearch.Version;
|
|
|
import org.elasticsearch.common.ParseField;
|
|
|
import org.elasticsearch.common.ParsingException;
|
|
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@@ -59,6 +60,8 @@ import java.util.TreeMap;
|
|
|
public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQueryBuilder> {
|
|
|
public static final String NAME = "query_string";
|
|
|
|
|
|
+ public static final Version V_5_1_0_UNRELEASED = Version.fromId(5010099);
|
|
|
+
|
|
|
public static final boolean DEFAULT_AUTO_GENERATE_PHRASE_QUERIES = false;
|
|
|
public static final int DEFAULT_MAX_DETERMINED_STATES = Operations.DEFAULT_MAX_DETERMINIZED_STATES;
|
|
|
public static final boolean DEFAULT_LOWERCASE_EXPANDED_TERMS = true;
|
|
@@ -72,6 +75,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
public static final Fuzziness DEFAULT_FUZZINESS = Fuzziness.AUTO;
|
|
|
public static final Operator DEFAULT_OPERATOR = Operator.OR;
|
|
|
public static final Locale DEFAULT_LOCALE = Locale.ROOT;
|
|
|
+ public static final boolean DEFAULT_SPLIT_ON_WHITESPACE = true;
|
|
|
|
|
|
private static final ParseField QUERY_FIELD = new ParseField("query");
|
|
|
private static final ParseField FIELDS_FIELD = new ParseField("fields");
|
|
@@ -98,6 +102,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
private static final ParseField LENIENT_FIELD = new ParseField("lenient");
|
|
|
private static final ParseField LOCALE_FIELD = new ParseField("locale");
|
|
|
private static final ParseField TIME_ZONE_FIELD = new ParseField("time_zone");
|
|
|
+ private static final ParseField SPLIT_ON_WHITESPACE = new ParseField("split_on_whitespace");
|
|
|
|
|
|
|
|
|
private final String queryString;
|
|
@@ -159,6 +164,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
/** To limit effort spent determinizing regexp queries. */
|
|
|
private int maxDeterminizedStates = DEFAULT_MAX_DETERMINED_STATES;
|
|
|
|
|
|
+ private boolean splitOnWhitespace = DEFAULT_SPLIT_ON_WHITESPACE;
|
|
|
+
|
|
|
public QueryStringQueryBuilder(String queryString) {
|
|
|
if (queryString == null) {
|
|
|
throw new IllegalArgumentException("query text missing");
|
|
@@ -200,6 +207,11 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
timeZone = in.readOptionalTimeZone();
|
|
|
escape = in.readBoolean();
|
|
|
maxDeterminizedStates = in.readVInt();
|
|
|
+ if (in.getVersion().onOrAfter(V_5_1_0_UNRELEASED)) {
|
|
|
+ splitOnWhitespace = in.readBoolean();
|
|
|
+ } else {
|
|
|
+ splitOnWhitespace = DEFAULT_SPLIT_ON_WHITESPACE;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -234,6 +246,9 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
out.writeOptionalTimeZone(timeZone);
|
|
|
out.writeBoolean(this.escape);
|
|
|
out.writeVInt(this.maxDeterminizedStates);
|
|
|
+ if (out.getVersion().onOrAfter(V_5_1_0_UNRELEASED)) {
|
|
|
+ out.writeBoolean(this.splitOnWhitespace);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public String queryString() {
|
|
@@ -570,6 +585,19 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
return this.escape;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Whether query text should be split on whitespace prior to analysis.
|
|
|
+ * Default is <code>{@value #DEFAULT_SPLIT_ON_WHITESPACE}</code>.
|
|
|
+ */
|
|
|
+ public QueryStringQueryBuilder splitOnWhitespace(boolean value) {
|
|
|
+ this.splitOnWhitespace = value;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean splitOnWhitespace() {
|
|
|
+ return splitOnWhitespace;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
|
|
builder.startObject(NAME);
|
|
@@ -626,6 +654,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
builder.field(TIME_ZONE_FIELD.getPreferredName(), this.timeZone.getID());
|
|
|
}
|
|
|
builder.field(ESCAPE_FIELD.getPreferredName(), this.escape);
|
|
|
+ builder.field(SPLIT_ON_WHITESPACE.getPreferredName(), this.splitOnWhitespace);
|
|
|
printBoostAndQueryName(builder);
|
|
|
builder.endObject();
|
|
|
}
|
|
@@ -661,6 +690,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
Fuzziness fuzziness = QueryStringQueryBuilder.DEFAULT_FUZZINESS;
|
|
|
String fuzzyRewrite = null;
|
|
|
String rewrite = null;
|
|
|
+ boolean splitOnWhitespace = DEFAULT_SPLIT_ON_WHITESPACE;
|
|
|
Map<String, Float> fieldsAndWeights = new HashMap<>();
|
|
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
|
|
if (token == XContentParser.Token.FIELD_NAME) {
|
|
@@ -750,6 +780,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
}
|
|
|
} else if (parseContext.getParseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
|
|
|
queryName = parser.text();
|
|
|
+ } else if (parseContext.getParseFieldMatcher().match(currentFieldName, SPLIT_ON_WHITESPACE)) {
|
|
|
+ splitOnWhitespace = parser.booleanValue();
|
|
|
} else {
|
|
|
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
|
|
|
"] query does not support [" + currentFieldName + "]");
|
|
@@ -791,6 +823,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
queryStringQuery.locale(locale);
|
|
|
queryStringQuery.boost(boost);
|
|
|
queryStringQuery.queryName(queryName);
|
|
|
+ queryStringQuery.splitOnWhitespace(splitOnWhitespace);
|
|
|
return Optional.of(queryStringQuery);
|
|
|
}
|
|
|
|
|
@@ -827,7 +860,8 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
timeZone == null ? other.timeZone == null : other.timeZone != null &&
|
|
|
Objects.equals(timeZone.getID(), other.timeZone.getID()) &&
|
|
|
Objects.equals(escape, other.escape) &&
|
|
|
- Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates);
|
|
|
+ Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates) &&
|
|
|
+ Objects.equals(splitOnWhitespace, other.splitOnWhitespace);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -836,7 +870,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
quoteFieldSuffix, autoGeneratePhraseQueries, allowLeadingWildcard, lowercaseExpandedTerms,
|
|
|
enablePositionIncrements, analyzeWildcard, locale.toLanguageTag(), fuzziness, fuzzyPrefixLength,
|
|
|
fuzzyMaxExpansions, fuzzyRewrite, phraseSlop, useDisMax, tieBreaker, rewrite, minimumShouldMatch, lenient,
|
|
|
- timeZone == null ? 0 : timeZone.getID(), escape, maxDeterminizedStates);
|
|
|
+ timeZone == null ? 0 : timeZone.getID(), escape, maxDeterminizedStates, splitOnWhitespace);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -904,6 +938,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|
|
qpSettings.lenient(lenient == null ? context.queryStringLenient() : lenient);
|
|
|
qpSettings.timeZone(timeZone);
|
|
|
qpSettings.maxDeterminizedStates(maxDeterminizedStates);
|
|
|
+ qpSettings.splitOnWhitespace(splitOnWhitespace);
|
|
|
|
|
|
MapperQueryParser queryParser = context.queryParser(qpSettings);
|
|
|
Query query;
|