Cut multi_match query to registerQuery
This commit is contained in:
parent
f61c29e67b
commit
1afc9b7e56
|
@ -564,8 +564,7 @@ public class MatchQueryBuilder extends AbstractQueryBuilder<MatchQueryBuilder> {
|
||||||
} else if ("phrase_prefix".equals(tStr) || ("phrasePrefix".equals(tStr))) {
|
} else if ("phrase_prefix".equals(tStr) || ("phrasePrefix".equals(tStr))) {
|
||||||
type = MatchQuery.Type.PHRASE_PREFIX;
|
type = MatchQuery.Type.PHRASE_PREFIX;
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(),
|
throw new ParsingException(parser.getTokenLocation(), "[" + NAME + "] query does not support type " + tStr);
|
||||||
"[" + MatchQueryBuilder.NAME + "] query does not support type " + tStr);
|
|
||||||
}
|
}
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZER_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZER_FIELD)) {
|
||||||
analyzer = parser.text();
|
analyzer = parser.text();
|
||||||
|
@ -605,11 +604,11 @@ public class MatchQueryBuilder extends AbstractQueryBuilder<MatchQueryBuilder> {
|
||||||
queryName = parser.text();
|
queryName = parser.text();
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(),
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
"[" + MatchQueryBuilder.NAME + "] query does not support [" + currentFieldName + "]");
|
"[" + NAME + "] query does not support [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(),
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
"[" + MatchQueryBuilder.NAME + "] unknown token [" + token + "] after [" + currentFieldName + "]");
|
"[" + NAME + "] unknown token [" + token + "] after [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.ParseFieldMatcher;
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
@ -31,12 +32,14 @@ import org.elasticsearch.common.io.stream.Writeable;
|
||||||
import org.elasticsearch.common.regex.Regex;
|
import org.elasticsearch.common.regex.Regex;
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.query.support.QueryParsers;
|
import org.elasticsearch.index.query.support.QueryParsers;
|
||||||
import org.elasticsearch.index.search.MatchQuery;
|
import org.elasticsearch.index.search.MatchQuery;
|
||||||
import org.elasticsearch.index.search.MultiMatchQuery;
|
import org.elasticsearch.index.search.MultiMatchQuery;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -46,7 +49,6 @@ import java.util.TreeMap;
|
||||||
* Same as {@link MatchQueryBuilder} but supports multiple fields.
|
* Same as {@link MatchQueryBuilder} but supports multiple fields.
|
||||||
*/
|
*/
|
||||||
public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQueryBuilder> {
|
public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQueryBuilder> {
|
||||||
|
|
||||||
public static final String NAME = "multi_match";
|
public static final String NAME = "multi_match";
|
||||||
|
|
||||||
public static final MultiMatchQueryBuilder.Type DEFAULT_TYPE = MultiMatchQueryBuilder.Type.BEST_FIELDS;
|
public static final MultiMatchQueryBuilder.Type DEFAULT_TYPE = MultiMatchQueryBuilder.Type.BEST_FIELDS;
|
||||||
|
@ -57,6 +59,23 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
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 ParseField QUERY_NAME_FIELD = new ParseField(NAME);
|
||||||
|
private static final ParseField SLOP_FIELD = new ParseField("slop", "phrase_slop");
|
||||||
|
private static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
|
||||||
|
private static final ParseField LENIENT_FIELD = new ParseField("lenient");
|
||||||
|
private static final ParseField CUTOFF_FREQUENCY_FIELD = new ParseField("cutoff_frequency");
|
||||||
|
private static final ParseField TIE_BREAKER_FIELD = new ParseField("tie_breaker");
|
||||||
|
private static final ParseField USE_DIS_MAX_FIELD = new ParseField("use_dis_max");
|
||||||
|
private static final ParseField FUZZY_REWRITE_FIELD = new ParseField("fuzzy_rewrite");
|
||||||
|
private static final ParseField MINIMUM_SHOULD_MATCH_FIELD = new ParseField("minimum_should_match");
|
||||||
|
private static final ParseField OPERATOR_FIELD = new ParseField("operator");
|
||||||
|
private static final ParseField MAX_EXPANSIONS_FIELD = new ParseField("max_expansions");
|
||||||
|
private static final ParseField PREFIX_LENGTH_FIELD = new ParseField("prefix_length");
|
||||||
|
private static final ParseField ANALYZER_FIELD = new ParseField("analyzer");
|
||||||
|
private static final ParseField TYPE_FIELD = new ParseField("type");
|
||||||
|
private static final ParseField QUERY_FIELD = new ParseField("query");
|
||||||
|
private static final ParseField FIELDS_FIELD = new ParseField("fields");
|
||||||
|
|
||||||
private final Object value;
|
private final Object value;
|
||||||
private final Map<String, Float> fieldsBoosts;
|
private final Map<String, Float> fieldsBoosts;
|
||||||
private MultiMatchQueryBuilder.Type type = DEFAULT_TYPE;
|
private MultiMatchQueryBuilder.Type type = DEFAULT_TYPE;
|
||||||
|
@ -74,7 +93,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;
|
||||||
|
|
||||||
static final MultiMatchQueryBuilder PROTOTYPE = new MultiMatchQueryBuilder("");
|
public static final MultiMatchQueryBuilder PROTOTYPE = new MultiMatchQueryBuilder("");
|
||||||
|
|
||||||
public enum Type implements Writeable<Type> {
|
public enum Type implements Writeable<Type> {
|
||||||
|
|
||||||
|
@ -457,44 +476,182 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
|
||||||
@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);
|
||||||
builder.field(MultiMatchQueryParser.QUERY_FIELD.getPreferredName(), value);
|
builder.field(QUERY_FIELD.getPreferredName(), value);
|
||||||
builder.startArray(MultiMatchQueryParser.FIELDS_FIELD.getPreferredName());
|
builder.startArray(FIELDS_FIELD.getPreferredName());
|
||||||
for (Map.Entry<String, Float> fieldEntry : this.fieldsBoosts.entrySet()) {
|
for (Map.Entry<String, Float> fieldEntry : this.fieldsBoosts.entrySet()) {
|
||||||
builder.value(fieldEntry.getKey() + "^" + fieldEntry.getValue());
|
builder.value(fieldEntry.getKey() + "^" + fieldEntry.getValue());
|
||||||
}
|
}
|
||||||
builder.endArray();
|
builder.endArray();
|
||||||
builder.field(MultiMatchQueryParser.TYPE_FIELD.getPreferredName(), type.toString().toLowerCase(Locale.ENGLISH));
|
builder.field(TYPE_FIELD.getPreferredName(), type.toString().toLowerCase(Locale.ENGLISH));
|
||||||
builder.field(MultiMatchQueryParser.OPERATOR_FIELD.getPreferredName(), operator.toString());
|
builder.field(OPERATOR_FIELD.getPreferredName(), operator.toString());
|
||||||
if (analyzer != null) {
|
if (analyzer != null) {
|
||||||
builder.field(MultiMatchQueryParser.ANALYZER_FIELD.getPreferredName(), analyzer);
|
builder.field(ANALYZER_FIELD.getPreferredName(), analyzer);
|
||||||
}
|
}
|
||||||
builder.field(MultiMatchQueryParser.SLOP_FIELD.getPreferredName(), slop);
|
builder.field(SLOP_FIELD.getPreferredName(), slop);
|
||||||
if (fuzziness != null) {
|
if (fuzziness != null) {
|
||||||
fuzziness.toXContent(builder, params);
|
fuzziness.toXContent(builder, params);
|
||||||
}
|
}
|
||||||
builder.field(MultiMatchQueryParser.PREFIX_LENGTH_FIELD.getPreferredName(), prefixLength);
|
builder.field(PREFIX_LENGTH_FIELD.getPreferredName(), prefixLength);
|
||||||
builder.field(MultiMatchQueryParser.MAX_EXPANSIONS_FIELD.getPreferredName(), maxExpansions);
|
builder.field(MAX_EXPANSIONS_FIELD.getPreferredName(), maxExpansions);
|
||||||
if (minimumShouldMatch != null) {
|
if (minimumShouldMatch != null) {
|
||||||
builder.field(MultiMatchQueryParser.MINIMUM_SHOULD_MATCH_FIELD.getPreferredName(), minimumShouldMatch);
|
builder.field(MINIMUM_SHOULD_MATCH_FIELD.getPreferredName(), minimumShouldMatch);
|
||||||
}
|
}
|
||||||
if (fuzzyRewrite != null) {
|
if (fuzzyRewrite != null) {
|
||||||
builder.field(MultiMatchQueryParser.FUZZY_REWRITE_FIELD.getPreferredName(), fuzzyRewrite);
|
builder.field(FUZZY_REWRITE_FIELD.getPreferredName(), fuzzyRewrite);
|
||||||
}
|
}
|
||||||
if (useDisMax != null) {
|
if (useDisMax != null) {
|
||||||
builder.field(MultiMatchQueryParser.USE_DIS_MAX_FIELD.getPreferredName(), useDisMax);
|
builder.field(USE_DIS_MAX_FIELD.getPreferredName(), useDisMax);
|
||||||
}
|
}
|
||||||
if (tieBreaker != null) {
|
if (tieBreaker != null) {
|
||||||
builder.field(MultiMatchQueryParser.TIE_BREAKER_FIELD.getPreferredName(), tieBreaker);
|
builder.field(TIE_BREAKER_FIELD.getPreferredName(), tieBreaker);
|
||||||
}
|
}
|
||||||
builder.field(MultiMatchQueryParser.LENIENT_FIELD.getPreferredName(), lenient);
|
builder.field(LENIENT_FIELD.getPreferredName(), lenient);
|
||||||
if (cutoffFrequency != null) {
|
if (cutoffFrequency != null) {
|
||||||
builder.field(MultiMatchQueryParser.CUTOFF_FREQUENCY_FIELD.getPreferredName(), cutoffFrequency);
|
builder.field(CUTOFF_FREQUENCY_FIELD.getPreferredName(), cutoffFrequency);
|
||||||
}
|
}
|
||||||
builder.field(MultiMatchQueryParser.ZERO_TERMS_QUERY_FIELD.getPreferredName(), zeroTermsQuery.toString());
|
builder.field(ZERO_TERMS_QUERY_FIELD.getPreferredName(), zeroTermsQuery.toString());
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MultiMatchQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
|
||||||
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
|
Object value = null;
|
||||||
|
Map<String, Float> fieldsBoosts = new HashMap<>();
|
||||||
|
MultiMatchQueryBuilder.Type type = DEFAULT_TYPE;
|
||||||
|
String analyzer = null;
|
||||||
|
int slop = DEFAULT_PHRASE_SLOP;
|
||||||
|
Fuzziness fuzziness = null;
|
||||||
|
int prefixLength = DEFAULT_PREFIX_LENGTH;
|
||||||
|
int maxExpansions = DEFAULT_MAX_EXPANSIONS;
|
||||||
|
Operator operator = DEFAULT_OPERATOR;
|
||||||
|
String minimumShouldMatch = null;
|
||||||
|
String fuzzyRewrite = null;
|
||||||
|
Boolean useDisMax = null;
|
||||||
|
Float tieBreaker = null;
|
||||||
|
Float cutoffFrequency = null;
|
||||||
|
boolean lenient = DEFAULT_LENIENCY;
|
||||||
|
MatchQuery.ZeroTermsQuery zeroTermsQuery = DEFAULT_ZERO_TERMS_QUERY;
|
||||||
|
|
||||||
|
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
|
||||||
|
String queryName = null;
|
||||||
|
|
||||||
|
XContentParser.Token token;
|
||||||
|
String currentFieldName = null;
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
currentFieldName = parser.currentName();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
|
||||||
|
if (token == XContentParser.Token.START_ARRAY) {
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
|
parseFieldAndBoost(parser, fieldsBoosts);
|
||||||
|
}
|
||||||
|
} else if (token.isValue()) {
|
||||||
|
parseFieldAndBoost(parser, fieldsBoosts);
|
||||||
|
} else {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"[" + NAME + "] query does not support [" + currentFieldName + "]");
|
||||||
|
}
|
||||||
|
} else if (token.isValue()) {
|
||||||
|
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
|
||||||
|
value = parser.objectText();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TYPE_FIELD)) {
|
||||||
|
type = MultiMatchQueryBuilder.Type.parse(parser.text(), parseContext.parseFieldMatcher());
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZER_FIELD)) {
|
||||||
|
analyzer = parser.text();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
|
||||||
|
boost = parser.floatValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, SLOP_FIELD)) {
|
||||||
|
slop = parser.intValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Fuzziness.FIELD)) {
|
||||||
|
fuzziness = Fuzziness.parse(parser);
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PREFIX_LENGTH_FIELD)) {
|
||||||
|
prefixLength = parser.intValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_EXPANSIONS_FIELD)) {
|
||||||
|
maxExpansions = parser.intValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, OPERATOR_FIELD)) {
|
||||||
|
operator = Operator.fromString(parser.text());
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MINIMUM_SHOULD_MATCH_FIELD)) {
|
||||||
|
minimumShouldMatch = parser.textOrNull();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_REWRITE_FIELD)) {
|
||||||
|
fuzzyRewrite = parser.textOrNull();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, USE_DIS_MAX_FIELD)) {
|
||||||
|
useDisMax = parser.booleanValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIE_BREAKER_FIELD)) {
|
||||||
|
tieBreaker = parser.floatValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, CUTOFF_FREQUENCY_FIELD)) {
|
||||||
|
cutoffFrequency = parser.floatValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LENIENT_FIELD)) {
|
||||||
|
lenient = parser.booleanValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ZERO_TERMS_QUERY_FIELD)) {
|
||||||
|
String zeroTermsDocs = parser.text();
|
||||||
|
if ("none".equalsIgnoreCase(zeroTermsDocs)) {
|
||||||
|
zeroTermsQuery = MatchQuery.ZeroTermsQuery.NONE;
|
||||||
|
} else if ("all".equalsIgnoreCase(zeroTermsDocs)) {
|
||||||
|
zeroTermsQuery = MatchQuery.ZeroTermsQuery.ALL;
|
||||||
|
} else {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "Unsupported zero_terms_docs value [" + zeroTermsDocs + "]");
|
||||||
|
}
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
|
||||||
|
queryName = parser.text();
|
||||||
|
} else {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"[" + NAME + "] query does not support [" + currentFieldName + "]");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"[" + NAME + "] unknown token [" + token + "] after [" + currentFieldName + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "No text specified for multi_match query");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldsBoosts.isEmpty()) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "No fields specified for multi_match query");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MultiMatchQueryBuilder(value)
|
||||||
|
.fields(fieldsBoosts)
|
||||||
|
.type(type)
|
||||||
|
.analyzer(analyzer)
|
||||||
|
.cutoffFrequency(cutoffFrequency)
|
||||||
|
.fuzziness(fuzziness)
|
||||||
|
.fuzzyRewrite(fuzzyRewrite)
|
||||||
|
.useDisMax(useDisMax)
|
||||||
|
.lenient(lenient)
|
||||||
|
.maxExpansions(maxExpansions)
|
||||||
|
.minimumShouldMatch(minimumShouldMatch)
|
||||||
|
.operator(operator)
|
||||||
|
.prefixLength(prefixLength)
|
||||||
|
.slop(slop)
|
||||||
|
.tieBreaker(tieBreaker)
|
||||||
|
.zeroTermsQuery(zeroTermsQuery)
|
||||||
|
.boost(boost)
|
||||||
|
.queryName(queryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseFieldAndBoost(XContentParser parser, Map<String, Float> fieldsBoosts) throws IOException {
|
||||||
|
String fField = null;
|
||||||
|
Float fBoost = AbstractQueryBuilder.DEFAULT_BOOST;
|
||||||
|
char[] fieldText = parser.textCharacters();
|
||||||
|
int end = parser.textOffset() + parser.textLength();
|
||||||
|
for (int i = parser.textOffset(); i < end; i++) {
|
||||||
|
if (fieldText[i] == '^') {
|
||||||
|
int relativeLocation = i - parser.textOffset();
|
||||||
|
fField = new String(fieldText, parser.textOffset(), relativeLocation);
|
||||||
|
fBoost = Float.parseFloat(new String(fieldText, i + 1, parser.textLength() - relativeLocation - 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fField == null) {
|
||||||
|
fField = parser.text();
|
||||||
|
}
|
||||||
|
fieldsBoosts.put(fField, fBoost);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWriteableName() {
|
public String getWriteableName() {
|
||||||
return NAME;
|
return NAME;
|
||||||
|
|
|
@ -1,197 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch licenses this file to you under
|
|
||||||
* the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.ParseField;
|
|
||||||
import org.elasticsearch.common.ParsingException;
|
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.index.search.MatchQuery;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as {@link MatchQueryBuilder} but has support for multiple fields.
|
|
||||||
*/
|
|
||||||
public class MultiMatchQueryParser implements QueryParser<MultiMatchQueryBuilder> {
|
|
||||||
|
|
||||||
public static final ParseField QUERY_NAME_FIELD = new ParseField(MultiMatchQueryBuilder.NAME);
|
|
||||||
public static final ParseField SLOP_FIELD = new ParseField("slop", "phrase_slop");
|
|
||||||
public static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
|
|
||||||
public static final ParseField LENIENT_FIELD = new ParseField("lenient");
|
|
||||||
public static final ParseField CUTOFF_FREQUENCY_FIELD = new ParseField("cutoff_frequency");
|
|
||||||
public static final ParseField TIE_BREAKER_FIELD = new ParseField("tie_breaker");
|
|
||||||
public static final ParseField USE_DIS_MAX_FIELD = new ParseField("use_dis_max");
|
|
||||||
public static final ParseField FUZZY_REWRITE_FIELD = new ParseField("fuzzy_rewrite");
|
|
||||||
public static final ParseField MINIMUM_SHOULD_MATCH_FIELD = new ParseField("minimum_should_match");
|
|
||||||
public static final ParseField OPERATOR_FIELD = new ParseField("operator");
|
|
||||||
public static final ParseField MAX_EXPANSIONS_FIELD = new ParseField("max_expansions");
|
|
||||||
public static final ParseField PREFIX_LENGTH_FIELD = new ParseField("prefix_length");
|
|
||||||
public static final ParseField ANALYZER_FIELD = new ParseField("analyzer");
|
|
||||||
public static final ParseField TYPE_FIELD = new ParseField("type");
|
|
||||||
public static final ParseField QUERY_FIELD = new ParseField("query");
|
|
||||||
public static final ParseField FIELDS_FIELD = new ParseField("fields");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MultiMatchQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
|
|
||||||
XContentParser parser = parseContext.parser();
|
|
||||||
|
|
||||||
Object value = null;
|
|
||||||
Map<String, Float> fieldsBoosts = new HashMap<>();
|
|
||||||
MultiMatchQueryBuilder.Type type = MultiMatchQueryBuilder.DEFAULT_TYPE;
|
|
||||||
String analyzer = null;
|
|
||||||
int slop = MultiMatchQueryBuilder.DEFAULT_PHRASE_SLOP;
|
|
||||||
Fuzziness fuzziness = null;
|
|
||||||
int prefixLength = MultiMatchQueryBuilder.DEFAULT_PREFIX_LENGTH;
|
|
||||||
int maxExpansions = MultiMatchQueryBuilder.DEFAULT_MAX_EXPANSIONS;
|
|
||||||
Operator operator = MultiMatchQueryBuilder.DEFAULT_OPERATOR;
|
|
||||||
String minimumShouldMatch = null;
|
|
||||||
String fuzzyRewrite = null;
|
|
||||||
Boolean useDisMax = null;
|
|
||||||
Float tieBreaker = null;
|
|
||||||
Float cutoffFrequency = null;
|
|
||||||
boolean lenient = MultiMatchQueryBuilder.DEFAULT_LENIENCY;
|
|
||||||
MatchQuery.ZeroTermsQuery zeroTermsQuery = MultiMatchQueryBuilder.DEFAULT_ZERO_TERMS_QUERY;
|
|
||||||
|
|
||||||
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
|
|
||||||
String queryName = null;
|
|
||||||
|
|
||||||
XContentParser.Token token;
|
|
||||||
String currentFieldName = null;
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
|
||||||
currentFieldName = parser.currentName();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
|
|
||||||
if (token == XContentParser.Token.START_ARRAY) {
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
|
||||||
parseFieldAndBoost(parser, fieldsBoosts);
|
|
||||||
}
|
|
||||||
} else if (token.isValue()) {
|
|
||||||
parseFieldAndBoost(parser, fieldsBoosts);
|
|
||||||
} else {
|
|
||||||
throw new ParsingException(parser.getTokenLocation(), "[" + MultiMatchQueryBuilder.NAME +
|
|
||||||
"] query does not support [" + currentFieldName + "]");
|
|
||||||
}
|
|
||||||
} else if (token.isValue()) {
|
|
||||||
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
|
|
||||||
value = parser.objectText();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TYPE_FIELD)) {
|
|
||||||
type = MultiMatchQueryBuilder.Type.parse(parser.text(), parseContext.parseFieldMatcher());
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZER_FIELD)) {
|
|
||||||
analyzer = parser.text();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
|
|
||||||
boost = parser.floatValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, SLOP_FIELD)) {
|
|
||||||
slop = parser.intValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Fuzziness.FIELD)) {
|
|
||||||
fuzziness = Fuzziness.parse(parser);
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PREFIX_LENGTH_FIELD)) {
|
|
||||||
prefixLength = parser.intValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_EXPANSIONS_FIELD)) {
|
|
||||||
maxExpansions = parser.intValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, OPERATOR_FIELD)) {
|
|
||||||
operator = Operator.fromString(parser.text());
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MINIMUM_SHOULD_MATCH_FIELD)) {
|
|
||||||
minimumShouldMatch = parser.textOrNull();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_REWRITE_FIELD)) {
|
|
||||||
fuzzyRewrite = parser.textOrNull();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, USE_DIS_MAX_FIELD)) {
|
|
||||||
useDisMax = parser.booleanValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIE_BREAKER_FIELD)) {
|
|
||||||
tieBreaker = parser.floatValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, CUTOFF_FREQUENCY_FIELD)) {
|
|
||||||
cutoffFrequency = parser.floatValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LENIENT_FIELD)) {
|
|
||||||
lenient = parser.booleanValue();
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ZERO_TERMS_QUERY_FIELD)) {
|
|
||||||
String zeroTermsDocs = parser.text();
|
|
||||||
if ("none".equalsIgnoreCase(zeroTermsDocs)) {
|
|
||||||
zeroTermsQuery = MatchQuery.ZeroTermsQuery.NONE;
|
|
||||||
} else if ("all".equalsIgnoreCase(zeroTermsDocs)) {
|
|
||||||
zeroTermsQuery = MatchQuery.ZeroTermsQuery.ALL;
|
|
||||||
} else {
|
|
||||||
throw new ParsingException(parser.getTokenLocation(), "Unsupported zero_terms_docs value [" + zeroTermsDocs + "]");
|
|
||||||
}
|
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
|
|
||||||
queryName = parser.text();
|
|
||||||
} else {
|
|
||||||
throw new ParsingException(parser.getTokenLocation(), "[" + MultiMatchQueryBuilder.NAME +
|
|
||||||
"] query does not support [" + currentFieldName + "]");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new ParsingException(parser.getTokenLocation(), "[" + MultiMatchQueryBuilder.NAME +
|
|
||||||
"] unknown token [" + token + "] after [" + currentFieldName + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
throw new ParsingException(parser.getTokenLocation(), "No text specified for multi_match query");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldsBoosts.isEmpty()) {
|
|
||||||
throw new ParsingException(parser.getTokenLocation(), "No fields specified for multi_match query");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MultiMatchQueryBuilder(value)
|
|
||||||
.fields(fieldsBoosts)
|
|
||||||
.type(type)
|
|
||||||
.analyzer(analyzer)
|
|
||||||
.cutoffFrequency(cutoffFrequency)
|
|
||||||
.fuzziness(fuzziness)
|
|
||||||
.fuzzyRewrite(fuzzyRewrite)
|
|
||||||
.useDisMax(useDisMax)
|
|
||||||
.lenient(lenient)
|
|
||||||
.maxExpansions(maxExpansions)
|
|
||||||
.minimumShouldMatch(minimumShouldMatch)
|
|
||||||
.operator(operator)
|
|
||||||
.prefixLength(prefixLength)
|
|
||||||
.slop(slop)
|
|
||||||
.tieBreaker(tieBreaker)
|
|
||||||
.zeroTermsQuery(zeroTermsQuery)
|
|
||||||
.boost(boost)
|
|
||||||
.queryName(queryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseFieldAndBoost(XContentParser parser, Map<String, Float> fieldsBoosts) throws IOException {
|
|
||||||
String fField = null;
|
|
||||||
Float fBoost = AbstractQueryBuilder.DEFAULT_BOOST;
|
|
||||||
char[] fieldText = parser.textCharacters();
|
|
||||||
int end = parser.textOffset() + parser.textLength();
|
|
||||||
for (int i = parser.textOffset(); i < end; i++) {
|
|
||||||
if (fieldText[i] == '^') {
|
|
||||||
int relativeLocation = i - parser.textOffset();
|
|
||||||
fField = new String(fieldText, parser.textOffset(), relativeLocation);
|
|
||||||
fBoost = Float.parseFloat(new String(fieldText, i + 1, parser.textLength() - relativeLocation - 1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fField == null) {
|
|
||||||
fField = parser.text();
|
|
||||||
}
|
|
||||||
fieldsBoosts.put(fField, fBoost);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MultiMatchQueryBuilder getBuilderPrototype() {
|
|
||||||
return MultiMatchQueryBuilder.PROTOTYPE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -486,8 +486,7 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder> ext
|
||||||
throw new IllegalArgumentException(FunctionScoreQueryBuilder.NAME + " : scale must be > 0.0.");
|
throw new IllegalArgumentException(FunctionScoreQueryBuilder.NAME + " : scale must be > 0.0.");
|
||||||
}
|
}
|
||||||
if (decay <= 0.0 || decay >= 1.0) {
|
if (decay <= 0.0 || decay >= 1.0) {
|
||||||
throw new IllegalArgumentException(FunctionScoreQueryBuilder.NAME
|
throw new IllegalArgumentException(FunctionScoreQueryBuilder.NAME + " : decay must be in the range [0..1].");
|
||||||
+ " : decay must be in the range [0..1].");
|
|
||||||
}
|
}
|
||||||
this.scale = func.processScale(userSuppiedScale, decay);
|
this.scale = func.processScale(userSuppiedScale, decay);
|
||||||
this.func = func;
|
this.func = func;
|
||||||
|
|
|
@ -256,7 +256,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWriteableName() {
|
public String getWriteableName() {
|
||||||
return FunctionScoreQueryBuilder.NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -477,12 +477,16 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
|
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. [query] is already defined.", FunctionScoreQueryBuilder.NAME);
|
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. [query] is already defined.",
|
||||||
|
NAME);
|
||||||
}
|
}
|
||||||
query = parseContext.parseInnerQueryBuilder();
|
query = parseContext.parseInnerQueryBuilder();
|
||||||
} else {
|
} else {
|
||||||
if (singleFunctionFound) {
|
if (singleFunctionFound) {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. already found function [{}], now encountering [{}]. use [functions] array if you want to define several functions.", FunctionScoreQueryBuilder.NAME, singleFunctionName, currentFieldName);
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"failed to parse [{}] query. already found function [{}], now encountering [{}]. use [functions] "
|
||||||
|
+ "array if you want to define several functions.",
|
||||||
|
NAME, singleFunctionName, currentFieldName);
|
||||||
}
|
}
|
||||||
if (functionArrayFound) {
|
if (functionArrayFound) {
|
||||||
String errorString = "already found [functions] array, now encountering [" + currentFieldName + "].";
|
String errorString = "already found [functions] array, now encountering [" + currentFieldName + "].";
|
||||||
|
@ -505,7 +509,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
functionArrayFound = true;
|
functionArrayFound = true;
|
||||||
currentFieldName = parseFiltersAndFunctions(scoreFunctionLookup, parseContext, parser, filterFunctionBuilders);
|
currentFieldName = parseFiltersAndFunctions(scoreFunctionLookup, parseContext, parser, filterFunctionBuilders);
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. array [{}] is not supported", FunctionScoreQueryBuilder.NAME, currentFieldName);
|
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. array [{}] is not supported",
|
||||||
|
NAME, currentFieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (token.isValue()) {
|
} else if (token.isValue()) {
|
||||||
|
@ -523,7 +528,10 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
minScore = parser.floatValue();
|
minScore = parser.floatValue();
|
||||||
} else {
|
} else {
|
||||||
if (singleFunctionFound) {
|
if (singleFunctionFound) {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. already found function [{}], now encountering [{}]. use [functions] array if you want to define several functions.", FunctionScoreQueryBuilder.NAME, singleFunctionName, currentFieldName);
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"failed to parse [{}] query. already found function [{}], now encountering [{}]. use [functions] array "
|
||||||
|
+ "if you want to define several functions.",
|
||||||
|
NAME, singleFunctionName, currentFieldName);
|
||||||
}
|
}
|
||||||
if (functionArrayFound) {
|
if (functionArrayFound) {
|
||||||
String errorString = "already found [functions] array, now encountering [" + currentFieldName + "].";
|
String errorString = "already found [functions] array, now encountering [" + currentFieldName + "].";
|
||||||
|
@ -534,7 +542,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
singleFunctionFound = true;
|
singleFunctionFound = true;
|
||||||
singleFunctionName = currentFieldName;
|
singleFunctionName = currentFieldName;
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. field [{}] is not supported", FunctionScoreQueryBuilder.NAME, currentFieldName);
|
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. field [{}] is not supported",
|
||||||
|
NAME, currentFieldName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +569,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void handleMisplacedFunctionsDeclaration(XContentLocation contentLocation, String errorString) {
|
private static void handleMisplacedFunctionsDeclaration(XContentLocation contentLocation, String errorString) {
|
||||||
throw new ParsingException(contentLocation, "failed to parse [{}] query. [{}]", FunctionScoreQueryBuilder.NAME, MISPLACED_FUNCTION_MESSAGE_PREFIX + errorString);
|
throw new ParsingException(contentLocation, "failed to parse [{}] query. [{}]", NAME,
|
||||||
|
MISPLACED_FUNCTION_MESSAGE_PREFIX + errorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String parseFiltersAndFunctions(Function<String, ScoreFunctionParser<?>> scoreFunctionLookup,
|
private static String parseFiltersAndFunctions(Function<String, ScoreFunctionParser<?>> scoreFunctionLookup,
|
||||||
|
@ -573,7 +583,9 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
ScoreFunctionBuilder<?> scoreFunction = null;
|
ScoreFunctionBuilder<?> scoreFunction = null;
|
||||||
Float functionWeight = null;
|
Float functionWeight = null;
|
||||||
if (token != XContentParser.Token.START_OBJECT) {
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}]. malformed query, expected a [{}] while parsing functions but got a [{}] instead", XContentParser.Token.START_OBJECT, token, FunctionScoreQueryBuilder.NAME);
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"failed to parse [{}]. malformed query, expected a [{}] while parsing functions but got a [{}] instead",
|
||||||
|
XContentParser.Token.START_OBJECT, token, NAME);
|
||||||
} else {
|
} else {
|
||||||
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) {
|
||||||
|
@ -593,7 +605,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
if (parseContext.parseFieldMatcher().match(currentFieldName, WEIGHT_FIELD)) {
|
if (parseContext.parseFieldMatcher().match(currentFieldName, WEIGHT_FIELD)) {
|
||||||
functionWeight = parser.floatValue();
|
functionWeight = parser.floatValue();
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. field [{}] is not supported", FunctionScoreQueryBuilder.NAME, currentFieldName);
|
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. field [{}] is not supported",
|
||||||
|
NAME, currentFieldName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -609,7 +622,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
|
||||||
filter = new MatchAllQueryBuilder();
|
filter = new MatchAllQueryBuilder();
|
||||||
}
|
}
|
||||||
if (scoreFunction == null) {
|
if (scoreFunction == null) {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "failed to parse [{}] query. an entry in functions list is missing a function.", FunctionScoreQueryBuilder.NAME);
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"failed to parse [{}] query. an entry in functions list is missing a function.", NAME);
|
||||||
}
|
}
|
||||||
filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(filter, scoreFunction));
|
filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(filter, scoreFunction));
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ import org.elasticsearch.index.query.MatchPhrasePrefixQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
|
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MatchQueryBuilder;
|
import org.elasticsearch.index.query.MatchQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MoreLikeThisQueryParser;
|
import org.elasticsearch.index.query.MoreLikeThisQueryParser;
|
||||||
import org.elasticsearch.index.query.MultiMatchQueryParser;
|
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
|
||||||
import org.elasticsearch.index.query.NestedQueryBuilder;
|
import org.elasticsearch.index.query.NestedQueryBuilder;
|
||||||
import org.elasticsearch.index.query.ParentIdQueryBuilder;
|
import org.elasticsearch.index.query.ParentIdQueryBuilder;
|
||||||
import org.elasticsearch.index.query.PercolatorQueryBuilder;
|
import org.elasticsearch.index.query.PercolatorQueryBuilder;
|
||||||
|
@ -315,8 +315,8 @@ public class SearchModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a query.
|
* Register a query via its parser's prototype.
|
||||||
* TODO remove this in favor of registerQuery and rename innerRegisterQueryParser
|
* TODO remove this in favor of registerQuery and merge innerRegisterQueryParser into registerQuery
|
||||||
*/
|
*/
|
||||||
public void registerQueryParser(QueryParser<?> queryParser, ParseField queryName) {
|
public void registerQueryParser(QueryParser<?> queryParser, ParseField queryName) {
|
||||||
innerRegisterQueryParser(queryParser, queryName);
|
innerRegisterQueryParser(queryParser, queryName);
|
||||||
|
@ -328,7 +328,7 @@ public class SearchModule extends AbstractModule {
|
||||||
for (String name: queryName.getAllNamesIncludedDeprecated()) {
|
for (String name: queryName.getAllNamesIncludedDeprecated()) {
|
||||||
Tuple<ParseField, QueryParser<?>> previousValue = queryParsers.putIfAbsent(name, parseFieldQueryParserTuple);
|
Tuple<ParseField, QueryParser<?>> previousValue = queryParsers.putIfAbsent(name, parseFieldQueryParserTuple);
|
||||||
if (previousValue != null) {
|
if (previousValue != null) {
|
||||||
throw new IllegalArgumentException("Query parser [" + queryParsers.get(name) + "] already registered for name [" +
|
throw new IllegalArgumentException("Query parser [" + previousValue.v2() + "] already registered for name [" +
|
||||||
name + "] while trying to register [" + parser + "]");
|
name + "] while trying to register [" + parser + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,7 +511,8 @@ public class SearchModule extends AbstractModule {
|
||||||
MatchPhraseQueryBuilder.QUERY_NAME_FIELD);
|
MatchPhraseQueryBuilder.QUERY_NAME_FIELD);
|
||||||
registerQuery(MatchPhrasePrefixQueryBuilder.PROTOTYPE::readFrom, MatchPhrasePrefixQueryBuilder::fromXContent,
|
registerQuery(MatchPhrasePrefixQueryBuilder.PROTOTYPE::readFrom, MatchPhrasePrefixQueryBuilder::fromXContent,
|
||||||
MatchPhrasePrefixQueryBuilder.QUERY_NAME_FIELD);
|
MatchPhrasePrefixQueryBuilder.QUERY_NAME_FIELD);
|
||||||
registerQueryParser(new MultiMatchQueryParser(), MultiMatchQueryParser.QUERY_NAME_FIELD);
|
registerQuery(MultiMatchQueryBuilder.PROTOTYPE::readFrom, MultiMatchQueryBuilder::fromXContent,
|
||||||
|
MultiMatchQueryBuilder.QUERY_NAME_FIELD);
|
||||||
registerQuery(NestedQueryBuilder.PROTOTYPE::readFrom, NestedQueryBuilder::fromXContent, NestedQueryBuilder.QUERY_NAME_FIELD);
|
registerQuery(NestedQueryBuilder.PROTOTYPE::readFrom, NestedQueryBuilder::fromXContent, NestedQueryBuilder.QUERY_NAME_FIELD);
|
||||||
registerQuery(HasChildQueryBuilder.PROTOTYPE::readFrom, HasChildQueryBuilder::fromXContent, HasChildQueryBuilder.QUERY_NAME_FIELD);
|
registerQuery(HasChildQueryBuilder.PROTOTYPE::readFrom, HasChildQueryBuilder::fromXContent, HasChildQueryBuilder.QUERY_NAME_FIELD);
|
||||||
registerQuery(HasParentQueryBuilder.PROTOTYPE::readFrom, HasParentQueryBuilder::fromXContent,
|
registerQuery(HasParentQueryBuilder.PROTOTYPE::readFrom, HasParentQueryBuilder::fromXContent,
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentLocation;
|
import org.elasticsearch.common.xcontent.XContentLocation;
|
||||||
import org.elasticsearch.index.query.QueryParser;
|
import org.elasticsearch.index.query.QueryParser;
|
||||||
|
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||||
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
|
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
|
||||||
import org.elasticsearch.search.highlight.CustomHighlighter;
|
import org.elasticsearch.search.highlight.CustomHighlighter;
|
||||||
import org.elasticsearch.search.highlight.Highlighter;
|
import org.elasticsearch.search.highlight.Highlighter;
|
||||||
|
@ -79,12 +80,9 @@ public class SearchModuleTests extends ModuleTestCase {
|
||||||
|
|
||||||
public void testRegisterQueryParserDuplicate() {
|
public void testRegisterQueryParserDuplicate() {
|
||||||
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
|
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
|
||||||
try {
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> module
|
||||||
module.buildQueryParserRegistry();
|
.registerQuery(TermQueryBuilder.PROTOTYPE::readFrom, TermQueryBuilder::fromXContent, TermQueryBuilder.QUERY_NAME_FIELD));
|
||||||
} catch (IllegalArgumentException e) {
|
assertThat(e.getMessage(), containsString("already registered for name [term] while trying to register [org.elasticsearch."));
|
||||||
assertThat(e.getMessage(),
|
|
||||||
containsString("already registered for name [term] while trying to register [org.elasticsearch.index."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRegisteredQueries() {
|
public void testRegisteredQueries() {
|
||||||
|
|
Loading…
Reference in New Issue