Skip to content

Commit

Permalink
Query DSL: Allow to control how all multi term queries are rewritten, c…
Browse files Browse the repository at this point in the history
…loses #1186.
  • Loading branch information
kimchy committed Jul 29, 2011
1 parent 06bcd42 commit 73adbdd
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 12 deletions.
Expand Up @@ -24,7 +24,6 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.io.FastStringReader;
Expand Down Expand Up @@ -84,7 +83,7 @@ public MapperQueryParser(QueryParserSettings settings, QueryParseContext parseCo
public void reset(QueryParserSettings settings) {
this.field = settings.defaultField();
this.analyzer = settings.analyzer();
setMultiTermRewriteMethod(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
setMultiTermRewriteMethod(settings.rewriteMethod());
setEnablePositionIncrements(settings.enablePositionIncrements());
setAutoGeneratePhraseQueries(settings.autoGeneratePhraseQueries());
setAllowLeadingWildcard(settings.allowLeadingWildcard());
Expand Down
Expand Up @@ -21,6 +21,7 @@

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiTermQuery;

/**
* @author kimchy (shay.banon)
Expand All @@ -41,6 +42,7 @@ public class QueryParserSettings {
private boolean analyzeWildcard = false;
private boolean escape = false;
private Analyzer analyzer = null;
private MultiTermQuery.RewriteMethod rewriteMethod = MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;

public String queryString() {
return queryString;
Expand Down Expand Up @@ -154,6 +156,14 @@ public void analyzeWildcard(boolean analyzeWildcard) {
this.analyzeWildcard = analyzeWildcard;
}

public MultiTermQuery.RewriteMethod rewriteMethod() {
return this.rewriteMethod;
}

public void rewriteMethod(MultiTermQuery.RewriteMethod rewriteMethod) {
this.rewriteMethod = rewriteMethod;
}

@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Expand Down
Expand Up @@ -65,6 +65,8 @@ public static enum Operator {

private boolean extraSet = false;

private String rewrite;

/**
* A query that executes the query string against a field. It is a simplified
* version of {@link QueryStringQueryBuilder} that simply runs against
Expand Down Expand Up @@ -268,6 +270,12 @@ public FieldQueryBuilder analyzeWildcard(boolean analyzeWildcard) {
return this;
}

public FieldQueryBuilder rewrite(String rewrite) {
this.rewrite = rewrite;
extraSet = true;
return this;
}

@Override public void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(FieldQueryParser.NAME);
if (!extraSet) {
Expand Down Expand Up @@ -308,6 +316,9 @@ public FieldQueryBuilder analyzeWildcard(boolean analyzeWildcard) {
if (analyzeWildcard != null) {
builder.field("analyze_wildcard", analyzeWildcard);
}
if (rewrite != null) {
builder.field("rewrite", rewrite);
}
builder.endObject();
}
builder.endObject();
Expand Down
Expand Up @@ -25,6 +25,7 @@
import org.apache.lucene.search.Query;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.support.QueryParsers;

import java.io.IOException;

Expand Down Expand Up @@ -93,6 +94,8 @@ public class FieldQueryParser implements QueryParser {
qpSettings.escape(parser.booleanValue());
} else if ("analyze_wildcard".equals(currentFieldName) || "analyzeWildcard".equals(currentFieldName)) {
qpSettings.analyzeWildcard(parser.booleanValue());
} else if ("rewrite".equals(currentFieldName)) {
qpSettings.rewriteMethod(QueryParsers.parseRewriteMethod(parser.textOrNull()));
}
}
}
Expand Down
Expand Up @@ -36,6 +36,8 @@ public class PrefixQueryBuilder extends BaseQueryBuilder {

private float boost = -1;

private String rewrite;

/**
* A Query that matches documents containing terms with a specified prefix.
*
Expand All @@ -56,14 +58,24 @@ public PrefixQueryBuilder boost(float boost) {
return this;
}

public PrefixQueryBuilder rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}

@Override public void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(PrefixQueryParser.NAME);
if (boost == -1) {
if (boost == -1 && rewrite == null) {
builder.field(name, prefix);
} else {
builder.startObject(name);
builder.field("prefix", prefix);
builder.field("boost", boost);
if (boost != -1) {
builder.field("boost", boost);
}
if (rewrite != null) {
builder.field("rewrite", rewrite);
}
builder.endObject();
}
builder.endObject();
Expand Down
Expand Up @@ -20,12 +20,12 @@
package org.elasticsearch.index.query;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.support.QueryParsers;

import java.io.IOException;

Expand All @@ -51,7 +51,7 @@ public class PrefixQueryParser implements QueryParser {
XContentParser.Token token = parser.nextToken();
assert token == XContentParser.Token.FIELD_NAME;
String fieldName = parser.currentName();

String rewriteMethod = null;

String value = null;
float boost = 1.0f;
Expand All @@ -68,6 +68,8 @@ public class PrefixQueryParser implements QueryParser {
value = parser.text();
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if ("rewrite".equals(currentFieldName)) {
rewriteMethod = parser.textOrNull();
}
}
}
Expand All @@ -90,7 +92,7 @@ public class PrefixQueryParser implements QueryParser {
}

PrefixQuery query = new PrefixQuery(new Term(fieldName, value));
query.setRewriteMethod(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
query.setRewriteMethod(QueryParsers.parseRewriteMethod(rewriteMethod));
query.setBoost(boost);
return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext);
}
Expand Down
Expand Up @@ -78,6 +78,8 @@ public static enum Operator {

private float tieBreaker = -1;

private String rewrite = null;

public QueryStringQueryBuilder(String queryString) {
this.queryString = queryString;
}
Expand Down Expand Up @@ -234,6 +236,11 @@ public QueryStringQueryBuilder analyzeWildcard(boolean analyzeWildcard) {
return this;
}

public QueryStringQueryBuilder rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}

/**
* 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.
Expand Down Expand Up @@ -302,6 +309,9 @@ public QueryStringQueryBuilder boost(float boost) {
if (analyzeWildcard != null) {
builder.field("analyze_wildcard", analyzeWildcard);
}
if (rewrite != null) {
builder.field("rewrite", rewrite);
}
builder.endObject();
}
}
Expand Up @@ -31,6 +31,7 @@
import org.elasticsearch.common.trove.map.hash.TObjectFloatHashMap;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
import org.elasticsearch.index.query.support.QueryParsers;

import java.io.IOException;

Expand Down Expand Up @@ -144,6 +145,8 @@ public class QueryStringQueryParser implements QueryParser {
qpSettings.tieBreaker(parser.floatValue());
} else if ("analyze_wildcard".equals(currentFieldName) || "analyzeWildcard".equals(currentFieldName)) {
qpSettings.analyzeWildcard(parser.booleanValue());
} else if ("rewrite".equals(currentFieldName)) {
qpSettings.rewriteMethod(QueryParsers.parseRewriteMethod(parser.textOrNull()));
}
}
}
Expand Down
Expand Up @@ -41,6 +41,8 @@ public class WildcardQueryBuilder extends BaseQueryBuilder {

private float boost = -1;

private String rewrite;

/**
* Implements the wildcard search query. Supported wildcards are <tt>*</tt>, which
* matches any character sequence (including the empty one), and <tt>?</tt>,
Expand All @@ -57,6 +59,11 @@ public WildcardQueryBuilder(String name, String wildcard) {
this.wildcard = wildcard;
}

public WildcardQueryBuilder rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}

/**
* 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.
Expand All @@ -68,12 +75,17 @@ public WildcardQueryBuilder boost(float boost) {

@Override public void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(WildcardQueryParser.NAME);
if (boost == -1) {
if (boost == -1 && rewrite != null) {
builder.field(name, wildcard);
} else {
builder.startObject(name);
builder.field("wildcard", wildcard);
builder.field("boost", boost);
if (boost != -1) {
builder.field("boost", boost);
}
if (rewrite != null) {
builder.field("rewrite", rewrite);
}
builder.endObject();
}
builder.endObject();
Expand Down
Expand Up @@ -20,12 +20,12 @@
package org.elasticsearch.index.query;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.WildcardQuery;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.support.QueryParsers;

import java.io.IOException;

Expand All @@ -51,7 +51,7 @@ public class WildcardQueryParser implements QueryParser {
XContentParser.Token token = parser.nextToken();
assert token == XContentParser.Token.FIELD_NAME;
String fieldName = parser.currentName();

String rewriteMethod = null;

String value = null;
float boost = 1.0f;
Expand All @@ -68,6 +68,8 @@ public class WildcardQueryParser implements QueryParser {
value = parser.text();
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if ("rewrite".equals(currentFieldName)) {
rewriteMethod = parser.textOrNull();
}
}
}
Expand All @@ -90,7 +92,7 @@ public class WildcardQueryParser implements QueryParser {
}

WildcardQuery query = new WildcardQuery(new Term(fieldName, value));
query.setRewriteMethod(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
query.setRewriteMethod(QueryParsers.parseRewriteMethod(rewriteMethod));
query.setBoost(boost);
return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext);
}
Expand Down
Expand Up @@ -21,7 +21,9 @@

import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FilteredQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.lucene.search.AndFilter;
Expand All @@ -38,6 +40,41 @@ private QueryParsers() {

}

public static MultiTermQuery.RewriteMethod parseRewriteMethod(@Nullable String rewriteMethod) {
if (rewriteMethod == null) {
return MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
}
if ("constant_score_auto".equals(rewriteMethod) || "constant_score_auto".equals(rewriteMethod)) {
return MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
}
if ("scoring_boolean".equals(rewriteMethod) || "scoringBoolean".equals(rewriteMethod)) {
return MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
}
if ("constant_score_boolean".equals(rewriteMethod) || "constantScoreBoolean".equals(rewriteMethod)) {
return MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE;
}
if ("constant_score_filter".equals(rewriteMethod) || "constantScoreFilter".equals(rewriteMethod)) {
return MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE;
}
if (rewriteMethod.startsWith("top_terms_")) {

This comment has been minimized.

Copy link
@Yegoroff

Yegoroff Nov 4, 2011

This will fail for "top_terms_boost_N" rewrite method. Cause it will try to parse "boost_N" to int.

This comment has been minimized.

Copy link
@kimchy

kimchy Nov 13, 2011

Author Member

Right, will fix in master and 0.18, thanks!

int size = Integer.parseInt(rewriteMethod.substring("top_terms_".length()));
return new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(size);
}
if (rewriteMethod.startsWith("topTerms")) {
int size = Integer.parseInt(rewriteMethod.substring("topTerms".length()));
return new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(size);
}
if (rewriteMethod.startsWith("top_terms_boost_")) {
int size = Integer.parseInt(rewriteMethod.substring("top_terms_boost_".length()));
return new MultiTermQuery.TopTermsBoostOnlyBooleanQueryRewrite(size);
}
if (rewriteMethod.startsWith("topTermsBoost")) {
int size = Integer.parseInt(rewriteMethod.substring("topTermsBoost".length()));
return new MultiTermQuery.TopTermsBoostOnlyBooleanQueryRewrite(size);
}
throw new ElasticSearchIllegalArgumentException("Failed to parse rewrite_method [" + rewriteMethod + "]");
}

public static Query wrapSmartNameQuery(Query query, @Nullable MapperService.SmartNameFieldMappers smartFieldMappers,
QueryParseContext parseContext) {
if (smartFieldMappers == null) {
Expand Down

0 comments on commit 73adbdd

Please sign in to comment.