diff options
author | Simon Willnauer <simonw@apache.org> | 2016-02-12 12:53:12 +0100 |
---|---|---|
committer | Simon Willnauer <simonw@apache.org> | 2016-02-12 12:53:12 +0100 |
commit | b906c8a389b36206685b46d70f114d6cef82cb15 (patch) | |
tree | 153faa6b3f425a1e2a6d45d11f59769fed815e09 | |
parent | 685bee308130d02fc379e09da7b817fff3a479b6 (diff) |
apply fixes after review
32 files changed, 351 insertions, 96 deletions
diff --git a/core/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java b/core/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java index 77afd12364..4eec61b3a6 100644 --- a/core/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java +++ b/core/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java @@ -33,7 +33,6 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.indices.IndexClosedException; -import org.elasticsearch.search.SearchService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; diff --git a/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java index d2116ae3c0..39c835e4b0 100644 --- a/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java @@ -258,4 +258,23 @@ public abstract class AbstractQueryBuilder<QB extends AbstractQueryBuilder<QB>> } return queries; } + + @Override + public final QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { + QueryBuilder rewritten = doRewrite(queryShardContext); + if (rewritten == this) { + return rewritten; + } + if (queryName() != null && rewritten.queryName() == null) { // we inherit the name + rewritten.queryName(queryName()); + } + if (boost() != DEFAULT_BOOST && rewritten.boost() == DEFAULT_BOOST) { + rewritten.boost(boost()); + } + return rewritten; + } + + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryShardContext) throws IOException { + return this; + } } diff --git a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java index 72e13c2c31..261acff33c 100644 --- a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java @@ -263,6 +263,13 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> { @Override protected Query doToQuery(QueryShardContext context) throws IOException { + final int numClauses = mustNotClauses.size() + filterClauses.size() + shouldClauses.size() + mustClauses.size(); + if (numClauses == 1 && must().size() == 1 && boost() == DEFAULT_BOOST) { + // we really only optimize this for testing since we use this to rewrite + // named queries TemplateQueryBuilder and WrapperQueryBuilder. + // it's equivalent but will anyways happen later down the road in the BQ#rewrite method + return mustClauses.get(0).toQuery(context); + } BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder(); booleanQueryBuilder.setDisableCoord(disableCoord); addBooleanClauses(context, booleanQueryBuilder, mustClauses, BooleanClause.Occur.MUST); @@ -273,6 +280,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> { if (booleanQuery.clauses().isEmpty()) { return new MatchAllDocsQuery(); } + final String minimumShouldMatch; if (context.isFilter() && this.minimumShouldMatch == null && shouldClauses.size() > 0) { minimumShouldMatch = "1"; @@ -349,7 +357,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> { } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { BoolQueryBuilder newBuilder = new BoolQueryBuilder(); boolean changed = false; final int clauses = mustClauses.size() + mustNotClauses.size() + filterClauses.size() + shouldClauses.size(); @@ -372,14 +380,14 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> { return this; } - private static boolean rewriteClauses(QueryRewriteContext queryRewriteContext, List<QueryBuilder<?>> builders, Consumer<QueryBuilder<?>> conusmer) throws IOException { + private static boolean rewriteClauses(QueryRewriteContext queryRewriteContext, List<QueryBuilder<?>> builders, Consumer<QueryBuilder<?>> consumer) throws IOException { boolean changed = false; for (QueryBuilder builder : builders) { QueryBuilder result = builder.rewrite(queryRewriteContext); if (result != builder) { changed = true; } - conusmer.accept(result); + consumer.accept(result); } return changed; } diff --git a/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java index 507e85687d..d03d6894b0 100644 --- a/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java @@ -160,12 +160,11 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder<BoostingQueryBuil } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder positiveQuery = this.positiveQuery.rewrite(queryShardContext); - QueryBuilder negativeQuery = this.negativeQuery.rewrite(queryShardContext); + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder positiveQuery = this.positiveQuery.rewrite(queryRewriteContext); + QueryBuilder negativeQuery = this.negativeQuery.rewrite(queryRewriteContext); if (positiveQuery != this.positiveQuery || negativeQuery != this.negativeQuery) { - BoostingQueryBuilder newQueryBuilder = new BoostingQueryBuilder(positiveQuery, negativeQuery) - .boost(boost()).queryName(queryName()); + BoostingQueryBuilder newQueryBuilder = new BoostingQueryBuilder(positiveQuery, negativeQuery); newQueryBuilder.negativeBoost = negativeBoost; return newQueryBuilder; } diff --git a/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java index ad00bba28b..ee6fa4c2c2 100644 --- a/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java @@ -106,10 +106,10 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder<ConstantScor } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder rewrite = filterBuilder.rewrite(queryShardContext); + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder rewrite = filterBuilder.rewrite(queryRewriteContext); if (rewrite != filterBuilder) { - return new ConstantScoreQueryBuilder(rewrite).boost(boost()).queryName(queryName()); + return new ConstantScoreQueryBuilder(rewrite); } return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java index 83f7abae7a..e810292a95 100644 --- a/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java @@ -20,24 +20,16 @@ package org.elasticsearch.index.query; import org.apache.lucene.search.Query; -import org.elasticsearch.action.support.ToXContentToBytes; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentType; import java.io.IOException; -import java.util.Objects; /** * A {@link QueryBuilder} that is a stand in replacement for an empty query clause in the DSL. * The current DSL allows parsing inner queries / filters like "{ }", in order to have a * valid non-null representation of these clauses that actually do nothing we can use this class. - * - * This builder has no corresponding parser and it is not registered under the query name. It is - * intended to be used internally as a stand-in for nested queries that are left empty and should - * be ignored upstream. */ public final class EmptyQueryBuilder extends AbstractQueryBuilder<EmptyQueryBuilder> { diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java index db64aa3a7d..dd186f92ba 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java @@ -235,7 +235,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil } @Override - protected Query doToQuery(QueryShardContext context) throws IOException { + protected Query doToQuery(QueryShardContext context) { if (shape == null) { throw new UnsupportedOperationException("query must be rewritten first"); } @@ -449,12 +449,11 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil } @Override - public QueryBuilder<GeoShapeQueryBuilder> rewrite(QueryRewriteContext queryShardContext) throws IOException { + protected QueryBuilder<GeoShapeQueryBuilder> doRewrite(QueryRewriteContext queryShardContext) throws IOException { if (this.shape == null) { GetRequest getRequest = new GetRequest(indexedShapeIndex, indexedShapeType, indexedShapeId); ShapeBuilder shape = fetch(queryShardContext.getClient(), getRequest, indexedShapePath); - return new GeoShapeQueryBuilder(this.fieldName, shape).relation(relation).strategy(strategy) - .boost(boost()).queryName(queryName()); + return new GeoShapeQueryBuilder(this.fieldName, shape).relation(relation).strategy(strategy); } return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java index 66c9d77534..940fa89f03 100644 --- a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java @@ -398,15 +398,15 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder rewrite = query.rewrite(queryShardContext); + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder rewrite = query.rewrite(queryRewriteContext); if (rewrite != query) { HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder(type, rewrite); hasChildQueryBuilder.minChildren = minChildren; hasChildQueryBuilder.maxChildren = maxChildren; hasChildQueryBuilder.scoreMode = scoreMode; hasChildQueryBuilder.queryInnerHits = queryInnerHits; - return hasChildQueryBuilder.queryName(queryName()).boost(boost()); + return hasChildQueryBuilder; } return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java index 10ed269a2b..9a3637de3f 100644 --- a/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java @@ -257,13 +257,13 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryShardContext) throws IOException { QueryBuilder rewrite = query.rewrite(queryShardContext); if (rewrite != query) { HasParentQueryBuilder hasParentQueryBuilder = new HasParentQueryBuilder(type, rewrite); hasParentQueryBuilder.score = score; hasParentQueryBuilder.innerHit = innerHit; - return hasParentQueryBuilder.queryName(queryName()).boost(boost()); + return hasParentQueryBuilder; } return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java index c366394976..019e18d134 100644 --- a/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java @@ -142,11 +142,11 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder<IndicesQueryBuilde } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryShardContext) throws IOException { QueryBuilder<?> newInnnerQuery = innerQuery.rewrite(queryShardContext); QueryBuilder<?> newNoMatchQuery = noMatchQuery.rewrite(queryShardContext); if (newInnnerQuery != innerQuery || newNoMatchQuery != noMatchQuery) { - return new IndicesQueryBuilder(innerQuery, indices).noMatchQuery(noMatchQuery).boost(boost()).queryName(queryName()); + return new IndicesQueryBuilder(innerQuery, indices).noMatchQuery(noMatchQuery); } return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java index c08cf205e6..9f6c8b24c4 100644 --- a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java @@ -1052,7 +1052,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { // TODO this needs heavy cleanups before we can rewrite it return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java index 461ebdb52a..596c249921 100644 --- a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java @@ -226,10 +226,10 @@ public class NestedQueryBuilder extends AbstractQueryBuilder<NestedQueryBuilder> } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder rewrite = query.rewrite(queryShardContext); + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder rewrite = query.rewrite(queryRewriteContext); if (rewrite != query) { - return new NestedQueryBuilder(path, rewrite).queryName(queryName()).boost(boost()).scoreMode(scoreMode); + return new NestedQueryBuilder(path, rewrite).scoreMode(scoreMode); } return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java index 3667905bac..f8010e7b52 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java @@ -74,16 +74,16 @@ public interface QueryBuilder<QB extends QueryBuilder<QB>> extends NamedWriteabl String getName(); /** - * Rewrites this query builder into it's primitive form. By default this method return theb builder itself. If the builder - * did not change the identity reference must be returend otherwise the builder will be rewritten infinitely. + * Rewrites this query builder into its primitive form. By default this method return the builder itself. If the builder + * did not change the identity reference must be returned otherwise the builder will be rewritten infinitely. */ default QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { return this; } /** - * Rewrites the given query into it's primitive form. Queries that for instance fetch resources from remote hosts or - * can simplify / optimize itself should do their heavy lifting duringt {@link #rewrite(QueryRewriteContext)}. This method + * Rewrites the given query into its primitive form. Queries that for instance fetch resources from remote hosts or + * can simplify / optimize itself should do their heavy lifting during {@link #rewrite(QueryRewriteContext)}. This method * rewrites the query until it doesn't change anymore. * @throws IOException if an {@link IOException} occurs */ diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java index 425673cb54..e057aff06b 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java @@ -24,6 +24,7 @@ import org.elasticsearch.indices.query.IndicesQueriesRegistry; import org.elasticsearch.script.ScriptService; /** + * Context object used to rewrite {@link QueryBuilder} instances into simplified version. */ public class QueryRewriteContext { protected final ScriptService scriptService; @@ -38,26 +39,34 @@ public class QueryRewriteContext { this.parseContext = new QueryParseContext(indicesQueriesRegistry); } + /** + * Returns a clients to fetch resources from local or remove nodes. + */ public final Client getClient() { return scriptService.getClient(); } + /** + * Returns the index settings for this context. This might return null if the + * context has not index scope. + */ public final IndexSettings getIndexSettings() { return indexSettings; } + /** + * Returns a script service to fetch scripts. + */ public final ScriptService getScriptService() { return scriptService; } + /** + * Returns a new {@link QueryParseContext} to parse template or wrapped queries. + */ public QueryParseContext newParseContext() { QueryParseContext queryParseContext = new QueryParseContext(indicesQueriesRegistry); queryParseContext.parseFieldMatcher(parseContext.parseFieldMatcher()); return queryParseContext; } - - public boolean hasIndex() { - return indexSettings != null; - } - } diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java index 09978122dc..83066fba7b 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java @@ -191,10 +191,6 @@ public class QueryShardContext extends QueryRewriteContext { return unmodifiableMap(new HashMap<>(namedQueries)); } - public void combineNamedQueries(QueryShardContext context) { - namedQueries.putAll(context.namedQueries); - } - /** * Return whether we are currently parsing a filter or a query. */ diff --git a/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java index 31484fe804..353dbd668a 100644 --- a/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java @@ -25,7 +25,6 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.RandomAccessWeight; import org.apache.lucene.search.Weight; import org.apache.lucene.util.Bits; -import org.elasticsearch.client.Client; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -33,7 +32,6 @@ import org.elasticsearch.script.LeafSearchScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.Script.ScriptField; import org.elasticsearch.script.ScriptContext; -import org.elasticsearch.script.ScriptEngineService; import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.SearchScript; import org.elasticsearch.search.lookup.SearchLookup; diff --git a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java index 4067f6d87c..4b3e81ebf1 100644 --- a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java @@ -127,7 +127,7 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { ExecutableScript executable = queryRewriteContext.getScriptService().executable(template, ScriptContext.Standard.SEARCH, Collections.emptyMap()); BytesReference querySource = (BytesReference) executable.run(); @@ -135,11 +135,10 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil try (XContentParser qSourceParser = XContentFactory.xContent(querySource).createParser(querySource)) { queryParseContext.reset(qSourceParser); final QueryBuilder<?> queryBuilder = queryParseContext.parseInnerQueryBuilder(); - if (queryBuilder.boost() == DEFAULT_BOOST) { - queryBuilder.boost(boost()); // only pass down the boost if it has it's own boost - } - if (queryName() != null) { - queryBuilder.queryName(queryName()); + if (boost() != DEFAULT_BOOST || queryName() != null) { + final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.must(queryBuilder); + return boolQueryBuilder; } return queryBuilder; } diff --git a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java index 570fc76dab..e75d982ebe 100644 --- a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java @@ -316,18 +316,18 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> { } @Override - public QueryBuilder<TermsQueryBuilder> rewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { if (this.termsLookup != null) { TermsLookup termsLookup = new TermsLookup(this.termsLookup); if (termsLookup.index() == null) { // TODO this should go away? - if (queryRewriteContext.hasIndex()) { + if (queryRewriteContext.getIndexSettings() != null) { termsLookup.index(queryRewriteContext.getIndexSettings().getIndex().getName()); } else { return this; // can't rewrite until we have index scope on the shard } } List<Object> values = fetch(termsLookup, queryRewriteContext.getClient()); - return new TermsQueryBuilder(this.fieldName, values).boost(boost()).queryName(queryName()); + return new TermsQueryBuilder(this.fieldName, values); } return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java index 6ba07f766e..6c7ac0e908 100644 --- a/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java @@ -105,7 +105,7 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder<WrapperQueryBuilde @Override protected Query doToQuery(QueryShardContext context) throws IOException { - throw new UnsupportedOperationException("this query must be rewritten first"); + throw new UnsupportedOperationException("this query must be rewritten first"); } @Override @@ -129,17 +129,16 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder<WrapperQueryBuilde } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext context) throws IOException { + protected QueryBuilder<?> doRewrite(QueryRewriteContext context) throws IOException { try (XContentParser qSourceParser = XContentFactory.xContent(source).createParser(source)) { QueryParseContext parseContext = context.newParseContext(); parseContext.reset(qSourceParser); final QueryBuilder<?> queryBuilder = parseContext.parseInnerQueryBuilder(); - if (queryBuilder.boost() == DEFAULT_BOOST) { - queryBuilder.boost(boost()); - } - if (queryName() != null) { // we inherit the name - queryBuilder.queryName(queryName()); + if (boost() != DEFAULT_BOOST || queryName() != null) { + final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.must(queryBuilder); + return boolQueryBuilder; } return queryBuilder; } diff --git a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java index 14a2826084..60959a9789 100644 --- a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java @@ -394,17 +394,32 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor public FilterFunctionBuilder readFrom(StreamInput in) throws IOException { return new FilterFunctionBuilder(in.readQuery(), in.readScoreFunction()); } + + public FilterFunctionBuilder rewrite(QueryRewriteContext context) throws IOException { + QueryBuilder<?> rewrite = filter.rewrite(context); + if (rewrite != filter) { + return new FilterFunctionBuilder(rewrite, scoreFunction); + } + return this; + } } @Override - public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder<?> queryBuilder = this.query.rewrite(queryShardContext); - if (queryBuilder != query) { - FunctionScoreQueryBuilder newQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, filterFunctionBuilders); + protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder<?> queryBuilder = this.query.rewrite(queryRewriteContext); + FilterFunctionBuilder[] rewrittenBuilders = new FilterFunctionBuilder[this.filterFunctionBuilders.length]; + boolean rewritten = false; + for (int i = 0; i < rewrittenBuilders.length; i++) { + FilterFunctionBuilder rewrite = filterFunctionBuilders[i].rewrite(queryRewriteContext); + rewritten |= rewrite != filterFunctionBuilders[i]; + rewrittenBuilders[i] = rewrite; + } + if (queryBuilder != query || rewritten) { + FunctionScoreQueryBuilder newQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, rewrittenBuilders); newQueryBuilder.scoreMode = scoreMode; newQueryBuilder.minScore = minScore; newQueryBuilder.maxBoost = maxBoost; - return newQueryBuilder.queryName(queryName()).boost(boost()); + return newQueryBuilder; } return this; } diff --git a/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java b/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java index 5b8550b7b1..19e2cab044 100644 --- a/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java +++ b/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java @@ -554,6 +554,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>> private QueryBuilder<?> rewriteQuery(QB queryBuilder, QueryRewriteContext rewriteContext) throws IOException { QueryBuilder<?> rewritten = QueryBuilder.rewriteQuery(queryBuilder, rewriteContext); + // extra safety to fail fast - serialize the rewritten version to ensure it's serializable. assertSerialization(rewritten); return rewritten; } @@ -975,4 +976,16 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>> } return ""; } + + /** + * This test ensures that queries that need to be rewritten have dedicated tests. + * These queries must override this method accordingly. + */ + public void testMustRewrite() throws IOException { + QueryShardContext context = createShardContext(); + context.setAllowUnmappedFields(true); + QB queryBuilder = createTestQueryBuilder(); + setSearchContext(randomTypes); // only set search context for toQuery to be more realistic + queryBuilder.toQuery(context); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java index 30dbcdf4b6..7b3f3ecb7f 100644 --- a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java @@ -195,14 +195,14 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde public void testDefaultMinShouldMatch() throws Exception { // Queries have a minShouldMatch of 0 - BooleanQuery bq = (BooleanQuery) parseQuery(boolQuery().must(termQuery("foo", "bar")).buildAsBytes()).toQuery(createShardContext()); + BooleanQuery bq = (BooleanQuery) parseQuery(boolQuery().filter(termQuery("foo", "bar")).buildAsBytes()).toQuery(createShardContext()); assertEquals(0, bq.getMinimumNumberShouldMatch()); bq = (BooleanQuery) parseQuery(boolQuery().should(termQuery("foo", "bar")).buildAsBytes()).toQuery(createShardContext()); assertEquals(0, bq.getMinimumNumberShouldMatch()); // Filters have a minShouldMatch of 0/1 - ConstantScoreQuery csq = (ConstantScoreQuery) parseQuery(constantScoreQuery(boolQuery().must(termQuery("foo", "bar"))).buildAsBytes()).toQuery(createShardContext()); + ConstantScoreQuery csq = (ConstantScoreQuery) parseQuery(constantScoreQuery(boolQuery().filter(termQuery("foo", "bar"))).buildAsBytes()).toQuery(createShardContext()); bq = (BooleanQuery) csq.getQuery(); assertEquals(0, bq.getMinimumNumberShouldMatch()); @@ -213,7 +213,7 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde public void testMinShouldMatchFilterWithoutShouldClauses() throws Exception { BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); - boolQueryBuilder.filter(new BoolQueryBuilder().must(new MatchAllQueryBuilder())); + boolQueryBuilder.filter(new BoolQueryBuilder().filter(new MatchAllQueryBuilder())); Query query = boolQueryBuilder.toQuery(createShardContext()); assertThat(query, instanceOf(BooleanQuery.class)); BooleanQuery booleanQuery = (BooleanQuery) query; @@ -227,7 +227,7 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde assertThat(innerBooleanQuery.getMinimumNumberShouldMatch(), equalTo(0)); assertThat(innerBooleanQuery.clauses().size(), equalTo(1)); BooleanClause innerBooleanClause = innerBooleanQuery.clauses().get(0); - assertThat(innerBooleanClause.getOccur(), equalTo(BooleanClause.Occur.MUST)); + assertThat(innerBooleanClause.getOccur(), equalTo(BooleanClause.Occur.FILTER)); assertThat(innerBooleanClause.getQuery(), instanceOf(MatchAllDocsQuery.class)); } @@ -343,4 +343,70 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde assertEquals(query, "23", queryBuilder.minimumShouldMatch()); assertEquals(query, "kimchy", ((TermQueryBuilder)queryBuilder.must().get(0)).value()); } + + public void testRewrite() throws IOException { + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolean mustRewrite = false; + if (randomBoolean()) { + mustRewrite = true; + boolQueryBuilder.must(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "must").toString())); + } + if (randomBoolean()) { + mustRewrite = true; + boolQueryBuilder.should(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "should").toString())); + } + if (randomBoolean()) { + mustRewrite = true; + boolQueryBuilder.filter(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "filter").toString())); + } + if (randomBoolean()) { + mustRewrite = true; + boolQueryBuilder.mustNot(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "must_not").toString())); + } + if (mustRewrite == false && randomBoolean()) { + boolQueryBuilder.must(new TermsQueryBuilder("foo", "no_rewrite")); + } + QueryBuilder<?> rewritten = boolQueryBuilder.rewrite(queryShardContext()); + if (mustRewrite == false && boolQueryBuilder.must().isEmpty()) { + // if it's empty we rewrite to match all + assertEquals(rewritten, new MatchAllQueryBuilder()); + } else { + BoolQueryBuilder rewrite = (BoolQueryBuilder) rewritten; + if (mustRewrite) { + assertNotSame(rewrite, boolQueryBuilder); + if (boolQueryBuilder.must().isEmpty() == false) { + assertEquals(new TermsQueryBuilder("foo", "must"), rewrite.must().get(0)); + } + if (boolQueryBuilder.should().isEmpty() == false) { + assertEquals(new TermsQueryBuilder("foo", "should"), rewrite.should().get(0)); + } + if (boolQueryBuilder.mustNot().isEmpty() == false) { + assertEquals(new TermsQueryBuilder("foo", "must_not"), rewrite.mustNot().get(0)); + } + if (boolQueryBuilder.filter().isEmpty() == false) { + assertEquals(new TermsQueryBuilder("foo", "filter"), rewrite.filter().get(0)); + } + } else { + assertSame(rewrite, boolQueryBuilder); + if (boolQueryBuilder.must().isEmpty() == false) { + assertSame(boolQueryBuilder.must().get(0), rewrite.must().get(0)); + } + } + } + } + + public void testRewriteMultipleTimes() throws IOException { + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.must(new WrapperQueryBuilder(new WrapperQueryBuilder(new MatchAllQueryBuilder().toString()).toString())); + QueryBuilder<?> rewritten = boolQueryBuilder.rewrite(queryShardContext()); + BoolQueryBuilder expected = new BoolQueryBuilder(); + expected.must(new WrapperQueryBuilder(new MatchAllQueryBuilder().toString())); + assertEquals(expected, rewritten); + + expected = new BoolQueryBuilder(); + expected.must(new MatchAllQueryBuilder()); + QueryBuilder<?> rewrittenAgain = rewritten.rewrite(queryShardContext()); + assertEquals(rewrittenAgain, expected); + assertEquals(QueryBuilder.rewriteQuery(boolQueryBuilder, queryShardContext()), expected); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java index f7f50136f7..414ab1f113 100644 --- a/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.index.query; import org.apache.lucene.queries.BoostingQuery; +import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.Query; import java.io.IOException; @@ -72,27 +73,27 @@ public class BoostingQueryBuilderTests extends AbstractQueryTestCase<BoostingQue public void testFromJson() throws IOException { String query = - "{\n" + - " \"boosting\" : {\n" + - " \"positive\" : {\n" + - " \"term\" : {\n" + - " \"field1\" : {\n" + - " \"value\" : \"value1\",\n" + - " \"boost\" : 5.0\n" + - " }\n" + - " }\n" + - " },\n" + - " \"negative\" : {\n" + - " \"term\" : {\n" + - " \"field2\" : {\n" + - " \"value\" : \"value2\",\n" + - " \"boost\" : 8.0\n" + - " }\n" + - " }\n" + - " },\n" + - " \"negative_boost\" : 23.0,\n" + - " \"boost\" : 42.0\n" + - " }\n" + + "{\n" + + " \"boosting\" : {\n" + + " \"positive\" : {\n" + + " \"term\" : {\n" + + " \"field1\" : {\n" + + " \"value\" : \"value1\",\n" + + " \"boost\" : 5.0\n" + + " }\n" + + " }\n" + + " },\n" + + " \"negative\" : {\n" + + " \"term\" : {\n" + + " \"field2\" : {\n" + + " \"value\" : \"value2\",\n" + + " \"boost\" : 8.0\n" + + " }\n" + + " }\n" + + " },\n" + + " \"negative_boost\" : 23.0,\n" + + " \"boost\" : 42.0\n" + + " }\n" + "}"; BoostingQueryBuilder queryBuilder = (BoostingQueryBuilder) parseQuery(query); @@ -103,4 +104,17 @@ public class BoostingQueryBuilderTests extends AbstractQueryTestCase<BoostingQue assertEquals(query, 8, queryBuilder.negativeQuery().boost(), 0.00001); assertEquals(query, 5, queryBuilder.positiveQuery().boost(), 0.00001); } + + public void testRewrite() throws IOException { + QueryBuilder positive = randomBoolean() ? new MatchAllQueryBuilder() : new WrapperQueryBuilder(new TermQueryBuilder("pos", "bar").toString()); + QueryBuilder negative = randomBoolean() ? new MatchAllQueryBuilder() : new WrapperQueryBuilder(new TermQueryBuilder("neg", "bar").toString()); + BoostingQueryBuilder qb = new BoostingQueryBuilder(positive, negative); + QueryBuilder<?> rewrite = qb.rewrite(queryShardContext()); + if (positive instanceof MatchAllQueryBuilder && negative instanceof MatchAllQueryBuilder) { + assertSame(rewrite, qb); + } else { + assertNotSame(rewrite, qb); + assertEquals(new BoostingQueryBuilder(positive.rewrite(queryShardContext()), negative.rewrite(queryShardContext())), rewrite); + } + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java index 290a05d1fa..410db8fc04 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java @@ -468,4 +468,10 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo assertEquals(json, 1.0, parsed.boost(), 0.0001); assertEquals(json, GeoExecType.MEMORY, parsed.type()); } + + @Override + public void testMustRewrite() throws IOException { + assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0); + super.testMustRewrite(); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java index e7b2d862f5..3d1f02c2e6 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java @@ -411,4 +411,10 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDista assertEquals(json, 40.0, parsed.point().getLat(), 0.0001); assertEquals(json, 12000.0, parsed.distance(), 0.0001); } + + @Override + public void testMustRewrite() throws IOException { + assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0); + super.testMustRewrite(); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java index 6d9095017b..f07e695a1a 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java @@ -316,4 +316,10 @@ public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanc checkGeneratedJson(json, parsed); assertEquals(json, -70.0, parsed.point().lon(), 0.0001); } + + @Override + public void testMustRewrite() throws IOException { + assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0); + super.testMustRewrite(); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoPolygonQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoPolygonQueryBuilderTests.java index ea16187f6d..7ab6275388 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoPolygonQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoPolygonQueryBuilderTests.java @@ -343,4 +343,10 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygo checkGeneratedJson(json, parsed); assertEquals(json, 4, parsed.points().size()); } + + @Override + public void testMustRewrite() throws IOException { + assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0); + super.testMustRewrite(); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java index 93193cf11e..533ce3bfb0 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java @@ -240,4 +240,24 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue checkGeneratedJson(json, parsed); assertEquals(json, 42.0, parsed.boost(), 0.0001); } + + @Override + public void testMustRewrite() throws IOException { + GeoShapeQueryBuilder sqb; + do { + sqb = doCreateTestQueryBuilder(); + // do this until we get one without a shape + } while (sqb.shape() != null); + try { + sqb.toQuery(queryShardContext()); + fail(); + } catch (UnsupportedOperationException e) { + assertEquals("query must be rewritten first", e.getMessage()); + } + QueryBuilder<?> rewrite = sqb.rewrite(queryShardContext()); + GeoShapeQueryBuilder geoShapeQueryBuilder = new GeoShapeQueryBuilder(GEO_SHAPE_FIELD_NAME, indexedShapeToReturn); + geoShapeQueryBuilder.strategy(sqb.strategy()); + geoShapeQueryBuilder.relation(sqb.relation()); + assertEquals(geoShapeQueryBuilder, rewrite); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeohashCellQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeohashCellQueryBuilderTests.java index bdc892605d..bf71e73aa4 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeohashCellQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeohashCellQueryBuilderTests.java @@ -145,4 +145,10 @@ public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder> checkGeneratedJson(json, parsed); assertEquals(json, 3, parsed.precision().intValue()); } + + @Override + public void testMustRewrite() throws IOException { + assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0); + super.testMustRewrite(); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java index 7a602f0941..c111684b25 100644 --- a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java @@ -22,6 +22,7 @@ package org.elasticsearch.index.query; import org.apache.lucene.search.Query; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.script.Script.ScriptParseException; import org.elasticsearch.script.ScriptService.ScriptType; @@ -29,6 +30,7 @@ import org.elasticsearch.script.Template; import org.junit.BeforeClass; import java.io.IOException; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -118,4 +120,40 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase<TemplateQue XContentType.JSON, params)); assertParsedQuery(query, expectedBuilder); } + + @Override + public void testMustRewrite() throws IOException { + String query = "{ \"match_all\" : {}}"; + QueryBuilder<?> builder = new TemplateQueryBuilder(new Template(query, ScriptType.INLINE, "mockscript", + XContentType.JSON, Collections.emptyMap())); + try { + builder.toQuery(queryShardContext()); + fail(); + } catch (UnsupportedOperationException ex) { + assertEquals("this query must be rewritten first", ex.getMessage()); + } + assertEquals(new MatchAllQueryBuilder(), builder.rewrite(queryShardContext())); + } + + public void testRewriteWithInnerName() throws IOException { + final String query = "{ \"match_all\" : {\"_name\" : \"foobar\"}}"; + QueryBuilder<?> builder = new TemplateQueryBuilder(new Template(query, ScriptType.INLINE, "mockscript", + XContentType.JSON, Collections.emptyMap())); + assertEquals(new MatchAllQueryBuilder().queryName("foobar"), builder.rewrite(queryShardContext())); + + builder = new TemplateQueryBuilder(new Template(query, ScriptType.INLINE, "mockscript", + XContentType.JSON, Collections.emptyMap())).queryName("outer"); + assertEquals(new BoolQueryBuilder().must(new MatchAllQueryBuilder().queryName("foobar")).queryName("outer"), builder.rewrite(queryShardContext())); + } + + public void testRewriteWithInnerBoost() throws IOException { + final TermQueryBuilder query = new TermQueryBuilder("foo", "bar").boost(2); + QueryBuilder<?> builder = new TemplateQueryBuilder(new Template(query.toString(), ScriptType.INLINE, "mockscript", + XContentType.JSON, Collections.emptyMap())); + assertEquals(query, builder.rewrite(queryShardContext())); + + builder = new TemplateQueryBuilder(new Template(query.toString(), ScriptType.INLINE, "mockscript", + XContentType.JSON, Collections.emptyMap())).boost(3); + assertEquals(new BoolQueryBuilder().must(query).boost(3), builder.rewrite(queryShardContext())); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java index 7224133028..9156108c63 100644 --- a/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java @@ -272,5 +272,17 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil assertEquals(json, 2, parsed.values().size()); } + + @Override + public void testMustRewrite() throws IOException { + TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder(STRING_FIELD_NAME, randomTermsLookup()); + try { + termsQueryBuilder.toQuery(queryShardContext()); + fail(); + } catch (UnsupportedOperationException ex) { + assertEquals("query must be rewritten first", ex.getMessage()); + } + assertEquals(termsQueryBuilder.rewrite(queryShardContext()), new TermsQueryBuilder(STRING_FIELD_NAME, randomTerms)); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java index 4f0b3e7343..be0df23cf1 100644 --- a/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java @@ -133,4 +133,34 @@ public class WrapperQueryBuilderTests extends AbstractQueryTestCase<WrapperQuery throw new RuntimeException(e); } } + + @Override + public void testMustRewrite() throws IOException { + TermQueryBuilder tqb = new TermQueryBuilder("foo", "bar"); + WrapperQueryBuilder qb = new WrapperQueryBuilder(tqb.toString()); + try { + qb.toQuery(queryShardContext()); + fail(); + } catch (UnsupportedOperationException e) { + assertEquals("this query must be rewritten first", e.getMessage()); + } + QueryBuilder<?> rewrite = qb.rewrite(queryShardContext()); + assertEquals(tqb, rewrite); + } + + public void testRewriteWithInnerName() throws IOException { + QueryBuilder<?> builder = new WrapperQueryBuilder("{ \"match_all\" : {\"_name\" : \"foobar\"}}"); + assertEquals(new MatchAllQueryBuilder().queryName("foobar"), builder.rewrite(queryShardContext())); + builder = new WrapperQueryBuilder("{ \"match_all\" : {\"_name\" : \"foobar\"}}").queryName("outer"); + assertEquals(new BoolQueryBuilder().must(new MatchAllQueryBuilder().queryName("foobar")).queryName("outer"), builder.rewrite(queryShardContext())); + } + + public void testRewriteWithInnerBoost() throws IOException { + final TermQueryBuilder query = new TermQueryBuilder("foo", "bar").boost(2); + QueryBuilder<?> builder = new WrapperQueryBuilder(query.toString()); + assertEquals(query, builder.rewrite(queryShardContext())); + builder = new WrapperQueryBuilder(query.toString()).boost(3); + assertEquals(new BoolQueryBuilder().must(query).boost(3), builder.rewrite(queryShardContext())); + } + } |