All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.elasticsearch.index.query.MatchPhraseQueryBuilder Maven / Gradle / Ivy
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.index.query;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.search.Query;
import org.elasticsearch.Version;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.search.MatchQueryParser;
import org.elasticsearch.xcontent.ParseField;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
/**
* Match query is a query that analyzes the text and constructs a phrase query
* as the result of the analysis.
*/
public class MatchPhraseQueryBuilder extends AbstractQueryBuilder {
public static final String NAME = "match_phrase";
public static final ParseField SLOP_FIELD = new ParseField("slop");
public static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
private final String fieldName;
private final Object value;
private String analyzer;
private int slop = MatchQueryParser.DEFAULT_PHRASE_SLOP;
private ZeroTermsQueryOption zeroTermsQuery = MatchQueryParser.DEFAULT_ZERO_TERMS_QUERY;
public MatchPhraseQueryBuilder(String fieldName, Object value) {
if (Strings.isEmpty(fieldName)) {
throw new IllegalArgumentException("[" + NAME + "] requires fieldName");
}
if (value == null) {
throw new IllegalArgumentException("[" + NAME + "] requires query value");
}
this.fieldName = fieldName;
this.value = value;
}
/**
* Read from a stream.
*/
public MatchPhraseQueryBuilder(StreamInput in) throws IOException {
super(in);
fieldName = in.readString();
value = in.readGenericValue();
slop = in.readVInt();
zeroTermsQuery = ZeroTermsQueryOption.readFromStream(in);
analyzer = in.readOptionalString();
}
@Override
protected void doWriteTo(StreamOutput out) throws IOException {
out.writeString(fieldName);
out.writeGenericValue(value);
out.writeVInt(slop);
zeroTermsQuery.writeTo(out);
out.writeOptionalString(analyzer);
}
/** Returns the field name used in this query. */
public String fieldName() {
return this.fieldName;
}
/** Returns the value used in this query. */
public Object value() {
return this.value;
}
/**
* Explicitly set the analyzer to use. Defaults to use explicit mapping
* config for the field, or, if not set, the default search analyzer.
*/
public MatchPhraseQueryBuilder analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/** Get the analyzer to use, if previously set, otherwise {@code null} */
public String analyzer() {
return this.analyzer;
}
/** Sets a slop factor for phrase queries */
public MatchPhraseQueryBuilder slop(int slop) {
if (slop < 0) {
throw new IllegalArgumentException("No negative slop allowed.");
}
this.slop = slop;
return this;
}
/** Get the slop factor for phrase queries. */
public int slop() {
return this.slop;
}
/**
* Sets query to use in case no query terms are available, e.g. after analysis removed them.
* Defaults to {@link ZeroTermsQueryOption#NONE}, but can be set to
* {@link ZeroTermsQueryOption#ALL} instead.
*/
public MatchPhraseQueryBuilder zeroTermsQuery(ZeroTermsQueryOption zeroTermsQuery) {
if (zeroTermsQuery == null) {
throw new IllegalArgumentException("[" + NAME + "] requires zeroTermsQuery to be non-null");
}
this.zeroTermsQuery = zeroTermsQuery;
return this;
}
public ZeroTermsQueryOption zeroTermsQuery() {
return this.zeroTermsQuery;
}
@Override
public String getWriteableName() {
return NAME;
}
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startObject(fieldName);
builder.field(MatchQueryBuilder.QUERY_FIELD.getPreferredName(), value);
if (analyzer != null) {
builder.field(MatchQueryBuilder.ANALYZER_FIELD.getPreferredName(), analyzer);
}
if (slop != MatchQueryParser.DEFAULT_PHRASE_SLOP) {
builder.field(SLOP_FIELD.getPreferredName(), slop);
}
if (zeroTermsQuery != MatchQueryParser.DEFAULT_ZERO_TERMS_QUERY) {
builder.field(ZERO_TERMS_QUERY_FIELD.getPreferredName(), zeroTermsQuery.toString());
}
boostAndQueryNameToXContent(builder);
builder.endObject();
builder.endObject();
}
@Override
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
SearchExecutionContext sec = queryRewriteContext.convertToSearchExecutionContext();
if (sec == null) {
return this;
}
// If we're using the default keyword analyzer then we can rewrite this to a TermQueryBuilder
// and possibly shortcut
// If we're using a keyword analyzer then we can rewrite this to a TermQueryBuilder
// and possibly shortcut
NamedAnalyzer configuredAnalyzer = configuredAnalyzer(sec);
if (configuredAnalyzer != null && configuredAnalyzer.analyzer() instanceof KeywordAnalyzer) {
TermQueryBuilder termQueryBuilder = new TermQueryBuilder(fieldName, value);
return termQueryBuilder.rewrite(sec);
}
return this;
}
private NamedAnalyzer configuredAnalyzer(SearchExecutionContext context) {
if (analyzer != null) {
return context.getIndexAnalyzers().get(analyzer);
}
MappedFieldType mft = context.getFieldType(fieldName);
if (mft != null) {
return mft.getTextSearchInfo().searchAnalyzer();
}
return null;
}
@Override
protected Query doToQuery(SearchExecutionContext context) throws IOException {
// validate context specific fields
if (analyzer != null && context.getIndexAnalyzers().get(analyzer) == null) {
throw new QueryShardException(context, "[" + NAME + "] analyzer [" + analyzer + "] not found");
}
MatchQueryParser queryParser = new MatchQueryParser(context);
if (analyzer != null) {
queryParser.setAnalyzer(analyzer);
}
queryParser.setPhraseSlop(slop);
queryParser.setZeroTermsQuery(zeroTermsQuery);
return queryParser.parse(MatchQueryParser.Type.PHRASE, fieldName, value);
}
@Override
protected boolean doEquals(MatchPhraseQueryBuilder other) {
return Objects.equals(fieldName, other.fieldName)
&& Objects.equals(value, other.value)
&& Objects.equals(analyzer, other.analyzer)
&& Objects.equals(slop, other.slop)
&& Objects.equals(zeroTermsQuery, other.zeroTermsQuery);
}
@Override
protected int doHashCode() {
return Objects.hash(fieldName, value, analyzer, slop);
}
public static MatchPhraseQueryBuilder fromXContent(XContentParser parser) throws IOException {
String fieldName = null;
Object value = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String analyzer = null;
int slop = MatchQueryParser.DEFAULT_PHRASE_SLOP;
ZeroTermsQueryOption zeroTermsQuery = MatchQueryParser.DEFAULT_ZERO_TERMS_QUERY;
String queryName = null;
String currentFieldName = null;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
throwParsingExceptionOnMultipleFields(NAME, parser.getTokenLocation(), fieldName, currentFieldName);
fieldName = currentFieldName;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (MatchQueryBuilder.QUERY_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
value = parser.objectText();
} else if (MatchQueryBuilder.ANALYZER_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
analyzer = parser.text();
} else if (AbstractQueryBuilder.BOOST_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
boost = parser.floatValue();
} else if (SLOP_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
slop = parser.intValue();
} else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
queryName = parser.text();
} else if (ZERO_TERMS_QUERY_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
String zeroTermsValue = parser.text();
if ("none".equalsIgnoreCase(zeroTermsValue)) {
zeroTermsQuery = ZeroTermsQueryOption.NONE;
} else if ("all".equalsIgnoreCase(zeroTermsValue)) {
zeroTermsQuery = ZeroTermsQueryOption.ALL;
} else {
throw new ParsingException(
parser.getTokenLocation(),
"Unsupported zero_terms_query value [" + zeroTermsValue + "]"
);
}
} else {
throw new ParsingException(
parser.getTokenLocation(),
"[" + NAME + "] query does not support [" + currentFieldName + "]"
);
}
} else {
throw new ParsingException(
parser.getTokenLocation(),
"[" + NAME + "] unknown token [" + token + "] after [" + currentFieldName + "]"
);
}
}
} else {
throwParsingExceptionOnMultipleFields(NAME, parser.getTokenLocation(), fieldName, parser.currentName());
fieldName = parser.currentName();
value = parser.objectText();
}
}
MatchPhraseQueryBuilder matchQuery = new MatchPhraseQueryBuilder(fieldName, value);
matchQuery.analyzer(analyzer);
matchQuery.slop(slop);
matchQuery.zeroTermsQuery(zeroTermsQuery);
matchQuery.queryName(queryName);
matchQuery.boost(boost);
return matchQuery;
}
@Override
public Version getMinimalSupportedVersion() {
return Version.V_EMPTY;
}
}