summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java2
-rw-r--r--core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java6
-rw-r--r--core/src/main/java/org/elasticsearch/index/IndexService.java2
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java37
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java13
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java9
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java52
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java25
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java15
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java13
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java10
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java6
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java8
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java24
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java2
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java63
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java55
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java2
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java32
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java36
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java26
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java14
-rw-r--r--core/src/main/java/org/elasticsearch/index/query/support/NestedInnerQueryParseSupport.java7
-rw-r--r--core/src/main/java/org/elasticsearch/index/shard/IndexShard.java2
-rw-r--r--core/src/main/java/org/elasticsearch/script/ScriptService.java4
-rw-r--r--core/src/main/java/org/elasticsearch/search/SearchService.java4
-rw-r--r--core/src/main/java/org/elasticsearch/search/action/SearchServiceTransportAction.java1
-rw-r--r--core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java14
-rw-r--r--core/src/main/java/org/elasticsearch/search/highlight/HighlightBuilder.java2
-rw-r--r--core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java4
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java41
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java5
-rw-r--r--core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java2
-rw-r--r--core/src/test/java/org/elasticsearch/percolator/PercolateDocumentParserTests.java2
-rw-r--r--core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java15
-rw-r--r--core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java2
-rw-r--r--core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java4
-rw-r--r--core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java2
38 files changed, 414 insertions, 149 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 c106cd1d4e..77afd12364 100644
--- a/core/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
+++ b/core/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
@@ -33,6 +33,7 @@ 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;
@@ -90,7 +91,6 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
logger.debug("failed to optimize search type, continue as normal", e);
}
}
-
if (searchRequest.searchType() == DFS_QUERY_THEN_FETCH) {
dfsQueryThenFetchAction.execute(searchRequest, listener);
} else if (searchRequest.searchType() == SearchType.QUERY_THEN_FETCH) {
diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
index 091fde6dec..e60bafedd6 100644
--- a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
+++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
@@ -27,6 +27,8 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.Index;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.indices.InvalidAliasNameException;
@@ -143,7 +145,9 @@ public class AliasValidator extends AbstractComponent {
private void validateAliasFilter(XContentParser parser, QueryShardContext queryShardContext) throws IOException {
try {
queryShardContext.reset(parser);
- queryShardContext.parseContext().parseInnerQueryBuilder().toFilter(queryShardContext);
+ QueryParseContext queryParseContext = queryShardContext.parseContext();
+ QueryBuilder<?> queryBuilder = QueryBuilder.rewriteQuery(queryParseContext.parseInnerQueryBuilder(), queryShardContext);
+ queryBuilder.toFilter(queryShardContext);
} finally {
queryShardContext.reset(null);
parser.close();
diff --git a/core/src/main/java/org/elasticsearch/index/IndexService.java b/core/src/main/java/org/elasticsearch/index/IndexService.java
index 9ffb6c4d56..0048f2a98a 100644
--- a/core/src/main/java/org/elasticsearch/index/IndexService.java
+++ b/core/src/main/java/org/elasticsearch/index/IndexService.java
@@ -421,7 +421,7 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
* Creates a new QueryShardContext. The context has not types set yet, if types are required set them via {@link QueryShardContext#setTypes(String...)}
*/
public QueryShardContext newQueryShardContext() {
- return new QueryShardContext(indexSettings, nodeServicesProvider.getClient(), indexCache.bitsetFilterCache(), indexFieldData, mapperService(), similarityService(), nodeServicesProvider.getScriptService(), nodeServicesProvider.getIndicesQueriesRegistry());
+ return new QueryShardContext(indexSettings, indexCache.bitsetFilterCache(), indexFieldData, mapperService(), similarityService(), nodeServicesProvider.getScriptService(), nodeServicesProvider.getIndicesQueriesRegistry());
}
ThreadPool getThreadPool() {
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 f7f4926d95..72e13c2c31 100644
--- a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
@@ -33,6 +33,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.function.Consumer;
import static org.elasticsearch.common.lucene.search.Queries.fixNegativeQueryIfNeeded;
@@ -346,4 +347,40 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
out.writeBoolean(disableCoord);
out.writeOptionalString(minimumShouldMatch);
}
+
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryRewriteContext) throws IOException {
+ BoolQueryBuilder newBuilder = new BoolQueryBuilder();
+ boolean changed = false;
+ final int clauses = mustClauses.size() + mustNotClauses.size() + filterClauses.size() + shouldClauses.size();
+ if (clauses == 0) {
+ return new MatchAllQueryBuilder().boost(boost()).queryName(queryName());
+ }
+ changed |= rewriteClauses(queryRewriteContext, mustClauses, newBuilder::must);
+ changed |= rewriteClauses(queryRewriteContext, mustNotClauses, newBuilder::mustNot);
+ changed |= rewriteClauses(queryRewriteContext, filterClauses, newBuilder::filter);
+ changed |= rewriteClauses(queryRewriteContext, shouldClauses, newBuilder::should);
+
+ if (changed) {
+ newBuilder.adjustPureNegative = adjustPureNegative;
+ newBuilder.disableCoord = disableCoord;
+ newBuilder.minimumShouldMatch = minimumShouldMatch;
+ newBuilder.boost(boost());
+ newBuilder.queryName(queryName());
+ return newBuilder;
+ }
+ return this;
+ }
+
+ private static boolean rewriteClauses(QueryRewriteContext queryRewriteContext, List<QueryBuilder<?>> builders, Consumer<QueryBuilder<?>> conusmer) throws IOException {
+ boolean changed = false;
+ for (QueryBuilder builder : builders) {
+ QueryBuilder result = builder.rewrite(queryRewriteContext);
+ if (result != builder) {
+ changed = true;
+ }
+ conusmer.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 50346c2d36..507e85687d 100644
--- a/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
@@ -158,4 +158,17 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder<BoostingQueryBuil
out.writeQuery(negativeQuery);
out.writeFloat(negativeBoost);
}
+
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException {
+ QueryBuilder positiveQuery = this.positiveQuery.rewrite(queryShardContext);
+ QueryBuilder negativeQuery = this.negativeQuery.rewrite(queryShardContext);
+ if (positiveQuery != this.positiveQuery || negativeQuery != this.negativeQuery) {
+ BoostingQueryBuilder newQueryBuilder = new BoostingQueryBuilder(positiveQuery, negativeQuery)
+ .boost(boost()).queryName(queryName());
+ newQueryBuilder.negativeBoost = negativeBoost;
+ return newQueryBuilder;
+ }
+ return this;
+ }
}
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 4b054a34d4..ad00bba28b 100644
--- a/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
@@ -104,4 +104,13 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder<ConstantScor
protected void doWriteTo(StreamOutput out) throws IOException {
out.writeQuery(filterBuilder);
}
+
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException {
+ QueryBuilder rewrite = filterBuilder.rewrite(queryShardContext);
+ if (rewrite != filterBuilder) {
+ return new ConstantScoreQueryBuilder(rewrite).boost(boost()).queryName(queryName());
+ }
+ 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 7d1761a44b..83f7abae7a 100644
--- a/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/EmptyQueryBuilder.java
@@ -23,10 +23,12 @@ 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.
@@ -37,75 +39,49 @@ import java.io.IOException;
* intended to be used internally as a stand-in for nested queries that are left empty and should
* be ignored upstream.
*/
-public class EmptyQueryBuilder extends ToXContentToBytes implements QueryBuilder<EmptyQueryBuilder> {
+public final class EmptyQueryBuilder extends AbstractQueryBuilder<EmptyQueryBuilder> {
public static final String NAME = "empty_query";
/** the one and only empty query builder */
public static final EmptyQueryBuilder PROTOTYPE = new EmptyQueryBuilder();
- // prevent instances other than prototype
- private EmptyQueryBuilder() {
- super(XContentType.JSON);
- }
-
@Override
public String getWriteableName() {
return NAME;
}
@Override
- public String getName() {
- return getWriteableName();
- }
-
- @Override
- public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
- builder.startObject();
- builder.endObject();
- return builder;
- }
-
- @Override
- public Query toQuery(QueryShardContext context) throws IOException {
- // empty
+ protected Query doToQuery(QueryShardContext context) throws IOException {
return null;
}
@Override
- public Query toFilter(QueryShardContext context) throws IOException {
- // empty
- return null;
+ public String getName() {
+ return getWriteableName();
}
@Override
- public void writeTo(StreamOutput out) throws IOException {
+ protected void doXContent(XContentBuilder builder, Params params) throws IOException {
}
@Override
- public EmptyQueryBuilder readFrom(StreamInput in) throws IOException {
- return EmptyQueryBuilder.PROTOTYPE;
+ protected void doWriteTo(StreamOutput out) throws IOException {
}
- @Override
- public EmptyQueryBuilder queryName(String queryName) {
- //no-op
- return this;
- }
@Override
- public String queryName() {
- return null;
+ protected EmptyQueryBuilder doReadFrom(StreamInput in) throws IOException {
+ return new EmptyQueryBuilder();
}
@Override
- public float boost() {
- return -1;
+ protected int doHashCode() {
+ return 31;
}
@Override
- public EmptyQueryBuilder boost(float boost) {
- //no-op
- return this;
+ protected boolean doEquals(EmptyQueryBuilder other) {
+ return true;
}
}
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 f7d8b22d78..db64aa3a7d 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
@@ -43,7 +43,6 @@ import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.geo.GeoShapeFieldMapper;
-import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
import java.util.Objects;
@@ -62,7 +61,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
private final String fieldName;
- private ShapeBuilder shape;
+ private final ShapeBuilder shape;
private SpatialStrategy strategy;
@@ -237,12 +236,11 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
- ShapeBuilder shapeToQuery = shape;
- if (shapeToQuery == null) {
- GetRequest getRequest = new GetRequest(indexedShapeIndex, indexedShapeType, indexedShapeId);
- shapeToQuery = fetch(context.getClient(), getRequest, indexedShapePath);
+ if (shape == null) {
+ throw new UnsupportedOperationException("query must be rewritten first");
}
- MappedFieldType fieldType = context.fieldMapper(fieldName);
+ final ShapeBuilder shapeToQuery = shape;
+ final MappedFieldType fieldType = context.fieldMapper(fieldName);
if (fieldType == null) {
throw new QueryShardException(context, "Failed to find geo_shape field [" + fieldName + "]");
}
@@ -252,7 +250,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
throw new QueryShardException(context, "Field [" + fieldName + "] is not a geo_shape");
}
- GeoShapeFieldMapper.GeoShapeFieldType shapeFieldType = (GeoShapeFieldMapper.GeoShapeFieldType) fieldType;
+ final GeoShapeFieldMapper.GeoShapeFieldType shapeFieldType = (GeoShapeFieldMapper.GeoShapeFieldType) fieldType;
PrefixTreeStrategy strategy = shapeFieldType.defaultStrategy();
if (this.strategy != null) {
@@ -449,4 +447,15 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
public String getWriteableName() {
return NAME;
}
+
+ @Override
+ public QueryBuilder<GeoShapeQueryBuilder> rewrite(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 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 c84883fe73..66c9d77534 100644
--- a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
@@ -26,7 +26,6 @@ import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.join.JoinUtil;
import org.apache.lucene.search.join.ScoreMode;
-import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.search.Queries;
@@ -397,4 +396,18 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
out.writeBoolean(false);
}
}
+
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException {
+ QueryBuilder rewrite = query.rewrite(queryShardContext);
+ 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 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 173d6aa00c..10ed269a2b 100644
--- a/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
@@ -22,7 +22,6 @@ import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.join.ScoreMode;
-import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.search.Queries;
@@ -256,4 +255,16 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu
protected int doHashCode() {
return Objects.hash(query, type, score, innerHit);
}
+
+ @Override
+ public QueryBuilder<?> rewrite(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 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 5185dfda3b..c366394976 100644
--- a/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
@@ -140,4 +140,14 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder<IndicesQueryBuilde
Arrays.equals(indices, other.indices) && // otherwise we are comparing pointers
Objects.equals(noMatchQuery, other.noMatchQuery);
}
+
+ @Override
+ public QueryBuilder<?> rewrite(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 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 0e98b2042a..c08cf205e6 100644
--- a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
@@ -1050,4 +1050,10 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
Objects.equals(include, other.include) &&
Objects.equals(failOnUnsupportedField, other.failOnUnsupportedField);
}
+
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) 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 103f957b24..461ebdb52a 100644
--- a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
@@ -225,4 +225,12 @@ public class NestedQueryBuilder extends AbstractQueryBuilder<NestedQueryBuilder>
return new ToParentBlockJoinQuery(Queries.filtered(innerQuery, childFilter), parentFilter, scoreMode);
}
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException {
+ QueryBuilder rewrite = query.rewrite(queryShardContext);
+ if (rewrite != query) {
+ return new NestedQueryBuilder(path, rewrite).queryName(queryName()).boost(boost()).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 b75406c864..3667905bac 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java
@@ -72,4 +72,28 @@ public interface QueryBuilder<QB extends QueryBuilder<QB>> extends NamedWriteabl
* Returns the name that identifies uniquely the query
*/
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.
+ */
+ 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 query until it doesn't change anymore.
+ * @throws IOException if an {@link IOException} occurs
+ */
+ static QueryBuilder<?> rewriteQuery(QueryBuilder<?> original, QueryRewriteContext context) throws IOException {
+ QueryBuilder builder = original;
+ for (QueryBuilder rewrittenBuilder = builder.rewrite(context); rewrittenBuilder != builder;
+ rewrittenBuilder = builder.rewrite(context)) {
+ builder = rewrittenBuilder;
+ }
+ return builder;
+ }
+
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java
index 78d76d8292..439e6533de 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java
@@ -106,7 +106,7 @@ public class QueryParseContext {
token = parser.nextToken();
if (token == XContentParser.Token.END_OBJECT) {
// empty query
- return EmptyQueryBuilder.PROTOTYPE;
+ return new EmptyQueryBuilder();
}
if (token != XContentParser.Token.FIELD_NAME) {
throw new ParsingException(parser.getTokenLocation(), "[_na] query malformed, no field after start_object");
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java
new file mode 100644
index 0000000000..425673cb54
--- /dev/null
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java
@@ -0,0 +1,63 @@
+/*
+ * 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.client.Client;
+import org.elasticsearch.index.IndexSettings;
+import org.elasticsearch.indices.query.IndicesQueriesRegistry;
+import org.elasticsearch.script.ScriptService;
+
+/**
+ */
+public class QueryRewriteContext {
+ protected final ScriptService scriptService;
+ protected final IndexSettings indexSettings;
+ protected final IndicesQueriesRegistry indicesQueriesRegistry;
+ protected final QueryParseContext parseContext;
+
+ public QueryRewriteContext(IndexSettings indexSettings, ScriptService scriptService, IndicesQueriesRegistry indicesQueriesRegistry) {
+ this.scriptService = scriptService;
+ this.indexSettings = indexSettings;
+ this.indicesQueriesRegistry = indicesQueriesRegistry;
+ this.parseContext = new QueryParseContext(indicesQueriesRegistry);
+ }
+
+ public final Client getClient() {
+ return scriptService.getClient();
+ }
+
+ public final IndexSettings getIndexSettings() {
+ return indexSettings;
+ }
+
+ public final ScriptService getScriptService() {
+ return scriptService;
+ }
+
+ 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 4701cdfeec..0e3348ac7a 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java
@@ -26,7 +26,6 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.join.BitSetProducer;
import org.apache.lucene.search.similarities.Similarity;
import org.elasticsearch.Version;
-import org.elasticsearch.client.Client;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
@@ -52,10 +51,7 @@ import org.elasticsearch.index.query.support.InnerHitsQueryParserHelper;
import org.elasticsearch.index.query.support.NestedScope;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
-import org.elasticsearch.script.ExecutableScript;
-import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
-import org.elasticsearch.script.Template;
import org.elasticsearch.search.fetch.innerhits.InnerHitsContext;
import org.elasticsearch.search.fetch.innerhits.InnerHitsSubSearchContext;
import org.elasticsearch.search.internal.SearchContext;
@@ -64,7 +60,6 @@ import org.elasticsearch.search.lookup.SearchLookup;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -73,15 +68,13 @@ import static java.util.Collections.unmodifiableMap;
/**
* Context object used to create lucene queries on the shard level.
*/
-public class QueryShardContext {
+public class QueryShardContext extends QueryRewriteContext {
private final MapperService mapperService;
- private final ScriptService scriptService;
private final SimilarityService similarityService;
private final BitsetFilterCache bitsetFilterCache;
private final IndexFieldDataService indexFieldDataService;
private final IndexSettings indexSettings;
- private final Client client;
private String[] types = Strings.EMPTY_ARRAY;
public void setTypes(String... types) {
@@ -94,35 +87,31 @@ public class QueryShardContext {
private final Map<String, Query> namedQueries = new HashMap<>();
private final MapperQueryParser queryParser = new MapperQueryParser(this);
- private final IndicesQueriesRegistry indicesQueriesRegistry;
private boolean allowUnmappedFields;
private boolean mapUnmappedFieldAsString;
private NestedScope nestedScope;
- private QueryParseContext parseContext;
boolean isFilter; // pkg private for testing
- public QueryShardContext(IndexSettings indexSettings, Client client, BitsetFilterCache bitsetFilterCache, IndexFieldDataService indexFieldDataService, MapperService mapperService, SimilarityService similarityService, ScriptService scriptService,
+ public QueryShardContext(IndexSettings indexSettings, BitsetFilterCache bitsetFilterCache, IndexFieldDataService indexFieldDataService, MapperService mapperService, SimilarityService similarityService, ScriptService scriptService,
final IndicesQueriesRegistry indicesQueriesRegistry) {
+ super(indexSettings, scriptService, indicesQueriesRegistry);
this.indexSettings = indexSettings;
- this.scriptService = scriptService;
- this.client = client;
this.similarityService = similarityService;
this.mapperService = mapperService;
this.bitsetFilterCache = bitsetFilterCache;
this.indexFieldDataService = indexFieldDataService;
this.allowUnmappedFields = indexSettings.isDefaultAllowUnmappedFields();
- this.indicesQueriesRegistry = indicesQueriesRegistry;
- this.parseContext = new QueryParseContext(indicesQueriesRegistry);
+
}
public QueryShardContext(QueryShardContext source) {
- this(source.indexSettings, source.client, source.bitsetFilterCache, source.indexFieldDataService, source.mapperService, source.similarityService, source.scriptService, source.indicesQueriesRegistry);
+ this(source.indexSettings, source.bitsetFilterCache, source.indexFieldDataService, source.mapperService, source.similarityService, source.scriptService, source.indicesQueriesRegistry);
this.types = source.getTypes();
}
public QueryShardContext clone() {
- return new QueryShardContext(indexSettings, client, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry);
+ return new QueryShardContext(indexSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry);
}
public void parseFieldMatcher(ParseFieldMatcher parseFieldMatcher) {
@@ -147,10 +136,6 @@ public class QueryShardContext {
this.parseContext.reset(jp);
}
- public Index index() {
- return this.mapperService.getIndexSettings().getIndex();
- }
-
public InnerHitsSubSearchContext getInnerHitsContext(XContentParser parser) throws IOException {
return InnerHitsQueryParserHelper.parse(parser);
}
@@ -159,10 +144,6 @@ public class QueryShardContext {
return mapperService.analysisService();
}
- public ScriptService getScriptService() {
- return scriptService;
- }
-
public MapperService getMapperService() {
return mapperService;
}
@@ -341,18 +322,6 @@ public class QueryShardContext {
return false;
}
- /*
- * Executes the given template, and returns the response.
- */
- public BytesReference executeQueryTemplate(Template template) {
- ExecutableScript executable = getScriptService().executable(template, ScriptContext.Standard.SEARCH, Collections.emptyMap());
- return (BytesReference) executable.run();
- }
-
- public Client getClient() {
- return client;
- }
-
public ParsedQuery parse(BytesReference source) {
XContentParser parser = null;
try {
@@ -385,7 +354,7 @@ public class QueryShardContext {
reset(parser);
try {
parseFieldMatcher(indexSettings.getParseFieldMatcher());
- Query filter = parseContext().parseInnerQueryBuilder().toFilter(this);
+ Query filter = QueryBuilder.rewriteQuery(parseContext().parseInnerQueryBuilder(), this).toFilter(this);
if (filter == null) {
return null;
}
@@ -426,12 +395,16 @@ public class QueryShardContext {
}
}
- private static Query toQuery(QueryBuilder<?> queryBuilder, QueryShardContext context) throws IOException {
- Query query = queryBuilder.toQuery(context);
+ private static Query toQuery(final QueryBuilder<?> queryBuilder, final QueryShardContext context) throws IOException {
+ final Query query = QueryBuilder.rewriteQuery(queryBuilder, context).toQuery(context);
if (query == null) {
- query = Queries.newMatchNoDocsQuery();
+ return Queries.newMatchNoDocsQuery();
}
return query;
}
+ public final Index index() {
+ return indexSettings.getIndex();
+ }
+
}
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 353dbd668a..31484fe804 100644
--- a/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
@@ -25,6 +25,7 @@ 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;
@@ -32,6 +33,7 @@ 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 02a9bc42e3..4067f6d87c 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
@@ -25,11 +25,13 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.script.ExecutableScript;
+import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.Template;
-import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
+import java.util.Collections;
import java.util.Map;
import java.util.Objects;
@@ -100,14 +102,7 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
- BytesReference querySource = context.executeQueryTemplate(template);
- try (XContentParser qSourceParser = XContentFactory.xContent(querySource).createParser(querySource)) {
- final QueryShardContext contextCopy = new QueryShardContext(context);
- contextCopy.reset(qSourceParser);
- QueryBuilder result = contextCopy.parseContext().parseInnerQueryBuilder();
- context.combineNamedQueries(contextCopy);
- return result.toQuery(context);
- }
+ throw new UnsupportedOperationException("this query must be rewritten first");
}
@Override
@@ -130,4 +125,23 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil
protected boolean doEquals(TemplateQueryBuilder other) {
return Objects.equals(template, other.template);
}
+
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryRewriteContext) throws IOException {
+ ExecutableScript executable = queryRewriteContext.getScriptService().executable(template,
+ ScriptContext.Standard.SEARCH, Collections.emptyMap());
+ BytesReference querySource = (BytesReference) executable.run();
+ final QueryParseContext queryParseContext = queryRewriteContext.newParseContext();
+ 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());
+ }
+ 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 326a6ed8b8..0cf4b7acf0 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
@@ -38,7 +38,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.indices.cache.query.terms.TermsLookup;
-import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
import java.util.ArrayList;
@@ -227,22 +226,13 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
- List<Object> terms;
- TermsLookup termsLookup = null;
- if (this.termsLookup != null) {
- termsLookup = new TermsLookup(this.termsLookup);
- if (termsLookup.index() == null) {
- termsLookup.index(context.index().getName());
- }
- Client client = context.getClient();
- terms = fetch(termsLookup, client);
- } else {
- terms = values;
+ if (termsLookup != null) {
+ throw new UnsupportedOperationException("query must be rewritten first");
}
- if (terms == null || terms.isEmpty()) {
+ if (values == null || values.isEmpty()) {
return Queries.newMatchNoDocsQuery();
}
- return handleTermsQuery(terms, fieldName, context);
+ return handleTermsQuery(values, fieldName, context);
}
private List<Object> fetch(TermsLookup termsLookup, Client client) {
@@ -324,4 +314,22 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
Objects.equals(values, other.values) &&
Objects.equals(termsLookup, other.termsLookup);
}
+
+ @Override
+ public QueryBuilder<TermsQueryBuilder> rewrite(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()) {
+ 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 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 e908d76331..6ba07f766e 100644
--- a/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
@@ -105,14 +105,7 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder<WrapperQueryBuilde
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
- try (XContentParser qSourceParser = XContentFactory.xContent(source).createParser(source)) {
- final QueryShardContext contextCopy = new QueryShardContext(context);
- contextCopy.reset(qSourceParser);
- contextCopy.parseFieldMatcher(context.parseFieldMatcher());
- QueryBuilder<?> result = contextCopy.parseContext().parseInnerQueryBuilder();
- context.combineNamedQueries(contextCopy);
- return result.toQuery(context);
- }
+ throw new UnsupportedOperationException("this query must be rewritten first");
}
@Override
@@ -134,4 +127,21 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder<WrapperQueryBuilde
protected boolean doEquals(WrapperQueryBuilder other) {
return Arrays.equals(source, other.source); // otherwise we compare pointers
}
+
+ @Override
+ public QueryBuilder<?> rewrite(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());
+ }
+ 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 766911bb74..14a2826084 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
@@ -34,6 +34,7 @@ import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.EmptyQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryRewriteContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.functionscore.random.RandomScoreFunctionBuilder;
@@ -394,4 +395,17 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
return new FilterFunctionBuilder(in.readQuery(), in.readScoreFunction());
}
}
+
+ @Override
+ public QueryBuilder<?> rewrite(QueryRewriteContext queryShardContext) throws IOException {
+ QueryBuilder<?> queryBuilder = this.query.rewrite(queryShardContext);
+ if (queryBuilder != query) {
+ FunctionScoreQueryBuilder newQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, filterFunctionBuilders);
+ newQueryBuilder.scoreMode = scoreMode;
+ newQueryBuilder.minScore = minScore;
+ newQueryBuilder.maxBoost = maxBoost;
+ return newQueryBuilder.queryName(queryName()).boost(boost());
+ }
+ return this;
+ }
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/support/NestedInnerQueryParseSupport.java b/core/src/main/java/org/elasticsearch/index/query/support/NestedInnerQueryParseSupport.java
index 890961dd2a..9923728e3b 100644
--- a/core/src/main/java/org/elasticsearch/index/query/support/NestedInnerQueryParseSupport.java
+++ b/core/src/main/java/org/elasticsearch/index/query/support/NestedInnerQueryParseSupport.java
@@ -27,6 +27,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.object.ObjectMapper;
+import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.QueryShardException;
@@ -91,7 +92,8 @@ public class NestedInnerQueryParseSupport {
if (path != null) {
setPathLevel();
try {
- innerFilter = parseContext.parseInnerQueryBuilder().toFilter(this.shardContext);
+ innerFilter = QueryBuilder.rewriteQuery(parseContext.parseInnerQueryBuilder(),
+ this.shardContext).toFilter(this.shardContext);
} finally {
resetPathLevel();
}
@@ -147,7 +149,8 @@ public class NestedInnerQueryParseSupport {
try {
XContentParser innerParser = XContentHelper.createParser(source);
parseContext.parser(innerParser);
- innerFilter = parseContext.parseInnerQueryBuilder().toFilter(this.shardContext);
+ innerFilter = QueryBuilder.rewriteQuery(parseContext.parseInnerQueryBuilder(),
+ this.shardContext).toFilter(this.shardContext);
filterParsed = true;
return innerFilter;
} finally {
diff --git a/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java b/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java
index f2f1add259..e131fa2dd0 100644
--- a/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java
+++ b/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java
@@ -252,7 +252,7 @@ public class IndexShard extends AbstractIndexShardComponent {
this.engineConfig = newEngineConfig(translogConfig, cachingPolicy);
this.suspendableRefContainer = new SuspendableRefContainer();
this.searcherWrapper = indexSearcherWrapper;
- QueryShardContext queryShardContext = new QueryShardContext(idxSettings, provider.getClient(), indexCache.bitsetFilterCache(), indexFieldDataService, mapperService, similarityService, provider.getScriptService(), provider.getIndicesQueriesRegistry());
+ QueryShardContext queryShardContext = new QueryShardContext(idxSettings, indexCache.bitsetFilterCache(), indexFieldDataService, mapperService, similarityService, provider.getScriptService(), provider.getIndicesQueriesRegistry());
this.percolatorQueriesRegistry = new PercolatorQueriesRegistry(shardId, indexSettings, queryShardContext);
}
diff --git a/core/src/main/java/org/elasticsearch/script/ScriptService.java b/core/src/main/java/org/elasticsearch/script/ScriptService.java
index d21283d9cf..8e1ac1c8d7 100644
--- a/core/src/main/java/org/elasticsearch/script/ScriptService.java
+++ b/core/src/main/java/org/elasticsearch/script/ScriptService.java
@@ -489,6 +489,10 @@ public class ScriptService extends AbstractComponent implements Closeable {
return scriptMetrics.stats();
}
+ public Client getClient() {
+ return client;
+ }
+
/**
* A small listener for the script cache that calls each
* {@code ScriptEngineService}'s {@code scriptRemoved} method when the
diff --git a/core/src/main/java/org/elasticsearch/search/SearchService.java b/core/src/main/java/org/elasticsearch/search/SearchService.java
index e0b30a2e34..7c6fa0da9b 100644
--- a/core/src/main/java/org/elasticsearch/search/SearchService.java
+++ b/core/src/main/java/org/elasticsearch/search/SearchService.java
@@ -536,8 +536,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> imp
DefaultSearchContext context = new DefaultSearchContext(idGenerator.incrementAndGet(), request, shardTarget, engineSearcher, indexService, indexShard, scriptService, pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter(), parseFieldMatcher, defaultSearchTimeout);
SearchContext.setCurrent(context);
-
try {
+ if (request.source() != null) {
+ request.source().rewrite(context.getQueryShardContext());
+ }
if (request.scroll() != null) {
context.scrollContext(new ScrollContext());
context.scrollContext().scroll = request.scroll();
diff --git a/core/src/main/java/org/elasticsearch/search/action/SearchServiceTransportAction.java b/core/src/main/java/org/elasticsearch/search/action/SearchServiceTransportAction.java
index 138b215e68..81fa590908 100644
--- a/core/src/main/java/org/elasticsearch/search/action/SearchServiceTransportAction.java
+++ b/core/src/main/java/org/elasticsearch/search/action/SearchServiceTransportAction.java
@@ -81,7 +81,6 @@ public class SearchServiceTransportAction extends AbstractComponent {
super(settings);
this.transportService = transportService;
this.searchService = searchService;
-
transportService.registerRequestHandler(FREE_CONTEXT_SCROLL_ACTION_NAME, ScrollFreeContextRequest::new, ThreadPool.Names.SAME, new FreeContextTransportHandler<>());
transportService.registerRequestHandler(FREE_CONTEXT_ACTION_NAME, SearchFreeContextRequest::new, ThreadPool.Names.SAME, new FreeContextTransportHandler<SearchFreeContextRequest>());
transportService.registerRequestHandler(CLEAR_SCROLL_CONTEXTS_ACTION_NAME, ClearScrollContextsRequest::new, ThreadPool.Names.SAME, new ClearScrollContextsTransportHandler());
diff --git a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
index 6a9d95deb3..99ee939d15 100644
--- a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
@@ -40,6 +40,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
+import org.elasticsearch.index.query.QueryRewriteContext;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.searchafter.SearchAfterBuilder;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
@@ -1433,4 +1434,17 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
&& Objects.equals(version, other.version)
&& Objects.equals(profile, other.profile);
}
+
+ /**
+ * Rewrites the internal query builders in-place
+ */
+ public void rewrite(QueryRewriteContext rewriteContext) throws IOException {
+ if (queryBuilder != null) {
+ queryBuilder = QueryBuilder.rewriteQuery(queryBuilder, rewriteContext);
+ }
+ if (postQueryBuilder != null) {
+ postQueryBuilder = QueryBuilder.rewriteQuery(postQueryBuilder, rewriteContext);
+ }
+ }
+
}
diff --git a/core/src/main/java/org/elasticsearch/search/highlight/HighlightBuilder.java b/core/src/main/java/org/elasticsearch/search/highlight/HighlightBuilder.java
index c0b1aeea3b..325541844c 100644
--- a/core/src/main/java/org/elasticsearch/search/highlight/HighlightBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/highlight/HighlightBuilder.java
@@ -355,7 +355,7 @@ public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilde
targetOptionsBuilder.options(highlighterBuilder.options);
}
if (highlighterBuilder.highlightQuery != null) {
- targetOptionsBuilder.highlightQuery(highlighterBuilder.highlightQuery.toQuery(context));
+ targetOptionsBuilder.highlightQuery(QueryBuilder.rewriteQuery(highlighterBuilder.highlightQuery, context).toQuery(context));
}
}
diff --git a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java
index 10c727a902..c65fca79a9 100644
--- a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java
@@ -149,7 +149,7 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> {
public QueryRescoreContext build(QueryShardContext context) throws IOException {
org.elasticsearch.search.rescore.QueryRescorer rescorer = new org.elasticsearch.search.rescore.QueryRescorer();
QueryRescoreContext queryRescoreContext = new QueryRescoreContext(rescorer);
- queryRescoreContext.setQuery(this.queryBuilder.toQuery(context));
+ queryRescoreContext.setQuery(QueryBuilder.rewriteQuery(this.queryBuilder, context).toQuery(context));
queryRescoreContext.setQueryWeight(this.queryWeight);
queryRescoreContext.setRescoreQueryWeight(this.rescoreQueryWeight);
queryRescoreContext.setScoreMode(this.scoreMode);
@@ -239,4 +239,4 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> {
this.scoreMode = scoreMode;
}
}
-} \ No newline at end of file
+}
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 e8f20cb855..5b8550b7b1 100644
--- a/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java
+++ b/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java
@@ -286,7 +286,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
}
});
indicesQueriesRegistry = injector.getInstance(IndicesQueriesRegistry.class);
- queryShardContext = new QueryShardContext(idxSettings, proxy, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry);
+ queryShardContext = new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry);
//create some random type with some default field, those types will stick around for all of the subclasses
currentTypes = new String[randomIntBetween(0, 5)];
for (int i = 0; i < currentTypes.length; i++) {
@@ -516,7 +516,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
QB firstQuery = createTestQueryBuilder();
QB controlQuery = copyQuery(firstQuery);
setSearchContext(randomTypes); // only set search context for toQuery to be more realistic
- Query firstLuceneQuery = firstQuery.toQuery(context);
+ Query firstLuceneQuery = rewriteQuery(firstQuery, context).toQuery(context);
assertLuceneQuery(firstQuery, firstLuceneQuery, context);
SearchContext.removeCurrent(); // remove after assertLuceneQuery since the assertLuceneQuery impl might access the context as well
assertTrue(
@@ -534,7 +534,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
+ randomAsciiOfLengthBetween(1, 10));
}
setSearchContext(randomTypes);
- Query secondLuceneQuery = secondQuery.toQuery(context);
+ Query secondLuceneQuery = rewriteQuery(secondQuery, context).toQuery(context);
assertLuceneQuery(secondQuery, secondLuceneQuery, context);
SearchContext.removeCurrent();
@@ -544,7 +544,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
if (firstLuceneQuery != null && supportsBoostAndQueryName()) {
secondQuery.boost(firstQuery.boost() + 1f + randomFloat());
setSearchContext(randomTypes);
- Query thirdLuceneQuery = secondQuery.toQuery(context);
+ Query thirdLuceneQuery = rewriteQuery(secondQuery, context).toQuery(context);
SearchContext.removeCurrent();
assertThat("modifying the boost doesn't affect the corresponding lucene query", firstLuceneQuery,
not(equalTo(thirdLuceneQuery)));
@@ -552,6 +552,12 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
}
}
+ private QueryBuilder<?> rewriteQuery(QB queryBuilder, QueryRewriteContext rewriteContext) throws IOException {
+ QueryBuilder<?> rewritten = QueryBuilder.rewriteQuery(queryBuilder, rewriteContext);
+ assertSerialization(rewritten);
+ return rewritten;
+ }
+
/**
* Few queries allow you to set the boost and queryName on the java api, although the corresponding parser doesn't parse them as they are not supported.
* This method allows to disable boost and queryName related tests for those queries. Those queries are easy to identify: their parsers
@@ -625,11 +631,13 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
* Serialize the given query builder and asserts that both are equal
*/
@SuppressWarnings("unchecked")
- protected QB assertSerialization(QB testQuery) throws IOException {
+ protected <QB extends QueryBuilder> QB assertSerialization(QB testQuery) throws IOException {
try (BytesStreamOutput output = new BytesStreamOutput()) {
testQuery.writeTo(output);
try (StreamInput in = new NamedWriteableAwareStreamInput(StreamInput.wrap(output.bytes()), namedWriteableRegistry)) {
- QueryBuilder<?> prototype = queryParser(testQuery.getName()).getBuilderPrototype();
+ QueryParser<?> queryParser = queryParser(testQuery.getName());
+ assertNotNull("queryparser not found for query: [" + testQuery.getName() + "]", queryParser);
+ QueryBuilder<?> prototype = queryParser.getBuilderPrototype();
QueryBuilder<?> deserializedQuery = prototype.readFrom(in);
assertEquals(deserializedQuery, testQuery);
assertEquals(deserializedQuery.hashCode(), testQuery.hashCode());
@@ -674,7 +682,26 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
}
private QueryParser<?> queryParser(String queryId) {
- return indicesQueriesRegistry.queryParsers().get(queryId);
+ QueryParser<?> queryParser = indicesQueriesRegistry.queryParsers().get(queryId);
+ if (queryParser == null && EmptyQueryBuilder.NAME.equals(queryId)) {
+ return new QueryParser() {
+ @Override
+ public String[] names() {
+ return new String[] {EmptyQueryBuilder.NAME};
+ }
+
+ @Override
+ public QueryBuilder<?> fromXContent(QueryParseContext parseContext) throws IOException {
+ return new EmptyQueryBuilder();
+ }
+
+ @Override
+ public QueryBuilder getBuilderPrototype() {
+ return EmptyQueryBuilder.PROTOTYPE;
+ }
+ };
+ }
+ return queryParser;
}
//we use the streaming infra to create a copy of the query provided as argument
diff --git a/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java b/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java
index f78700d4a1..1c35642c51 100644
--- a/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java
@@ -21,15 +21,12 @@ package org.elasticsearch.index.query;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.test.ESTestCase;
-import java.util.Collections;
-
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
@@ -50,7 +47,7 @@ public class QueryShardContextTests extends ESTestCase {
MapperService mapperService = mock(MapperService.class);
when(mapperService.getIndexSettings()).thenReturn(indexSettings);
QueryShardContext context = new QueryShardContext(
- indexSettings, null, null, null, mapperService, null, null, null
+ indexSettings, null, null, mapperService, null, null, null
);
context.setAllowUnmappedFields(false);
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 df7eb3c697..7a602f0941 100644
--- a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java
@@ -56,7 +56,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase<TemplateQue
@Override
protected void doAssertLuceneQuery(TemplateQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
- assertEquals(templateBase.toQuery(context), query);
+ assertEquals(QueryBuilder.rewriteQuery(templateBase, context).toQuery(context), query);
}
public void testIllegalArgument() {
diff --git a/core/src/test/java/org/elasticsearch/percolator/PercolateDocumentParserTests.java b/core/src/test/java/org/elasticsearch/percolator/PercolateDocumentParserTests.java
index 91fb8b5cd8..a561c97e3d 100644
--- a/core/src/test/java/org/elasticsearch/percolator/PercolateDocumentParserTests.java
+++ b/core/src/test/java/org/elasticsearch/percolator/PercolateDocumentParserTests.java
@@ -84,7 +84,7 @@ public class PercolateDocumentParserTests extends ESTestCase {
Map<String, QueryParser<?>> parsers = singletonMap("term", new TermQueryParser());
IndicesQueriesRegistry indicesQueriesRegistry = new IndicesQueriesRegistry(indexSettings.getSettings(), parsers);
- queryShardContext = new QueryShardContext(indexSettings, null, null, null, mapperService, null, null, indicesQueriesRegistry);
+ queryShardContext = new QueryShardContext(indexSettings, null, null, mapperService, null, null, indicesQueriesRegistry);
HighlightPhase highlightPhase = new HighlightPhase(Settings.EMPTY, new Highlighters());
AggregatorParsers aggregatorParsers = new AggregatorParsers(Collections.emptySet(), Collections.emptySet());
diff --git a/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java b/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java
index 786d594182..3714f6a23f 100644
--- a/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java
@@ -41,9 +41,14 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.query.AbstractQueryTestCase;
+import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.EmptyQueryBuilder;
+import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
+import org.elasticsearch.index.query.QueryRewriteContext;
+import org.elasticsearch.index.query.TermQueryBuilder;
+import org.elasticsearch.index.query.WrapperQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.Script;
@@ -483,4 +488,14 @@ public class SearchSourceBuilderTests extends ESTestCase {
String query = "{ \"post_filter\": {} }";
assertParseSearchSource(builder, new BytesArray(query));
}
+
+ public void testRewrite() throws IOException {
+ SearchSourceBuilder builder = new SearchSourceBuilder();
+ builder.query(new BoolQueryBuilder());
+ TermQueryBuilder tqb = new TermQueryBuilder("foo", "bar");
+ builder.postFilter(new WrapperQueryBuilder(tqb.toString()));
+ builder.rewrite(new QueryRewriteContext(null, null, indicesQueriesRegistry));
+ assertEquals(new MatchAllQueryBuilder(), builder.query());
+ assertEquals(tqb, builder.postFilter());
+ }
}
diff --git a/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java b/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java
index 5dc8528c00..2cd81b0fde 100644
--- a/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java
@@ -278,7 +278,7 @@ public class HighlightBuilderTests extends ESTestCase {
Index index = new Index(randomAsciiOfLengthBetween(1, 10), "_na_");
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(index, indexSettings);
// shard context will only need indicesQueriesRegistry for building Query objects nested in highlighter
- QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, null, indicesQueriesRegistry) {
+ QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry) {
@Override
public MappedFieldType fieldMapper(String name) {
StringFieldMapper.Builder builder = MapperBuilders.stringField(name);
diff --git a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java
index 01f7e33244..37f81e3d33 100644
--- a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java
@@ -160,7 +160,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAsciiOfLengthBetween(1, 10), indexSettings);
// shard context will only need indicesQueriesRegistry for building Query objects nested in query rescorer
- QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, null, indicesQueriesRegistry) {
+ QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry) {
@Override
public MappedFieldType fieldMapper(String name) {
StringFieldMapper.Builder builder = MapperBuilders.stringField(name);
@@ -170,7 +170,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
RescoreBuilder<?> rescoreBuilder = randomRescoreBuilder();
- QueryRescoreContext rescoreContext = (QueryRescoreContext) rescoreBuilder.build(mockShardContext);
+ QueryRescoreContext rescoreContext = rescoreBuilder.build(mockShardContext);
XContentParser parser = createParser(rescoreBuilder);
QueryRescoreContext parsedRescoreContext = (QueryRescoreContext) new RescoreParseElement().parseSingleRescoreContext(parser, mockShardContext);
diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java
index 02826b9a7e..ebf903d91a 100644
--- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java
+++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java
@@ -171,7 +171,7 @@ public class DirectCandidateGeneratorTests extends ESTestCase{
}
};
- QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, mockMapperService, null, null, null) {
+ QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, mockMapperService, null, null, null) {
@Override
public MappedFieldType fieldMapper(String name) {
StringFieldMapper.Builder builder = MapperBuilders.stringField(name);