OpenSearch/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java

389 lines
13 KiB
Java
Raw Normal View History

2010-02-08 15:30:06 +02:00
/*
2011-12-06 02:42:25 +02:00
* Licensed to ElasticSearch and Shay Banon under one
2010-02-08 15:30:06 +02:00
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
2011-12-06 02:42:25 +02:00
* regarding copyright ownership. ElasticSearch licenses this
2010-02-08 15:30:06 +02:00
* 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;
2010-02-08 15:30:06 +02:00
2011-12-06 02:42:25 +02:00
import gnu.trove.impl.Constants;
import gnu.trove.map.hash.TObjectFloatHashMap;
2010-09-12 23:20:13 +02:00
import org.elasticsearch.common.xcontent.XContentBuilder;
2010-02-08 15:30:06 +02:00
import java.io.IOException;
import java.util.List;
2011-12-06 02:42:25 +02:00
import static com.google.common.collect.Lists.newArrayList;
2010-02-08 15:30:06 +02:00
/**
2010-03-02 22:16:35 +02:00
* A query that parses a query string and runs it. There are two modes that this operates. The first,
* when no field is added (using {@link #field(String)}, will run the query once and non prefixed fields
* will use the {@link #defaultField(String)} set. The second, when one or more fields are added
* (using {@link #field(String)}), will run the parsed query against the provided fields, and combine
* them either using DisMax or a plain boolean query (see {@link #useDisMax(boolean)}).
* <p/>
2011-12-06 02:42:25 +02:00
* (shay.baon)
2010-02-08 15:30:06 +02:00
*/
public class QueryStringQueryBuilder extends BaseQueryBuilder {
2010-02-08 15:30:06 +02:00
public static enum Operator {
OR,
AND
}
private final String queryString;
private String defaultField;
private Operator defaultOperator;
private String analyzer;
private String quoteAnalyzer;
private String quoteFieldSuffix;
2010-02-08 15:30:06 +02:00
private Boolean autoGeneratePhraseQueries;
2010-02-08 15:30:06 +02:00
private Boolean allowLeadingWildcard;
private Boolean lowercaseExpandedTerms;
private Boolean enablePositionIncrements;
private Boolean analyzeWildcard;
2010-02-08 15:30:06 +02:00
private float boost = -1;
private float fuzzyMinSim = -1;
2010-02-08 15:30:06 +02:00
private int fuzzyPrefixLength = -1;
private int fuzzyMaxExpansions = -1;
private String fuzzyRewrite;
2010-02-08 15:30:06 +02:00
private int phraseSlop = -1;
private List<String> fields;
private TObjectFloatHashMap<String> fieldsBoosts;
private Boolean useDisMax;
private float tieBreaker = -1;
private String rewrite = null;
private String minimumShouldMatch;
private Boolean lenient;
public QueryStringQueryBuilder(String queryString) {
2010-02-08 15:30:06 +02:00
this.queryString = queryString;
}
2010-03-02 22:16:35 +02:00
/**
* The default field to run against when no prefix field is specified. Only relevant when
* not explicitly adding fields the query string will run against.
*/
public QueryStringQueryBuilder defaultField(String defaultField) {
2010-02-08 15:30:06 +02:00
this.defaultField = defaultField;
return this;
}
/**
* Adds a field to run the query string against.
*/
public QueryStringQueryBuilder field(String field) {
if (fields == null) {
fields = newArrayList();
}
fields.add(field);
return this;
}
/**
* Adds a field to run the query string against with a specific boost.
*/
public QueryStringQueryBuilder field(String field, float boost) {
if (fields == null) {
fields = newArrayList();
}
fields.add(field);
if (fieldsBoosts == null) {
fieldsBoosts = new TObjectFloatHashMap<String>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, -1);
}
fieldsBoosts.put(field, boost);
return this;
}
/**
* When more than one field is used with the query string, should queries be combined using
* dis max, or boolean query. Defaults to dis max (<tt>true</tt>).
*/
public QueryStringQueryBuilder useDisMax(boolean useDisMax) {
this.useDisMax = useDisMax;
return this;
}
/**
* When more than one field is used with the query string, and combined queries are using
* dis max, control the tie breaker for it.
*/
public QueryStringQueryBuilder tieBreaker(float tieBreaker) {
this.tieBreaker = tieBreaker;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Sets the boolean operator of the query parser used to parse the query string.
2011-12-06 02:42:25 +02:00
* <p/>
* <p>In default mode ({@link FieldQueryBuilder.Operator#OR}) terms without any modifiers
2010-03-02 22:16:35 +02:00
* are considered optional: for example <code>capital of Hungary</code> is equal to
* <code>capital OR of OR Hungary</code>.
2011-12-06 02:42:25 +02:00
* <p/>
* <p>In {@link FieldQueryBuilder.Operator#AND} mode terms are considered to be in conjunction: the
2010-03-02 22:16:35 +02:00
* above mentioned query is parsed as <code>capital AND of AND Hungary</code>
*/
public QueryStringQueryBuilder defaultOperator(Operator defaultOperator) {
2010-02-08 15:30:06 +02:00
this.defaultOperator = defaultOperator;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* The optional analyzer used to analyze the query string. Note, if a field has search analyzer
* defined for it, then it will be used automatically. Defaults to the smart search analyzer.
*/
public QueryStringQueryBuilder analyzer(String analyzer) {
2010-02-08 15:30:06 +02:00
this.analyzer = analyzer;
return this;
}
/**
* The optional analyzer used to analyze the query string for phrase searches. Note, if a field has search (quote) analyzer
* defined for it, then it will be used automatically. Defaults to the smart search analyzer.
*/
public QueryStringQueryBuilder quoteAnalyzer(String analyzer) {
this.quoteAnalyzer = analyzer;
return this;
}
/**
* Set to true if phrase queries will be automatically generated
* when the analyzer returns more than one term from whitespace
* delimited text.
* NOTE: this behavior may not be suitable for all languages.
2011-12-06 02:42:25 +02:00
* <p/>
* Set to false if phrase queries should only be generated when
* surrounded by double quotes.
*/
2011-08-13 22:36:11 +03:00
public QueryStringQueryBuilder autoGeneratePhraseQueries(boolean autoGeneratePhraseQueries) {
this.autoGeneratePhraseQueries = autoGeneratePhraseQueries;
2011-08-13 22:36:11 +03:00
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Should leading wildcards be allowed or not. Defaults to <tt>true</tt>.
*/
public QueryStringQueryBuilder allowLeadingWildcard(boolean allowLeadingWildcard) {
2010-02-08 15:30:06 +02:00
this.allowLeadingWildcard = allowLeadingWildcard;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically
* lower-cased or not. Default is <tt>true</tt>.
*/
public QueryStringQueryBuilder lowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
2010-02-08 15:30:06 +02:00
this.lowercaseExpandedTerms = lowercaseExpandedTerms;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Set to <tt>true</tt> to enable position increments in result query. Defaults to
* <tt>true</tt>.
2011-12-06 02:42:25 +02:00
* <p/>
2010-03-02 22:16:35 +02:00
* <p>When set, result phrase and multi-phrase queries will be aware of position increments.
* Useful when e.g. a StopFilter increases the position increment of the token that follows an omitted token.
*/
public QueryStringQueryBuilder enablePositionIncrements(boolean enablePositionIncrements) {
2010-02-08 15:30:06 +02:00
this.enablePositionIncrements = enablePositionIncrements;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Set the minimum similarity for fuzzy queries. Default is 0.5f.
*/
public QueryStringQueryBuilder fuzzyMinSim(float fuzzyMinSim) {
2010-02-08 15:30:06 +02:00
this.fuzzyMinSim = fuzzyMinSim;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Set the minimum similarity for fuzzy queries. Default is 0.5f.
*/
public QueryStringQueryBuilder fuzzyPrefixLength(int fuzzyPrefixLength) {
2010-02-08 15:30:06 +02:00
this.fuzzyPrefixLength = fuzzyPrefixLength;
return this;
}
public QueryStringQueryBuilder fuzzyMaxExpansions(int fuzzyMaxExpansions) {
this.fuzzyMaxExpansions = fuzzyMaxExpansions;
return this;
}
public QueryStringQueryBuilder fuzzyRewrite(String fuzzyRewrite) {
this.fuzzyRewrite = fuzzyRewrite;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Sets the default slop for phrases. If zero, then exact phrase matches
* are required. Default value is zero.
*/
public QueryStringQueryBuilder phraseSlop(int phraseSlop) {
2010-02-08 15:30:06 +02:00
this.phraseSlop = phraseSlop;
return this;
}
/**
* Set to <tt>true</tt> to enable analysis on wildcard and prefix queries.
*/
public QueryStringQueryBuilder analyzeWildcard(boolean analyzeWildcard) {
this.analyzeWildcard = analyzeWildcard;
return this;
}
public QueryStringQueryBuilder rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}
public QueryStringQueryBuilder minimumShouldMatch(String minimumShouldMatch) {
this.minimumShouldMatch = minimumShouldMatch;
return this;
}
2010-03-02 22:16:35 +02:00
/**
* Sets the boost for this query. Documents matching this query will (in addition to the normal
* weightings) have their score multiplied by the boost provided.
*/
public QueryStringQueryBuilder boost(float boost) {
2010-03-02 22:16:35 +02:00
this.boost = boost;
return this;
}
/**
* An optional field name suffix to automatically try and add to the field searched when using quoted text.
*/
public QueryStringQueryBuilder quoteFieldSuffix(String quoteFieldSuffix) {
this.quoteFieldSuffix = quoteFieldSuffix;
return this;
}
/**
* Sets the query string parser to be lenient when parsing field values, defaults to the index
* setting and if not set, defaults to false.
*/
public QueryStringQueryBuilder lenient(Boolean lenient) {
this.lenient = lenient;
return this;
}
2011-12-06 02:42:25 +02:00
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(QueryStringQueryParser.NAME);
2010-02-08 15:30:06 +02:00
builder.field("query", queryString);
if (defaultField != null) {
builder.field("default_field", defaultField);
2010-02-08 15:30:06 +02:00
}
if (fields != null) {
builder.startArray("fields");
for (String field : fields) {
float boost = -1;
if (fieldsBoosts != null) {
boost = fieldsBoosts.get(field);
}
if (boost != -1) {
field += "^" + boost;
}
2010-03-02 22:16:35 +02:00
builder.value(field);
}
builder.endArray();
}
if (useDisMax != null) {
builder.field("use_dis_max", useDisMax);
}
if (tieBreaker != -1) {
builder.field("tie_breaker", tieBreaker);
}
2010-02-08 15:30:06 +02:00
if (defaultOperator != null) {
builder.field("default_operator", defaultOperator.name().toLowerCase());
2010-02-08 15:30:06 +02:00
}
if (analyzer != null) {
builder.field("analyzer", analyzer);
}
if (quoteAnalyzer != null) {
builder.field("quote_analyzer", quoteAnalyzer);
}
if (autoGeneratePhraseQueries != null) {
builder.field("auto_generate_phrase_queries", autoGeneratePhraseQueries);
}
2010-02-08 15:30:06 +02:00
if (allowLeadingWildcard != null) {
builder.field("allow_leading_wildcard", allowLeadingWildcard);
2010-02-08 15:30:06 +02:00
}
if (lowercaseExpandedTerms != null) {
builder.field("lowercase_expanded_terms", lowercaseExpandedTerms);
2010-02-08 15:30:06 +02:00
}
if (enablePositionIncrements != null) {
builder.field("enable_position_increments", enablePositionIncrements);
2010-02-08 15:30:06 +02:00
}
if (fuzzyMinSim != -1) {
builder.field("fuzzy_min_sim", fuzzyMinSim);
2010-02-08 15:30:06 +02:00
}
if (boost != -1) {
builder.field("boost", boost);
}
if (fuzzyPrefixLength != -1) {
builder.field("fuzzy_prefix_length", fuzzyPrefixLength);
2010-02-08 15:30:06 +02:00
}
if (fuzzyMaxExpansions != -1) {
builder.field("fuzzy_max_expansions", fuzzyMaxExpansions);
}
if (fuzzyRewrite != null) {
builder.field("fuzzy_rewrite", fuzzyRewrite);
}
2010-02-08 15:30:06 +02:00
if (phraseSlop != -1) {
builder.field("phrase_slop", phraseSlop);
2010-02-08 15:30:06 +02:00
}
if (analyzeWildcard != null) {
builder.field("analyze_wildcard", analyzeWildcard);
}
if (rewrite != null) {
builder.field("rewrite", rewrite);
}
if (minimumShouldMatch != null) {
builder.field("minimum_should_match", minimumShouldMatch);
}
if (quoteFieldSuffix != null) {
builder.field("quote_field_suffix", quoteFieldSuffix);
}
if (lenient != null) {
builder.field("lenient", lenient);
}
2010-02-08 15:30:06 +02:00
builder.endObject();
}
}