Parse source, extra-source and template-source on the coordinating node

This commit removes all the opaque bytes for extra_source and template_source.
Instead source and extra_source etc. are represented as SearchSourceBuilder which can
in-place be modified and is updated with the content of the request parameters.
Template Source is parsed and evaluated which in-turn replaces the actual source.
This commit is contained in:
Simon Willnauer 2015-09-22 20:37:24 +02:00
parent ac8c1722ac
commit 6c335f4a47
38 changed files with 515 additions and 776 deletions

View File

@ -33,6 +33,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
@ -44,9 +45,6 @@ import static org.elasticsearch.search.internal.SearchContext.DEFAULT_TERMINATE_
/**
* A request to count the number of documents matching a specific query. Best created with
* {@link org.elasticsearch.client.Requests#countRequest(String...)}.
* <p>
* The request requires the query source to be set either using {@link #source(QuerySourceBuilder)},
* or {@link #source(byte[])}.
*
* @see CountResponse
* @see org.elasticsearch.client.Client#count(CountRequest)
@ -64,12 +62,12 @@ public class CountRequest extends BroadcastRequest<CountRequest> {
@Nullable
private String preference;
private BytesReference source;
private String[] types = Strings.EMPTY_ARRAY;
private int terminateAfter = DEFAULT_TERMINATE_AFTER;
private SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
/**
* Constructs a new count request against the provided indices. No indices provided means it will
* run against all indices.
@ -94,67 +92,21 @@ public class CountRequest extends BroadcastRequest<CountRequest> {
return this;
}
/**
* The source to execute.
*/
public BytesReference source() {
return source;
}
/**
* The source to execute.
* The query to execute
*/
public CountRequest source(QuerySourceBuilder sourceBuilder) {
this.source = sourceBuilder.buildAsBytes(Requests.CONTENT_TYPE);
public CountRequest query(QueryBuilder queryBuilder) {
this.searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder);
return this;
}
/**
* The source to execute in the form of a map.
*/
@SuppressWarnings("unchecked")
public CountRequest source(Map querySource) {
try {
XContentBuilder builder = XContentFactory.contentBuilder(Requests.CONTENT_TYPE);
builder.map(querySource);
return source(builder);
} catch (IOException e) {
throw new ElasticsearchGenerationException("Failed to generate [" + querySource + "]", e);
}
}
public CountRequest source(XContentBuilder builder) {
this.source = builder.bytes();
public CountRequest searchSource(SearchSourceBuilder searchSourceBuilder) {
this.searchSourceBuilder = searchSourceBuilder;
return this;
}
/**
* The source to execute. It is preferable to use either {@link #source(byte[])}
* or {@link #source(QuerySourceBuilder)}.
*/
public CountRequest source(String querySource) {
this.source = new BytesArray(querySource);
return this;
}
/**
* The source to execute.
*/
public CountRequest source(byte[] querySource) {
return source(querySource, 0, querySource.length);
}
/**
* The source to execute.
*/
public CountRequest source(byte[] querySource, int offset, int length) {
return source(new BytesArray(querySource, offset, length));
}
public CountRequest source(BytesReference querySource) {
this.source = querySource;
return this;
}
/**
* The types of documents the query will run against. Defaults to all types.
@ -232,7 +184,7 @@ public class CountRequest extends BroadcastRequest<CountRequest> {
public String toString() {
String sSource = "_na_";
try {
sSource = XContentHelper.convertToJson(source, false);
sSource = XContentHelper.toString(searchSourceBuilder);
} catch (Exception e) {
// ignore
}
@ -240,13 +192,6 @@ public class CountRequest extends BroadcastRequest<CountRequest> {
}
public SearchRequest toSearchRequest() {
SearchRequest searchRequest = new SearchRequest(indices());
searchRequest.indicesOptions(indicesOptions());
searchRequest.types(types());
searchRequest.routing(routing());
searchRequest.preference(preference());
// searchRequest.source(source()); NOCOMMIT fix this
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(0);
if (minScore() != DEFAULT_MIN_SCORE) {
searchSourceBuilder.minScore(minScore());
@ -254,7 +199,16 @@ public class CountRequest extends BroadcastRequest<CountRequest> {
if (terminateAfter() != DEFAULT_TERMINATE_AFTER) {
searchSourceBuilder.terminateAfter(terminateAfter());
}
searchRequest.extraSource(searchSourceBuilder);
SearchRequest searchRequest = new SearchRequest(indices());
searchRequest.source(searchSourceBuilder);
searchRequest.indicesOptions(indicesOptions());
searchRequest.types(types());
searchRequest.routing(routing());
searchRequest.preference(preference());
return searchRequest;
}
SearchSourceBuilder sourceBuilder() {
return searchSourceBuilder;
}
}

View File

@ -31,14 +31,13 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
/**
* A count action request builder.
*/
public class CountRequestBuilder extends BroadcastOperationRequestBuilder<CountRequest, CountResponse, CountRequestBuilder> {
private QuerySourceBuilder sourceBuilder;
public CountRequestBuilder(ElasticsearchClient client, CountAction action) {
super(client, action, new CountRequest());
}
@ -87,45 +86,19 @@ public class CountRequestBuilder extends BroadcastOperationRequestBuilder<CountR
return this;
}
/**
* The query source to execute.
*
* @see org.elasticsearch.index.query.QueryBuilders
*/
public CountRequestBuilder setQuery(QueryBuilder queryBuilder) {
sourceBuilder().setQuery(queryBuilder);
return this;
}
/**
* The query binary to execute
*/
public CountRequestBuilder setQuery(BytesReference queryBinary) {
sourceBuilder().setQuery(queryBinary);
return this;
}
/**
* Constructs a new builder with a raw search query.
*/
public CountRequestBuilder setQuery(XContentBuilder query) {
return setQuery(query.bytes());
}
/**
* The source to execute.
*/
public CountRequestBuilder setSource(BytesReference source) {
request().source(source);
public CountRequestBuilder setSource(SearchSourceBuilder source) {
request().searchSource(source);
return this;
}
/**
* The query source to execute.
*/
public CountRequestBuilder setSource(byte[] querySource) {
request.source(querySource);
public CountRequestBuilder setQuery(QueryBuilder<?> builder) {
request.query(builder);
return this;
}
@ -134,21 +107,6 @@ public class CountRequestBuilder extends BroadcastOperationRequestBuilder<CountR
return this;
}
@Override
protected CountRequest beforeExecute(CountRequest request) {
if (sourceBuilder != null) {
request.source(sourceBuilder);
}
return request;
}
private QuerySourceBuilder sourceBuilder() {
if (sourceBuilder == null) {
sourceBuilder = new QuerySourceBuilder();
}
return sourceBuilder;
}
@Override
public void execute(ActionListener<CountResponse> listener) {
CountRequest countRequest = beforeExecute(request);
@ -162,15 +120,8 @@ public class CountRequestBuilder extends BroadcastOperationRequestBuilder<CountR
@Override
public String toString() {
if (sourceBuilder != null) {
return sourceBuilder.toString();
}
if (request.source() != null) {
try {
return XContentHelper.convertToJson(request.source().toBytesArray(), false, true);
} catch (Exception e) {
return "{ \"error\" : \"" + ExceptionsHelper.detailedMessage(e) + "\"}";
}
if (request.sourceBuilder() != null) {
return request.sourceBuilder().toString();
}
return new QuerySourceBuilder().toString();
}

View File

@ -24,24 +24,14 @@ import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.CompositeIndicesRequest;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.action.ValidateActions.addValidationError;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringArrayValue;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue;
/**
* A multi search API request.
@ -70,108 +60,6 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> implem
return this;
}
public MultiSearchRequest add(byte[] data, int from, int length,
boolean isTemplateRequest, @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType) throws Exception {
return add(new BytesArray(data, from, length), isTemplateRequest, indices, types, searchType, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true);
}
public MultiSearchRequest add(BytesReference data, boolean isTemplateRequest, @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType, IndicesOptions indicesOptions) throws Exception {
return add(data, isTemplateRequest, indices, types, searchType, null, indicesOptions, true);
}
public MultiSearchRequest add(BytesReference data, boolean isTemplateRequest, @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType, @Nullable String routing, IndicesOptions indicesOptions, boolean allowExplicitIndex) throws Exception {
XContent xContent = XContentFactory.xContent(data);
int from = 0;
int length = data.length();
byte marker = xContent.streamSeparator();
while (true) {
int nextMarker = findNextMarker(marker, from, data, length);
if (nextMarker == -1) {
break;
}
// support first line with \n
if (nextMarker == 0) {
from = nextMarker + 1;
continue;
}
SearchRequest searchRequest = new SearchRequest();
if (indices != null) {
searchRequest.indices(indices);
}
if (indicesOptions != null) {
searchRequest.indicesOptions(indicesOptions);
}
if (types != null && types.length > 0) {
searchRequest.types(types);
}
if (routing != null) {
searchRequest.routing(routing);
}
searchRequest.searchType(searchType);
IndicesOptions defaultOptions = IndicesOptions.strictExpandOpenAndForbidClosed();
// now parse the action
if (nextMarker - from > 0) {
try (XContentParser parser = xContent.createParser(data.slice(from, nextMarker - from))) {
Map<String, Object> source = parser.map();
for (Map.Entry<String, Object> entry : source.entrySet()) {
Object value = entry.getValue();
if ("index".equals(entry.getKey()) || "indices".equals(entry.getKey())) {
if (!allowExplicitIndex) {
throw new IllegalArgumentException("explicit index in multi percolate is not allowed");
}
searchRequest.indices(nodeStringArrayValue(value));
} else if ("type".equals(entry.getKey()) || "types".equals(entry.getKey())) {
searchRequest.types(nodeStringArrayValue(value));
} else if ("search_type".equals(entry.getKey()) || "searchType".equals(entry.getKey())) {
searchRequest.searchType(nodeStringValue(value, null));
} else if ("request_cache".equals(entry.getKey()) || "requestCache".equals(entry.getKey())) {
searchRequest.requestCache(nodeBooleanValue(value));
} else if ("preference".equals(entry.getKey())) {
searchRequest.preference(nodeStringValue(value, null));
} else if ("routing".equals(entry.getKey())) {
searchRequest.routing(nodeStringValue(value, null));
}
}
defaultOptions = IndicesOptions.fromMap(source, defaultOptions);
}
}
searchRequest.indicesOptions(defaultOptions);
// move pointers
from = nextMarker + 1;
// now for the body
nextMarker = findNextMarker(marker, from, data, length);
if (nextMarker == -1) {
break;
}
if (isTemplateRequest) {
searchRequest.templateSource(data.slice(from, nextMarker - from));
} else {
// searchRequest.source(data.slice(from, nextMarker - from));
// NOCOMMIT fix this
}
// move pointers
from = nextMarker + 1;
add(searchRequest);
}
return this;
}
private int findNextMarker(byte marker, int from, BytesReference data, int length) {
for (int i = from; i < length; i++) {
if (data.get(i) == marker) {
return i;
}
}
return -1;
}
public List<SearchRequest> requests() {
return this.requests;
}

View File

@ -32,15 +32,11 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.Template;
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
import java.util.Map;
import static org.elasticsearch.search.Scroll.readScroll;
@ -50,9 +46,7 @@ import static org.elasticsearch.search.Scroll.readScroll;
* <p>
* Note, the search {@link #source(org.elasticsearch.search.builder.SearchSourceBuilder)}
* is required. The search source is the different search options, including aggregations and such.
* <p>
* There is an option to specify an addition search source using the {@link #extraSource(org.elasticsearch.search.builder.SearchSourceBuilder)}.
*
* </p>
* @see org.elasticsearch.client.Requests#searchRequest(String...)
* @see org.elasticsearch.client.Client#search(SearchRequest)
* @see SearchResponse
@ -68,12 +62,8 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
@Nullable
private String preference;
private BytesReference templateSource;
private Template template;
private SearchSourceBuilder source;
private BytesReference extraSource;
private Boolean requestCache;
private Scroll scroll;
@ -84,6 +74,8 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
private IndicesOptions indicesOptions = DEFAULT_INDICES_OPTIONS;
private Template template;
public SearchRequest() {
}
@ -97,10 +89,8 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
this.indices = searchRequest.indices;
this.routing = searchRequest.routing;
this.preference = searchRequest.preference;
this.templateSource = searchRequest.templateSource;
this.template = searchRequest.template;
this.source = searchRequest.source;
this.extraSource = searchRequest.extraSource;
this.requestCache = searchRequest.requestCache;
this.scroll = searchRequest.scroll;
this.types = searchRequest.types;
@ -248,7 +238,6 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
return this;
}
/**
* The search source to execute.
*/
@ -256,40 +245,6 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
return source;
}
/**
* The search source template to execute.
*/
public BytesReference templateSource() {
return templateSource;
}
/**
* Allows to provide additional source that will be used as well.
*/
public SearchRequest extraSource(SearchSourceBuilder sourceBuilder) {
if (sourceBuilder == null) {
extraSource = null;
return this;
}
this.extraSource = sourceBuilder.buildAsBytes(Requests.CONTENT_TYPE);
return this;
}
/**
* Allows to provide template as source.
*/
public SearchRequest templateSource(BytesReference template) {
this.templateSource = template;
return this;
}
/**
* The template of the search request.
*/
public SearchRequest templateSource(String template) {
this.templateSource = new BytesArray(template);
return this;
}
/**
* The stored template
@ -305,88 +260,6 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
return template;
}
/**
* The name of the stored template
*
* @deprecated use {@link #template(Template)} instead.
*/
@Deprecated
public void templateName(String templateName) {
updateOrCreateScript(templateName, null, null, null);
}
/**
* The type of the stored template
*
* @deprecated use {@link #template(Template)} instead.
*/
@Deprecated
public void templateType(ScriptService.ScriptType templateType) {
updateOrCreateScript(null, templateType, null, null);
}
/**
* Template parameters used for rendering
*
* @deprecated use {@link #template(Template)} instead.
*/
@Deprecated
public void templateParams(Map<String, Object> params) {
updateOrCreateScript(null, null, null, params);
}
/**
* The name of the stored template
*
* @deprecated use {@link #template()} instead.
*/
@Deprecated
public String templateName() {
return template == null ? null : template.getScript();
}
/**
* The name of the stored template
*
* @deprecated use {@link #template()} instead.
*/
@Deprecated
public ScriptService.ScriptType templateType() {
return template == null ? null : template.getType();
}
/**
* Template parameters used for rendering
*
* @deprecated use {@link #template()} instead.
*/
@Deprecated
public Map<String, Object> templateParams() {
return template == null ? null : template.getParams();
}
private void updateOrCreateScript(String templateContent, ScriptType type, String lang, Map<String, Object> params) {
Template template = template();
if (template == null) {
template = new Template(templateContent == null ? "" : templateContent, type == null ? ScriptType.INLINE : type, lang, null,
params);
} else {
String newTemplateContent = templateContent == null ? template.getScript() : templateContent;
ScriptType newTemplateType = type == null ? template.getType() : type;
String newTemplateLang = lang == null ? template.getLang() : lang;
Map<String, Object> newTemplateParams = params == null ? template.getParams() : params;
template = new Template(newTemplateContent, newTemplateType, MustacheScriptEngineService.NAME, null, newTemplateParams);
}
template(template);
}
/**
* Additional search source to execute.
*/
public BytesReference extraSource() {
return this.extraSource;
}
/**
* The tye of search to execute.
*/
@ -463,16 +336,12 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
}
source = SearchSourceBuilder.PROTOTYPE.readFrom(in);
extraSource = in.readBytesReference();
types = in.readStringArray();
indicesOptions = IndicesOptions.readIndicesOptions(in);
templateSource = in.readBytesReference();
if (in.readBoolean()) {
template = Template.readTemplate(in);
}
requestCache = in.readOptionalBoolean();
template = in.readOptionalStreamable(new Template());
}
@Override
@ -495,17 +364,9 @@ public class SearchRequest extends ActionRequest<SearchRequest> implements Indic
scroll.writeTo(out);
}
source.writeTo(out);
out.writeBytesReference(extraSource);
out.writeStringArray(types);
indicesOptions.writeIndicesOptions(out);
out.writeBytesReference(templateSource);
boolean hasTemplate = template != null;
out.writeBoolean(hasTemplate);
if (hasTemplate) {
template.writeTo(out);
}
out.writeOptionalBoolean(requestCache);
out.writeOptionalStreamable(template);
}
}

View File

@ -455,25 +455,13 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
}
/**
* Sets the source of the request as a SearchSourceBuilder. Note, settings anything other
* than the search type will cause this source to be overridden, consider using
* {@link #setExtraSource(SearchSourceBuilder)} instead.
* Sets the source of the request as a SearchSourceBuilder.
*/
public SearchRequestBuilder setSource(SearchSourceBuilder source) {
request.source(source);
return this;
}
/**
* Sets the an addtional source of the request as a SearchSourceBuilder. All values and
* settings set on the extra source will override the corresponding settings on the specified
* source.
*/
public SearchRequestBuilder setExtraSource(SearchSourceBuilder source) {
request.extraSource(source);
return this;
}
/**
* template stuff
*/
@ -482,16 +470,6 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
return this;
}
public SearchRequestBuilder setTemplateSource(String source) {
request.templateSource(source);
return this;
}
public SearchRequestBuilder setTemplateSource(BytesReference source) {
request.templateSource(source);
return this;
}
/**
* Sets if this request should use the request cache or not, assuming that it can (for
* example, if "now" is used, it will never be cached). By default (not set, or null,

View File

@ -311,6 +311,10 @@ public class PagedBytesReference implements BytesReference {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof PagedBytesReference)) {
return BytesReference.Helper.bytesEqual(this, (BytesReference) obj);
}

View File

@ -150,7 +150,7 @@ public class IndexQueryParserService extends AbstractIndexComponent {
return this.queryStringLenient;
}
IndicesQueriesRegistry indicesQueriesRegistry() {
public IndicesQueriesRegistry indicesQueriesRegistry() {
return indicesQueriesRegistry;
}

View File

@ -25,6 +25,7 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.Index;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import java.io.IOException;
@ -43,6 +44,10 @@ public class QueryParseContext {
private IndicesQueriesRegistry indicesQueriesRegistry;
public QueryParseContext(IndicesQueriesRegistry registry) {
this(null, registry); // NOCOMMIT - remove index
}
public QueryParseContext(Index index, IndicesQueriesRegistry registry) {
this.indicesQueriesRegistry = registry;
this.shardContext = null;
}

View File

@ -18,17 +18,26 @@
*/
package org.elasticsearch.index.query;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.HasContextAndHeaders;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.lease.Releasables;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.Template;
import org.elasticsearch.script.*;
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.elasticsearch.common.Strings.hasLength;
/**
* In the simplest case, parse template string and variables from the request,
* compile the template and execute the template against the given variables.
@ -91,4 +100,6 @@ public class TemplateQueryParser extends BaseQueryParser<TemplateQueryBuilder> {
public TemplateQueryBuilder getBuilderPrototype() {
return TemplateQueryBuilder.PROTOTYPE;
}
}

View File

@ -194,15 +194,6 @@ public final class SearchSlowLog{
} else {
sb.append("source[], ");
}
if (context.request().extraSource() != null && context.request().extraSource().length() > 0) {
try {
sb.append("extra_source[").append(XContentHelper.convertToJson(context.request().extraSource(), reformat)).append("], ");
} catch (IOException e) {
sb.append("extra_source[_failed_to_convert_], ");
}
} else {
sb.append("extra_source[], ");
}
return sb.toString();
}
}

View File

@ -207,11 +207,6 @@ public class IndicesRequestCache extends AbstractComponent implements RemovalLis
* Can the shard request be cached at all?
*/
public boolean canCache(ShardSearchRequest request, SearchContext context) {
// TODO: for now, template is not supported, though we could use the generated bytes as the key
if (hasLength(request.templateSource())) {
return false;
}
// for now, only enable it for requests with no hits
if (context.size() != 0) {
return false;

View File

@ -19,36 +19,48 @@
package org.elasticsearch.rest.action.cat;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.count.CountRequest;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.support.QuerySourceBuilder;
import org.elasticsearch.bootstrap.Elasticsearch;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.Table;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.action.search.RestSearchAction;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestResponseListener;
import org.elasticsearch.rest.action.support.RestTable;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.elasticsearch.rest.RestRequest.Method.GET;
public class RestCountAction extends AbstractCatAction {
private final IndicesQueriesRegistry indicesQueriesRegistry;
@Inject
public RestCountAction(Settings settings, RestController restController, RestController controller, Client client) {
public RestCountAction(Settings settings, RestController restController, RestController controller, Client client, IndicesQueriesRegistry indicesQueriesRegistry) {
super(settings, controller, client);
restController.registerHandler(GET, "/_cat/count", this);
restController.registerHandler(GET, "/_cat/count/{index}", this);
this.indicesQueriesRegistry = indicesQueriesRegistry;
}
@Override
@ -63,16 +75,22 @@ public class RestCountAction extends AbstractCatAction {
CountRequest countRequest = new CountRequest(indices);
String source = request.param("source");
if (source != null) {
countRequest.source(source);
try (XContentParser requestParser = XContentFactory.xContent(source).createParser(source)) {
QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
context.reset(requestParser);
final SearchSourceBuilder builder = SearchSourceBuilder.PROTOTYPE.fromXContent(requestParser, context);
countRequest.searchSource(builder);
} catch (IOException e) {
throw new ElasticsearchException("failed to parse source", e);
}
} else {
QueryBuilder<?> queryBuilder = RestActions.parseQuerySource(request);
if (queryBuilder != null) {
QuerySourceBuilder querySourceBuilder = new QuerySourceBuilder();
querySourceBuilder.setQuery(queryBuilder);
countRequest.source(querySourceBuilder.buildAsBytes());
countRequest.query(queryBuilder);
}
}
client.count(countRequest, new RestResponseListener<CountResponse>(channel) {
@Override
public RestResponse buildResponse(CountResponse countResponse) throws Exception {

View File

@ -19,16 +19,22 @@
package org.elasticsearch.rest.action.count;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.count.CountRequest;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.QuerySourceBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestChannel;
@ -37,6 +43,9 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
import static org.elasticsearch.action.count.CountRequest.DEFAULT_MIN_SCORE;
import static org.elasticsearch.rest.RestRequest.Method.GET;
@ -49,8 +58,10 @@ import static org.elasticsearch.search.internal.SearchContext.DEFAULT_TERMINATE_
*/
public class RestCountAction extends BaseRestHandler {
private final IndicesQueriesRegistry indicesQueriesRegistry;
@Inject
public RestCountAction(Settings settings, RestController controller, Client client) {
public RestCountAction(Settings settings, RestController controller, Client client, IndicesQueriesRegistry indicesQueriesRegistry) {
super(settings, controller, client);
controller.registerHandler(POST, "/_count", this);
controller.registerHandler(GET, "/_count", this);
@ -58,6 +69,7 @@ public class RestCountAction extends BaseRestHandler {
controller.registerHandler(GET, "/{index}/_count", this);
controller.registerHandler(POST, "/{index}/{type}/_count", this);
controller.registerHandler(GET, "/{index}/{type}/_count", this);
this.indicesQueriesRegistry = indicesQueriesRegistry;
}
@Override
@ -65,13 +77,19 @@ public class RestCountAction extends BaseRestHandler {
CountRequest countRequest = new CountRequest(Strings.splitStringByCommaToArray(request.param("index")));
countRequest.indicesOptions(IndicesOptions.fromRequest(request, countRequest.indicesOptions()));
if (RestActions.hasBodyContent(request)) {
countRequest.source(RestActions.getRestContent(request));
BytesReference restContent = RestActions.getRestContent(request);
try (XContentParser requestParser = XContentFactory.xContent(restContent).createParser(restContent)) {
QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
context.reset(requestParser);
final SearchSourceBuilder builder = SearchSourceBuilder.PROTOTYPE.fromXContent(requestParser, context);
countRequest.searchSource(builder);
} catch (IOException e) {
throw new ElasticsearchException("failed to parse source", e);
}
} else {
QueryBuilder<?> queryBuilder = RestActions.parseQuerySource(request);
if (queryBuilder != null) {
QuerySourceBuilder querySourceBuilder = new QuerySourceBuilder();
querySourceBuilder.setQuery(queryBuilder);
countRequest.source(querySourceBuilder.buildAsBytes());
countRequest.query(queryBuilder);
}
}
countRequest.routing(request.param("routing"));

View File

@ -20,16 +20,31 @@
package org.elasticsearch.rest.action.search;
import org.elasticsearch.action.search.MultiSearchRequest;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.TemplateQueryParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestToXContentListener;
import org.elasticsearch.script.Template;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringArrayValue;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.POST;
@ -38,9 +53,11 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
public class RestMultiSearchAction extends BaseRestHandler {
private final boolean allowExplicitIndex;
private final IndicesQueriesRegistry indicesQueriesRegistry;
@Inject
public RestMultiSearchAction(Settings settings, RestController controller, Client client) {
public RestMultiSearchAction(Settings settings, RestController controller, Client client, IndicesQueriesRegistry indicesQueriesRegistry) {
super(settings, controller, client);
controller.registerHandler(GET, "/_msearch", this);
@ -58,6 +75,7 @@ public class RestMultiSearchAction extends BaseRestHandler {
controller.registerHandler(POST, "/{index}/{type}/_msearch/template", this);
this.allowExplicitIndex = settings.getAsBoolean("rest.action.multi.allow_explicit_index", true);
this.indicesQueriesRegistry = indicesQueriesRegistry;
}
@Override
@ -69,12 +87,117 @@ public class RestMultiSearchAction extends BaseRestHandler {
String path = request.path();
boolean isTemplateRequest = isTemplateRequest(path);
IndicesOptions indicesOptions = IndicesOptions.fromRequest(request, multiSearchRequest.indicesOptions());
multiSearchRequest.add(RestActions.getRestContent(request), isTemplateRequest, indices, types, request.param("search_type"), request.param("routing"), indicesOptions, allowExplicitIndex);
client.multiSearch(multiSearchRequest, new RestToXContentListener<MultiSearchResponse>(channel));
parseRequest(multiSearchRequest, RestActions.getRestContent(request), isTemplateRequest, indices, types, request.param("search_type"), request.param("routing"), indicesOptions, allowExplicitIndex, indicesQueriesRegistry);
client.multiSearch(multiSearchRequest, new RestToXContentListener<>(channel));
}
private boolean isTemplateRequest(String path) {
return (path != null && path.endsWith("/template"));
}
public static MultiSearchRequest parseRequest(MultiSearchRequest msr, BytesReference data, boolean isTemplateRequest,
@Nullable String[] indices,
@Nullable String[] types,
@Nullable String searchType,
@Nullable String routing,
IndicesOptions indicesOptions,
boolean allowExplicitIndex, IndicesQueriesRegistry indicesQueriesRegistry) throws Exception {
XContent xContent = XContentFactory.xContent(data);
int from = 0;
int length = data.length();
byte marker = xContent.streamSeparator();
final QueryParseContext queryParseContext = new QueryParseContext(indicesQueriesRegistry);
while (true) {
int nextMarker = findNextMarker(marker, from, data, length);
if (nextMarker == -1) {
break;
}
// support first line with \n
if (nextMarker == 0) {
from = nextMarker + 1;
continue;
}
SearchRequest searchRequest = new SearchRequest();
if (indices != null) {
searchRequest.indices(indices);
}
if (indicesOptions != null) {
searchRequest.indicesOptions(indicesOptions);
}
if (types != null && types.length > 0) {
searchRequest.types(types);
}
if (routing != null) {
searchRequest.routing(routing);
}
searchRequest.searchType(searchType);
IndicesOptions defaultOptions = IndicesOptions.strictExpandOpenAndForbidClosed();
// now parse the action
if (nextMarker - from > 0) {
try (XContentParser parser = xContent.createParser(data.slice(from, nextMarker - from))) {
Map<String, Object> source = parser.map();
for (Map.Entry<String, Object> entry : source.entrySet()) {
Object value = entry.getValue();
if ("index".equals(entry.getKey()) || "indices".equals(entry.getKey())) {
if (!allowExplicitIndex) {
throw new IllegalArgumentException("explicit index in multi percolate is not allowed");
}
searchRequest.indices(nodeStringArrayValue(value));
} else if ("type".equals(entry.getKey()) || "types".equals(entry.getKey())) {
searchRequest.types(nodeStringArrayValue(value));
} else if ("search_type".equals(entry.getKey()) || "searchType".equals(entry.getKey())) {
searchRequest.searchType(nodeStringValue(value, null));
} else if ("request_cache".equals(entry.getKey()) || "requestCache".equals(entry.getKey())) {
searchRequest.requestCache(nodeBooleanValue(value));
} else if ("preference".equals(entry.getKey())) {
searchRequest.preference(nodeStringValue(value, null));
} else if ("routing".equals(entry.getKey())) {
searchRequest.routing(nodeStringValue(value, null));
}
}
defaultOptions = IndicesOptions.fromMap(source, defaultOptions);
}
}
searchRequest.indicesOptions(defaultOptions);
// move pointers
from = nextMarker + 1;
// now for the body
nextMarker = findNextMarker(marker, from, data, length);
if (nextMarker == -1) {
break;
}
final BytesReference slice = data.slice(from, nextMarker - from);
if (isTemplateRequest) {
try (XContentParser parser = XContentFactory.xContent(slice).createParser(slice)) {
queryParseContext.reset(parser);
Template template = TemplateQueryParser.parse(parser, queryParseContext.parseFieldMatcher(), "params", "template");
searchRequest.template(template);
}
} else {
try (XContentParser requestParser = XContentFactory.xContent(slice).createParser(slice)) {
queryParseContext.reset(requestParser);
searchRequest.source(SearchSourceBuilder.PROTOTYPE.fromXContent(requestParser, queryParseContext));
}
}
// move pointers
from = nextMarker + 1;
msr.add(searchRequest);
}
return msr;
}
private static int findNextMarker(byte marker, int from, BytesReference data, int length) {
for (int i = from; i < length; i++) {
if (data.get(i) == marker) {
return i;
}
}
return -1;
}
}

View File

@ -20,7 +20,6 @@
package org.elasticsearch.rest.action.search;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
@ -31,8 +30,10 @@ import org.elasticsearch.common.inject.Inject;
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.TemplateQueryParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestChannel;
@ -41,6 +42,8 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.exists.RestExistsAction;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestStatusToXContentListener;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.Template;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
@ -91,26 +94,36 @@ public class RestSearchAction extends BaseRestHandler {
@Override
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) throws IOException {
SearchRequest searchRequest;
searchRequest = RestSearchAction.parseSearchRequest(request, parseFieldMatcher, queryRegistry);
client.search(searchRequest, new RestStatusToXContentListener<SearchResponse>(channel));
searchRequest = RestSearchAction.parseSearchRequest(queryRegistry, request, parseFieldMatcher);
client.search(searchRequest, new RestStatusToXContentListener<>(channel));
}
public static SearchRequest parseSearchRequest(RestRequest request, ParseFieldMatcher parseFieldMatcher, IndicesQueriesRegistry queryRegistry) throws IOException {
public static SearchRequest parseSearchRequest(IndicesQueriesRegistry indicesQueriesRegistry, RestRequest request, ParseFieldMatcher parseFieldMatcher) throws IOException {
String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
SearchRequest searchRequest = new SearchRequest(indices);
// get the content, and put it in the body
// add content/source as template if template flag is set
boolean isTemplateRequest = request.path().endsWith("/template");
final SearchSourceBuilder builder;
if (RestActions.hasBodyContent(request)) {
BytesReference restContent = RestActions.getRestContent(request);
QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
System.out.println(restContent.toUtf8());
if (isTemplateRequest) {
searchRequest.templateSource(RestActions.getRestContent(request));
try (XContentParser parser = XContentFactory.xContent(restContent).createParser(restContent)) {
context.reset(parser);
Template template = TemplateQueryParser.parse(parser, context.parseFieldMatcher(), "params", "template");
searchRequest.template(template);
}
builder = null;
} else {
BytesReference sourceBytes = RestActions.getRestContent(request);
XContentParser parser = XContentFactory.xContent(sourceBytes).createParser(sourceBytes);
QueryParseContext queryParseContext = new QueryParseContext(queryRegistry);
queryParseContext.reset(parser);
searchRequest.source(SearchSourceBuilder.PROTOTYPE.fromXContent(parser, queryParseContext));
try (XContentParser requestParser = XContentFactory.xContent(restContent).createParser(restContent)) {
context.reset(requestParser);
builder = SearchSourceBuilder.PROTOTYPE.fromXContent(requestParser, context);
}
}
} else {
builder = null;
}
// do not allow 'query_and_fetch' or 'dfs_query_and_fetch' search types
@ -123,8 +136,15 @@ public class RestSearchAction extends BaseRestHandler {
} else {
searchRequest.searchType(searchType);
}
searchRequest.extraSource(parseSearchSource(request));
if (builder == null) {
SearchSourceBuilder extraBuilder = new SearchSourceBuilder();
if (parseSearchSource(extraBuilder, request)) {
searchRequest.source(extraBuilder);
}
} else {
parseSearchSource(builder, request);
searchRequest.source(builder);
}
searchRequest.requestCache(request.paramAsBoolean("request_cache", null));
String scroll = request.param("scroll");
@ -140,111 +160,89 @@ public class RestSearchAction extends BaseRestHandler {
return searchRequest;
}
public static SearchSourceBuilder parseSearchSource(RestRequest request) {
SearchSourceBuilder searchSourceBuilder = null;
public static boolean parseSearchSource(final SearchSourceBuilder searchSourceBuilder, RestRequest request) {
boolean modified = false;
QueryBuilder<?> queryBuilder = RestActions.parseQuerySource(request);
if (queryBuilder != null) {
searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder);
modified = true;
}
int from = request.paramAsInt("from", -1);
if (from != -1) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.from(from);
modified = true;
}
int size = request.paramAsInt("size", -1);
if (size != -1) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.size(size);
modified = true;
}
if (request.hasParam("explain")) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.explain(request.paramAsBoolean("explain", null));
modified = true;
}
if (request.hasParam("version")) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.version(request.paramAsBoolean("version", null));
modified = true;
}
if (request.hasParam("timeout")) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.timeout(request.paramAsTime("timeout", null));
modified = true;
}
if (request.hasParam("terminate_after")) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
int terminateAfter = request.paramAsInt("terminate_after",
SearchContext.DEFAULT_TERMINATE_AFTER);
if (terminateAfter < 0) {
throw new IllegalArgumentException("terminateAfter must be > 0");
} else if (terminateAfter > 0) {
searchSourceBuilder.terminateAfter(terminateAfter);
modified = true;
}
}
String sField = request.param("fields");
if (sField != null) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
if (!Strings.hasText(sField)) {
searchSourceBuilder.noFields();
modified = true;
} else {
String[] sFields = Strings.splitStringByCommaToArray(sField);
if (sFields != null) {
for (String field : sFields) {
searchSourceBuilder.field(field);
modified = true;
}
}
}
}
String sFieldDataFields = request.param("fielddata_fields");
if (sFieldDataFields != null) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
if (Strings.hasText(sFieldDataFields)) {
String[] sFields = Strings.splitStringByCommaToArray(sFieldDataFields);
if (sFields != null) {
for (String field : sFields) {
searchSourceBuilder.fieldDataField(field);
modified = true;
}
}
}
}
FetchSourceContext fetchSourceContext = FetchSourceContext.parseFromRestRequest(request);
if (fetchSourceContext != null) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.fetchSource(fetchSourceContext);
modified = true;
}
if (request.hasParam("track_scores")) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.trackScores(request.paramAsBoolean("track_scores", false));
modified = true;
}
String sSorts = request.param("sort");
if (sSorts != null) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
String[] sorts = Strings.splitStringByCommaToArray(sSorts);
for (String sort : sorts) {
int delimiter = sort.lastIndexOf(":");
@ -253,37 +251,33 @@ public class RestSearchAction extends BaseRestHandler {
String reverse = sort.substring(delimiter + 1);
if ("asc".equals(reverse)) {
searchSourceBuilder.sort(sortField, SortOrder.ASC);
modified = true;
} else if ("desc".equals(reverse)) {
searchSourceBuilder.sort(sortField, SortOrder.DESC);
modified = true;
}
} else {
searchSourceBuilder.sort(sort);
modified = true;
}
}
}
String sStats = request.param("stats");
if (sStats != null) {
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
searchSourceBuilder.stats(Strings.splitStringByCommaToArray(sStats));
modified = true;
}
String suggestField = request.param("suggest_field");
if (suggestField != null) {
String suggestText = request.param("suggest_text", request.param("q"));
int suggestSize = request.paramAsInt("suggest_size", 5);
if (searchSourceBuilder == null) {
searchSourceBuilder = new SearchSourceBuilder();
}
String suggestMode = request.param("suggest_mode");
searchSourceBuilder.suggest(new SuggestBuilder().addSuggestion(
termSuggestion(suggestField).field(suggestField).text(suggestText).size(suggestSize)
.suggestMode(suggestMode))
);
termSuggestion(suggestField).field(suggestField).text(suggestText).size(suggestSize).suggestMode(suggestMode)));
modified = true;
}
return searchSourceBuilder;
return modified;
}
}

View File

@ -34,6 +34,7 @@ import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.cache.recycler.PageCacheRecycler;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.HasContextAndHeaders;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.bytes.BytesReference;
@ -50,6 +51,7 @@ import org.elasticsearch.common.util.concurrent.FutureUtils;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentLocation;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.engine.Engine;
@ -62,6 +64,7 @@ import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Loading;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.TemplateQueryParser;
import org.elasticsearch.index.search.stats.ShardSearchStats;
import org.elasticsearch.index.search.stats.StatsGroupsParseElement;
@ -578,10 +581,15 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
context.scrollContext(new ScrollContext());
context.scrollContext().scroll = request.scroll();
}
parseTemplate(request, context);
if (request.template() != null) {
ExecutableScript executable = this.scriptService.executable(request.template(), ScriptContext.Standard.SEARCH, context);
BytesReference run = (BytesReference) executable.run();
try (XContentParser parser = XContentFactory.xContent(run).createParser(run)) {
// NOCOMMIT this override the source entirely
request.source(SearchSourceBuilder.PROTOTYPE.fromXContent(parser, new QueryParseContext(indexService.queryParserService().indicesQueriesRegistry())));
}
}
parseSource(context, request.source());
// parseSource(context, request.extraSource()); NOCOMMIT fix this
// if the from and size are still not set, default them
if (context.from() == -1) {
@ -670,70 +678,6 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
}
}
private void parseTemplate(ShardSearchRequest request, SearchContext searchContext) {
BytesReference processedQuery;
if (request.template() != null) {
ExecutableScript executable = this.scriptService.executable(request.template(), ScriptContext.Standard.SEARCH, searchContext);
processedQuery = (BytesReference) executable.run();
} else {
if (!hasLength(request.templateSource())) {
return;
}
XContentParser parser = null;
Template template = null;
try {
parser = XContentFactory.xContent(request.templateSource()).createParser(request.templateSource());
template = TemplateQueryParser.parse(parser, searchContext.parseFieldMatcher(), "params", "template");
if (template.getType() == ScriptService.ScriptType.INLINE) {
//Try to double parse for nested template id/file
parser = null;
try {
ExecutableScript executable = this.scriptService.executable(template, ScriptContext.Standard.SEARCH, searchContext);
processedQuery = (BytesReference) executable.run();
parser = XContentFactory.xContent(processedQuery).createParser(processedQuery);
} catch (ElasticsearchParseException epe) {
//This was an non-nested template, the parse failure was due to this, it is safe to assume this refers to a file
//for backwards compatibility and keep going
template = new Template(template.getScript(), ScriptService.ScriptType.FILE, MustacheScriptEngineService.NAME,
null, template.getParams());
ExecutableScript executable = this.scriptService.executable(template, ScriptContext.Standard.SEARCH, searchContext);
processedQuery = (BytesReference) executable.run();
}
if (parser != null) {
try {
Template innerTemplate = TemplateQueryParser.parse(parser, searchContext.parseFieldMatcher());
if (hasLength(innerTemplate.getScript()) && !innerTemplate.getType().equals(ScriptService.ScriptType.INLINE)) {
//An inner template referring to a filename or id
template = new Template(innerTemplate.getScript(), innerTemplate.getType(),
MustacheScriptEngineService.NAME, null, template.getParams());
ExecutableScript executable = this.scriptService.executable(template, ScriptContext.Standard.SEARCH,
searchContext);
processedQuery = (BytesReference) executable.run();
}
} catch (ScriptParseException e) {
// No inner template found, use original template from above
}
}
} else {
ExecutableScript executable = this.scriptService.executable(template, ScriptContext.Standard.SEARCH, searchContext);
processedQuery = (BytesReference) executable.run();
}
} catch (IOException e) {
throw new ElasticsearchParseException("Failed to parse template", e);
} finally {
Releasables.closeWhileHandlingException(parser);
}
if (!hasLength(template.getScript())) {
throw new ElasticsearchParseException("Template must have [template] field configured");
}
}
// request.source(processedQuery); NOCOMMIT fix this
}
private void parseSource(SearchContext context, SearchSourceBuilder source) throws SearchParseException {
// nothing to parse...
if (source == null) {

View File

@ -57,9 +57,6 @@ import java.util.Map;
* A search source builder allowing to easily build search source. Simple
* construction using
* {@link org.elasticsearch.search.builder.OldSearchSourceBuilder#searchSource()}
* .
*
* @see org.elasticsearch.action.search.SearchRequest#source(OldSearchSourceBuilder)
*/
public class OldSearchSourceBuilder extends ToXContentToBytes {

View File

@ -40,6 +40,7 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.Template;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.fetch.innerhits.InnerHitsBuilder;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
@ -87,7 +88,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
public static final ParseField SORT_FIELD = new ParseField("sort");
public static final ParseField TRACK_SCORES_FIELD = new ParseField("track_scores");
public static final ParseField INDICES_BOOST_FIELD = new ParseField("indices_boost");
public static final ParseField AGGREGATIONS_FIELD = new ParseField("aggregations");
public static final ParseField AGGREGATIONS_FIELD = new ParseField("aggregations", "aggs");
public static final ParseField HIGHLIGHT_FIELD = new ParseField("highlight");
public static final ParseField INNER_HITS_FIELD = new ParseField("inner_hits");
public static final ParseField SUGGEST_FIELD = new ParseField("suggest");
@ -321,7 +322,6 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
*
* @param name
* The name of the field to sort by
* @throws IOException
*/
public SearchSourceBuilder sort(String name) {
return sort(SortBuilders.fieldSort(name));
@ -687,8 +687,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
XContentParser.Token token;
String currentFieldName = null;
if ((token = parser.nextToken()) != XContentParser.Token.START_OBJECT) {
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.START_OBJECT + "] but found ["
+ token + "]");
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.START_OBJECT + "] but found [" + token + "]",
parser.getTokenLocation());
}
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
@ -717,8 +717,11 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
List<String> fieldNames = new ArrayList<>();
fieldNames.add(parser.text());
builder.fieldNames = fieldNames;
} else if (context.parseFieldMatcher().match(currentFieldName, SORT_FIELD)) {
builder.sort(parser.text());
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (context.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
@ -742,25 +745,24 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
scriptFields
.add(new ScriptField(scriptFieldName, Script.parse(parser, context.parseFieldMatcher())));
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in ["
+ currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName
+ "].", parser.getTokenLocation());
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (context.parseFieldMatcher().match(currentFieldName, SCRIPT_FIELD)) {
scriptFields
.add(new ScriptField(scriptFieldName, Script.parse(parser, context.parseFieldMatcher())));
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in ["
+ currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName
+ "].", parser.getTokenLocation());
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in ["
+ currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName
+ "].", parser.getTokenLocation());
}
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.START_OBJECT
+ "] in ["
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.START_OBJECT + "] in ["
+ currentFieldName + "] but found [" + token + "]", parser.getTokenLocation());
}
}
@ -773,8 +775,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
} else if (token.isValue()) {
indexBoost.put(currentFieldName, parser.floatValue());
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName
+ "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
}
builder.indexBoost = indexBoost;
@ -791,8 +793,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
xContentBuilder.endObject();
aggregations.add(xContentBuilder.bytes());
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName
+ "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
}
builder.aggregations = aggregations;
@ -806,17 +808,19 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
XContentBuilder xContentBuilder = XContentFactory.contentBuilder(parser.contentType()).copyCurrentStructure(parser);
builder.suggestBuilder = xContentBuilder.bytes();
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
} else if (token == XContentParser.Token.START_ARRAY) {
if (context.parseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
List<String> fieldNames = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token == XContentParser.Token.VALUE_STRING) {
fieldNames.add(parser.text());
} else {
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING
+ "] in [" + currentFieldName + "] but found [" + token + "]");
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING + "] in ["
+ currentFieldName + "] but found [" + token + "]", parser.getTokenLocation());
}
}
builder.fieldNames = fieldNames;
@ -826,8 +830,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
if (token == XContentParser.Token.VALUE_STRING) {
fieldDataFields.add(parser.text());
} else {
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING
+ "] in [" + currentFieldName + "] but found [" + token + "]");
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING + "] in ["
+ currentFieldName + "] but found [" + token + "]", parser.getTokenLocation());
}
}
builder.fieldDataFields = fieldDataFields;
@ -851,16 +855,21 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
if (token == XContentParser.Token.VALUE_STRING) {
stats.add(parser.text());
} else {
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING
+ "] in [" + currentFieldName + "] but found [" + token + "]");
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING + "] in ["
+ currentFieldName + "] but found [" + token + "]", parser.getTokenLocation());
}
}
builder.stats = stats.toArray(new String[stats.size()]);
} else if (context.parseFieldMatcher().match(currentFieldName, _SOURCE_FIELD)) {
FetchSourceContext fetchSourceContext = FetchSourceContext.parse(parser, context);
builder.fetchSourceContext = fetchSourceContext;
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
}
return builder;

View File

@ -41,8 +41,8 @@ import java.util.List;
*/
public class FetchSourceContext implements Streamable, ToXContent {
public static final ParseField INCLUDES_FIELD = new ParseField("includes");
public static final ParseField EXCLUDES_FIELD = new ParseField("excludes");
public static final ParseField INCLUDES_FIELD = new ParseField("includes", "include");
public static final ParseField EXCLUDES_FIELD = new ParseField("excludes", "exclude");
public static final FetchSourceContext FETCH_SOURCE = new FetchSourceContext(true);
public static final FetchSourceContext DO_NOT_FETCH_SOURCE = new FetchSourceContext(false);
@ -194,6 +194,14 @@ public class FetchSourceContext implements Streamable, ToXContent {
String[] excludes = Strings.EMPTY_ARRAY;
if (token == XContentParser.Token.VALUE_BOOLEAN) {
fetchSource = parser.booleanValue();
} else if (token == XContentParser.Token.VALUE_STRING) {
includes = new String[]{parser.text()};
} else if (token == XContentParser.Token.START_ARRAY) {
ArrayList<String> list = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
list.add(parser.text());
}
includes = list.toArray(new String[list.size()]);
} else if (token == XContentParser.Token.START_OBJECT) {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
@ -206,8 +214,8 @@ public class FetchSourceContext implements Streamable, ToXContent {
if (token == XContentParser.Token.VALUE_STRING) {
includesList.add(parser.text());
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in ["
+ currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
}
includes = includesList.toArray(new String[includesList.size()]);
@ -217,22 +225,29 @@ public class FetchSourceContext implements Streamable, ToXContent {
if (token == XContentParser.Token.VALUE_STRING) {
excludesList.add(parser.text());
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in ["
+ currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
}
excludes = excludesList.toArray(new String[excludesList.size()]);
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName
+ "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (context.parseFieldMatcher().match(currentFieldName, INCLUDES_FIELD)) {
includes = new String[] {parser.text()};
} else if (context.parseFieldMatcher().match(currentFieldName, EXCLUDES_FIELD)) {
excludes = new String[] {parser.text()};
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].");
throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
parser.getTokenLocation());
}
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Expected one of [" + XContentParser.Token.VALUE_BOOLEAN + ", "
+ XContentParser.Token.START_OBJECT + "] but found [" + token + "]");
+ XContentParser.Token.START_OBJECT + "] but found [" + token + "]", parser.getTokenLocation());
}
this.fetchSource = fetchSource;
this.includes = includes;

View File

@ -67,8 +67,6 @@ public class ShardSearchLocalRequest extends ContextAndHeaderHolder implements S
private String[] types = Strings.EMPTY_ARRAY;
private String[] filteringAliases;
private SearchSourceBuilder source;
private BytesReference extraSource;
private BytesReference templateSource;
private Template template;
private Boolean requestCache;
private long nowInMillis;
@ -80,8 +78,6 @@ public class ShardSearchLocalRequest extends ContextAndHeaderHolder implements S
String[] filteringAliases, long nowInMillis) {
this(shardRouting.shardId(), numberOfShards, searchRequest.searchType(),
searchRequest.source(), searchRequest.types(), searchRequest.requestCache());
this.extraSource = searchRequest.extraSource();
this.templateSource = searchRequest.templateSource();
this.template = searchRequest.template();
this.scroll = searchRequest.scroll();
this.filteringAliases = filteringAliases;
@ -135,11 +131,6 @@ public class ShardSearchLocalRequest extends ContextAndHeaderHolder implements S
this.source = source;
}
@Override
public BytesReference extraSource() {
return extraSource;
}
@Override
public int numberOfShards() {
return numberOfShards;
@ -159,17 +150,11 @@ public class ShardSearchLocalRequest extends ContextAndHeaderHolder implements S
public long nowInMillis() {
return nowInMillis;
}
@Override
public Template template() {
return template;
}
@Override
public BytesReference templateSource() {
return templateSource;
}
@Override
public Boolean requestCache() {
return requestCache;
@ -189,18 +174,11 @@ public class ShardSearchLocalRequest extends ContextAndHeaderHolder implements S
if (in.readBoolean()) {
scroll = readScroll(in);
}
source = SearchSourceBuilder.PROTOTYPE.readFrom(in);
extraSource = in.readBytesReference();
types = in.readStringArray();
filteringAliases = in.readStringArray();
nowInMillis = in.readVLong();
templateSource = in.readBytesReference();
if (in.readBoolean()) {
template = Template.readTemplate(in);
}
template = in.readOptionalStreamable(new Template());
requestCache = in.readOptionalBoolean();
}
@ -218,19 +196,13 @@ public class ShardSearchLocalRequest extends ContextAndHeaderHolder implements S
scroll.writeTo(out);
}
source.writeTo(out);
out.writeBytesReference(extraSource);
out.writeStringArray(types);
out.writeStringArrayNullable(filteringAliases);
if (!asKey) {
out.writeVLong(nowInMillis);
}
out.writeBytesReference(templateSource);
boolean hasTemplate = template != null;
out.writeBoolean(hasTemplate);
if (hasTemplate) {
template.writeTo(out);
}
out.writeOptionalStreamable(template);
out.writeOptionalBoolean(requestCache);
}

View File

@ -45,8 +45,6 @@ public interface ShardSearchRequest extends HasContextAndHeaders {
void source(SearchSourceBuilder source);
BytesReference extraSource();
int numberOfShards();
SearchType searchType();
@ -57,8 +55,6 @@ public interface ShardSearchRequest extends HasContextAndHeaders {
Template template();
BytesReference templateSource();
Boolean requestCache();
Scroll scroll();

View File

@ -97,11 +97,6 @@ public class ShardSearchTransportRequest extends TransportRequest implements Sha
shardSearchLocalRequest.source(source);
}
@Override
public BytesReference extraSource() {
return shardSearchLocalRequest.extraSource();
}
@Override
public int numberOfShards() {
return shardSearchLocalRequest.numberOfShards();
@ -121,17 +116,11 @@ public class ShardSearchTransportRequest extends TransportRequest implements Sha
public long nowInMillis() {
return shardSearchLocalRequest.nowInMillis();
}
@Override
public Template template() {
return shardSearchLocalRequest.template();
}
@Override
public BytesReference templateSource() {
return shardSearchLocalRequest.templateSource();
}
@Override
public Boolean requestCache() {
return shardSearchLocalRequest.requestCache();

View File

@ -28,7 +28,10 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.ESTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@ -75,58 +78,14 @@ public class CountRequestBuilderTests extends ESTestCase {
@Test
public void testStringQueryToString() {
CountRequestBuilder countRequestBuilder = client.prepareCount();
String query = "{ \"match_all\" : {} }";
countRequestBuilder.setQuery(new BytesArray(query));
assertThat(countRequestBuilder.toString(), containsString("\"query\":{ \"match_all\" : {} }"));
}
@Test
public void testXContentBuilderQueryToString() throws IOException {
CountRequestBuilder countRequestBuilder = client.prepareCount();
XContentBuilder xContentBuilder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
xContentBuilder.startObject();
xContentBuilder.startObject("match_all");
xContentBuilder.endObject();
xContentBuilder.endObject();
countRequestBuilder.setQuery(xContentBuilder);
assertThat(countRequestBuilder.toString(), equalTo(new QuerySourceBuilder().setQuery(xContentBuilder.bytes()).toString()));
countRequestBuilder.setQuery(new MatchAllQueryBuilder());
assertThat(countRequestBuilder.toString(), containsString("match_all"));
}
@Test
public void testStringSourceToString() {
CountRequestBuilder countRequestBuilder = client.prepareCount();
String query = "{ \"query\": { \"match_all\" : {} } }";
countRequestBuilder.setSource(new BytesArray(query));
assertThat(countRequestBuilder.toString(), equalTo("{ \"query\": { \"match_all\" : {} } }"));
}
@Test
public void testXContentBuilderSourceToString() throws IOException {
CountRequestBuilder countRequestBuilder = client.prepareCount();
XContentBuilder xContentBuilder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
xContentBuilder.startObject();
xContentBuilder.startObject("match_all");
xContentBuilder.endObject();
xContentBuilder.endObject();
countRequestBuilder.setSource(xContentBuilder.bytes());
assertThat(countRequestBuilder.toString(), equalTo(XContentHelper.convertToJson(xContentBuilder.bytes(), false, true)));
}
@Test
public void testThatToStringDoesntWipeSource() {
String source = "{\n" +
" \"query\" : {\n" +
" \"match\" : {\n" +
" \"field\" : {\n" +
" \"query\" : \"value\"" +
" }\n" +
" }\n" +
" }\n" +
" }";
CountRequestBuilder countRequestBuilder = client.prepareCount().setSource(new BytesArray(source));
String preToString = countRequestBuilder.request().source().toUtf8();
assertThat(countRequestBuilder.toString(), equalTo(source));
String postToString = countRequestBuilder.request().source().toUtf8();
assertThat(preToString, equalTo(postToString));
countRequestBuilder.setSource(new SearchSourceBuilder().query(new MatchAllQueryBuilder()));
assertThat(countRequestBuilder.toString(), containsString("match_all"));
}
}

View File

@ -22,6 +22,7 @@ package org.elasticsearch.action.count;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.QuerySourceBuilder;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.internal.SearchContext;
@ -56,8 +57,9 @@ public class CountRequestTests extends ESTestCase {
if (randomBoolean()) {
countRequest.preference(randomAsciiOfLengthBetween(1, 10));
}
if (randomBoolean()) {
countRequest.source(new QuerySourceBuilder().setQuery(QueryBuilders.termQuery("field", "value")));
final boolean querySet;
if (querySet = randomBoolean()) {
countRequest.query(QueryBuilders.termQuery("field", "value"));
}
if (randomBoolean()) {
countRequest.minScore(randomFloat());
@ -72,29 +74,29 @@ public class CountRequestTests extends ESTestCase {
assertThat(searchRequest.types(), equalTo(countRequest.types()));
assertThat(searchRequest.routing(), equalTo(countRequest.routing()));
assertThat(searchRequest.preference(), equalTo(countRequest.preference()));
if (countRequest.source() == null) {
assertThat(searchRequest.source(), nullValue());
} else {
assertThat(searchRequest.source().query(), notNullValue());
}
Map<String, Object> extraSourceMap = XContentHelper.convertToMap(searchRequest.extraSource(), false).v2();
BytesArray array = new BytesArray(XContentHelper.toString(searchRequest.source()));
Map<String, Object> sourceMap = XContentHelper.convertToMap(array, false).v2();
int count = 1;
assertThat((Integer)extraSourceMap.get("size"), equalTo(0));
if (countRequest.minScore() == CountRequest.DEFAULT_MIN_SCORE) {
assertThat(extraSourceMap.get("min_score"), nullValue());
assertThat(sourceMap.get("size"), equalTo(0));
if (querySet) {
count++;
assertThat(sourceMap.get("query"), notNullValue());
} else {
assertThat(((Number)extraSourceMap.get("min_score")).floatValue(), equalTo(countRequest.minScore()));
assertNull(sourceMap.get("query"));
}
if (countRequest.minScore() == CountRequest.DEFAULT_MIN_SCORE) {
assertThat(sourceMap.get("min_score"), nullValue());
} else {
assertThat(((Number)sourceMap.get("min_score")).floatValue(), equalTo(countRequest.minScore()));
count++;
}
if (countRequest.terminateAfter() == SearchContext.DEFAULT_TERMINATE_AFTER) {
assertThat(extraSourceMap.get("terminate_after"), nullValue());
assertThat(sourceMap.get("terminate_after"), nullValue());
} else {
assertThat((Integer)extraSourceMap.get("terminate_after"), equalTo(countRequest.terminateAfter()));
assertThat(sourceMap.get("terminate_after"), equalTo(countRequest.terminateAfter()));
count++;
}
assertThat(extraSourceMap.size(), equalTo(count));
assertThat(sourceMap.toString(), sourceMap.size(), equalTo(count));
}
private static String[] randomStringArray() {

View File

@ -20,6 +20,13 @@
package org.elasticsearch.action.search;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.query.MatchAllQueryParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.rest.action.search.RestMultiSearchAction;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.test.StreamsUtils;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -28,6 +35,7 @@ import org.elasticsearch.test.ESTestCase;
import org.junit.Test;
import java.io.IOException;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
@ -36,8 +44,9 @@ public class MultiSearchRequestTests extends ESTestCase {
@Test
public void simpleAdd() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY, Collections.singleton(new MatchAllQueryParser()), new NamedWriteableRegistry());
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch1.json");
MultiSearchRequest request = new MultiSearchRequest().add(data, 0, data.length, false, null, null, null);
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null, null, null, IndicesOptions.strictExpandOpenAndForbidClosed(),true, registry);
assertThat(request.requests().size(), equalTo(8));
assertThat(request.requests().get(0).indices()[0], equalTo("test"));
assertThat(request.requests().get(0).indicesOptions(), equalTo(IndicesOptions.fromOptions(true, true, true, true, IndicesOptions.strictExpandOpenAndForbidClosed())));
@ -62,8 +71,9 @@ public class MultiSearchRequestTests extends ESTestCase {
@Test
public void simpleAdd2() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY, Collections.singleton(new MatchAllQueryParser()), new NamedWriteableRegistry());
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch2.json");
MultiSearchRequest request = new MultiSearchRequest().add(data, 0, data.length, false, null, null, null);
MultiSearchRequest request =RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null, null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry);
assertThat(request.requests().size(), equalTo(5));
assertThat(request.requests().get(0).indices()[0], equalTo("test"));
assertThat(request.requests().get(0).types().length, equalTo(0));
@ -80,8 +90,9 @@ public class MultiSearchRequestTests extends ESTestCase {
@Test
public void simpleAdd3() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY, Collections.singleton(new MatchAllQueryParser()), new NamedWriteableRegistry());
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch3.json");
MultiSearchRequest request = new MultiSearchRequest().add(data, 0, data.length, false, null, null, null);
MultiSearchRequest request =RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null, null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry);
assertThat(request.requests().size(), equalTo(4));
assertThat(request.requests().get(0).indices()[0], equalTo("test0"));
assertThat(request.requests().get(0).indices()[1], equalTo("test1"));
@ -99,8 +110,9 @@ public class MultiSearchRequestTests extends ESTestCase {
@Test
public void simpleAdd4() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY, Collections.singleton(new MatchAllQueryParser()), new NamedWriteableRegistry());
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch4.json");
MultiSearchRequest request = new MultiSearchRequest().add(data, 0, data.length, false, null, null, null);
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null, null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry);
assertThat(request.requests().size(), equalTo(3));
assertThat(request.requests().get(0).indices()[0], equalTo("test0"));
assertThat(request.requests().get(0).indices()[1], equalTo("test1"));
@ -120,8 +132,9 @@ public class MultiSearchRequestTests extends ESTestCase {
@Test
public void simpleAdd5() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY, Collections.singleton(new MatchAllQueryParser()), new NamedWriteableRegistry());
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch5.json");
MultiSearchRequest request = new MultiSearchRequest().add(data, 0, data.length, true, null, null, null);
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), true, null, null, null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry);
assertThat(request.requests().size(), equalTo(3));
assertThat(request.requests().get(0).indices()[0], equalTo("test0"));
assertThat(request.requests().get(0).indices()[1], equalTo("test1"));
@ -137,6 +150,18 @@ public class MultiSearchRequestTests extends ESTestCase {
assertThat(request.requests().get(2).types()[0], equalTo("type2"));
assertThat(request.requests().get(2).types()[1], equalTo("type1"));
assertThat(request.requests().get(2).routing(), equalTo("123"));
assertNotNull(request.requests().get(0).template());
assertNotNull(request.requests().get(1).template());
assertNotNull(request.requests().get(2).template());
assertEquals(ScriptService.ScriptType.INLINE, request.requests().get(0).template().getType());
assertEquals(ScriptService.ScriptType.INLINE, request.requests().get(1).template().getType());
assertEquals(ScriptService.ScriptType.INLINE, request.requests().get(2).template().getType());
assertEquals("{\"query\":{\"match_{{template}}\":{}}}", request.requests().get(0).template().getScript());
assertEquals("{\"query\":{\"match_{{template}}\":{}}}", request.requests().get(1).template().getScript());
assertEquals("{\"query\":{\"match_{{template}}\":{}}}", request.requests().get(2).template().getScript());
assertEquals(1, request.requests().get(0).template().getParams().size());
assertEquals(1, request.requests().get(1).template().getParams().size());
assertEquals(1, request.requests().get(2).template().getParams().size());
}
public void testResponseErrorToXContent() throws IOException {

View File

@ -68,15 +68,6 @@ public class BroadcastActionsIT extends ESIntegTestCase {
assertThat(countResponse.getSuccessfulShards(), equalTo(numShards.numPrimaries));
assertThat(countResponse.getFailedShards(), equalTo(0));
}
for (int i = 0; i < 5; i++) {
// test failed (simply query that can't be parsed)
try {
client().count(countRequest("test").source("{ term : { _type : \"type1 } }".getBytes(StandardCharsets.UTF_8))).actionGet();
} catch(SearchPhaseExecutionException e) {
assertThat(e.shardFailures().length, equalTo(numShards.numPrimaries));
}
}
}
private XContentBuilder source(String id, String nameValue) throws IOException {

View File

@ -32,6 +32,8 @@ import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.search.MultiMatchQuery;
import org.elasticsearch.test.ESIntegTestCase;
import org.junit.Test;
@ -163,13 +165,6 @@ public class DocumentActionsIT extends ESIntegTestCase {
assertThat(countResponse.getSuccessfulShards(), equalTo(numShards.numPrimaries));
assertThat(countResponse.getFailedShards(), equalTo(0));
// test failed (simply query that can't be parsed)
try {
client().count(countRequest("test").source("{ term : { _type : \"type1 } }")).actionGet();
} catch(SearchPhaseExecutionException e) {
assertThat(e.shardFailures().length, equalTo(numShards.numPrimaries));
}
// count with no query is a match all one
countResponse = client().prepareCount("test").execute().actionGet();
assertThat("Failures " + countResponse.getShardFailures(), countResponse.getShardFailures() == null ? 0 : countResponse.getShardFailures().length, equalTo(0));

View File

@ -27,14 +27,22 @@ import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.HasContextAndHeaders;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.Template;
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.internal.DefaultSearchContext;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.rest.FakeRestRequest;
import org.junit.Before;
import org.junit.Test;
@ -177,13 +185,18 @@ public class TemplateQueryIT extends ESIntegTestCase {
searchRequest.indices("_all");
String query = "{ \"template\" : { \"query\": {\"match_{{template}}\": {} } }, \"params\" : { \"template\":\"all\" } }";
BytesReference bytesRef = new BytesArray(query);
searchRequest.templateSource(bytesRef);
searchRequest.template(parseTemplate(query));
SearchResponse searchResponse = client().search(searchRequest).get();
assertHitCount(searchResponse, 2);
}
private Template parseTemplate(String template) throws IOException {
try (XContentParser parser = XContentFactory.xContent(template).createParser(template)) {
return TemplateQueryParser.parse(parser, ParseFieldMatcher.EMPTY, "params", "template");
}
}
@Test
// Releates to #6318
public void testSearchRequestFail() throws Exception {
@ -191,16 +204,14 @@ public class TemplateQueryIT extends ESIntegTestCase {
searchRequest.indices("_all");
try {
String query = "{ \"template\" : { \"query\": {\"match_all\": {}}, \"size\" : \"{{my_size}}\" } }";
BytesReference bytesRef = new BytesArray(query);
searchRequest.templateSource(bytesRef);
searchRequest.template(parseTemplate(query));
client().search(searchRequest).get();
fail("expected exception");
} catch (Exception ex) {
// expected - no params
}
String query = "{ \"template\" : { \"query\": {\"match_all\": {}}, \"size\" : \"{{my_size}}\" }, \"params\" : { \"my_size\": 1 } }";
BytesReference bytesRef = new BytesArray(query);
searchRequest.templateSource(bytesRef);
searchRequest.template(parseTemplate(query));
SearchResponse searchResponse = client().search(searchRequest).get();
assertThat(searchResponse.getHits().hits().length, equalTo(1));
@ -238,10 +249,9 @@ public class TemplateQueryIT extends ESIntegTestCase {
public void testSearchTemplateQueryFromFile() throws Exception {
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("_all");
String templateString = "{" + " \"file\": \"full-query-template\"," + " \"params\":{" + " \"mySize\": 2,"
String query = "{" + " \"file\": \"full-query-template\"," + " \"params\":{" + " \"mySize\": 2,"
+ " \"myField\": \"text\"," + " \"myValue\": \"value1\"" + " }" + "}";
BytesReference bytesRef = new BytesArray(templateString);
searchRequest.templateSource(bytesRef);
searchRequest.template(parseTemplate(query));
SearchResponse searchResponse = client().search(searchRequest).get();
assertThat(searchResponse.getHits().hits().length, equalTo(1));
}
@ -253,10 +263,9 @@ public class TemplateQueryIT extends ESIntegTestCase {
public void testTemplateQueryAsEscapedString() throws Exception {
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("_all");
String templateString = "{" + " \"template\" : \"{ \\\"size\\\": \\\"{{size}}\\\", \\\"query\\\":{\\\"match_all\\\":{}}}\","
String query = "{" + " \"template\" : \"{ \\\"size\\\": \\\"{{size}}\\\", \\\"query\\\":{\\\"match_all\\\":{}}}\","
+ " \"params\":{" + " \"size\": 1" + " }" + "}";
BytesReference bytesRef = new BytesArray(templateString);
searchRequest.templateSource(bytesRef);
searchRequest.template(parseTemplate(query));
SearchResponse searchResponse = client().search(searchRequest).get();
assertThat(searchResponse.getHits().hits().length, equalTo(1));
}
@ -272,8 +281,7 @@ public class TemplateQueryIT extends ESIntegTestCase {
String templateString = "{"
+ " \"template\" : \"{ {{#use_size}} \\\"size\\\": \\\"{{size}}\\\", {{/use_size}} \\\"query\\\":{\\\"match_all\\\":{}}}\","
+ " \"params\":{" + " \"size\": 1," + " \"use_size\": true" + " }" + "}";
BytesReference bytesRef = new BytesArray(templateString);
searchRequest.templateSource(bytesRef);
searchRequest.template(parseTemplate(templateString));
SearchResponse searchResponse = client().search(searchRequest).get();
assertThat(searchResponse.getHits().hits().length, equalTo(1));
}
@ -289,8 +297,7 @@ public class TemplateQueryIT extends ESIntegTestCase {
String templateString = "{"
+ " \"inline\" : \"{ \\\"query\\\":{\\\"match_all\\\":{}} {{#use_size}}, \\\"size\\\": \\\"{{size}}\\\" {{/use_size}} }\","
+ " \"params\":{" + " \"size\": 1," + " \"use_size\": true" + " }" + "}";
BytesReference bytesRef = new BytesArray(templateString);
searchRequest.templateSource(bytesRef);
searchRequest.template(parseTemplate(templateString));
SearchResponse searchResponse = client().search(searchRequest).get();
assertThat(searchResponse.getHits().hits().length, equalTo(1));
}

View File

@ -45,6 +45,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsModule;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.env.Environment;
@ -145,7 +146,6 @@ public class NewSearchSourceBuilderTests extends ESTestCase {
/**
* Setup for the whole base test class.
* @throws IOException
*/
@BeforeClass
public static void init() throws IOException {
@ -571,4 +571,55 @@ public class NewSearchSourceBuilderTests extends ESTestCase {
throw new UnsupportedOperationException("this test can't handle MultiTermVector requests");
}
public void testParseIncludeExclude() throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
{
String restContent = " { \"_source\": { \"includes\": \"include\", \"excludes\": \"*.field2\"}}";
try (XContentParser parser = XContentFactory.xContent(restContent).createParser(restContent)) {
SearchSourceBuilder searchSourceBuilder = builder.fromXContent(parser, new QueryParseContext(queryParserService.indicesQueriesRegistry()));
assertArrayEquals(new String[]{"*.field2" }, searchSourceBuilder.fetchSource().excludes());
assertArrayEquals(new String[]{"include" }, searchSourceBuilder.fetchSource().includes());
}
}
{
String restContent = " { \"_source\": false}";
try (XContentParser parser = XContentFactory.xContent(restContent).createParser(restContent)) {
SearchSourceBuilder searchSourceBuilder = builder.fromXContent(parser, new QueryParseContext(queryParserService.indicesQueriesRegistry()));
assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().excludes());
assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().includes());
assertFalse(searchSourceBuilder.fetchSource().fetchSource());
}
}
}
public void testParseSort() throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
{
String restContent = " { \"sort\": \"foo\"}";
try (XContentParser parser = XContentFactory.xContent(restContent).createParser(restContent)) {
SearchSourceBuilder searchSourceBuilder = builder.fromXContent(parser, new QueryParseContext(queryParserService.indicesQueriesRegistry()));
assertEquals(1, searchSourceBuilder.sorts().size());
assertEquals("{\"foo\":{}}", searchSourceBuilder.sorts().get(0).toUtf8());
}
}
{
String restContent = "{\"sort\" : [\n" +
" { \"post_date\" : {\"order\" : \"asc\"}},\n" +
" \"user\",\n" +
" { \"name\" : \"desc\" },\n" +
" { \"age\" : \"desc\" },\n" +
" \"_score\"\n" +
" ]}";
try (XContentParser parser = XContentFactory.xContent(restContent).createParser(restContent)) {
SearchSourceBuilder searchSourceBuilder = builder.fromXContent(parser, new QueryParseContext(queryParserService.indicesQueriesRegistry()));
assertEquals(5, searchSourceBuilder.sorts().size());
assertEquals("{\"post_date\":{\"order\":\"asc\"}}", searchSourceBuilder.sorts().get(0).toUtf8());
assertEquals("\"user\"", searchSourceBuilder.sorts().get(1).toUtf8());
assertEquals("{\"name\":\"desc\"}", searchSourceBuilder.sorts().get(2).toUtf8());
assertEquals("{\"age\":\"desc\"}", searchSourceBuilder.sorts().get(3).toUtf8());
assertEquals("\"_score\"", searchSourceBuilder.sorts().get(4).toUtf8());
}
}
}
}

View File

@ -67,6 +67,7 @@ import org.elasticsearch.script.groovy.GroovyScriptEngineService;
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder;

View File

@ -1,16 +1,16 @@
{"index":"test", "ignore_unavailable" : true, "expand_wildcards" : "open,closed"}}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}
{"index" : "test", "type" : "type1", "expand_wildcards" : ["open", "closed"]}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}
{"index":"test", "ignore_unavailable" : false, "expand_wildcards" : ["open"]}}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}
{"index":"test", "ignore_unavailable" : true, "allow_no_indices": true, "expand_wildcards" : ["open", "closed"]}}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}
{"index":"test", "ignore_unavailable" : true, "allow_no_indices": false, "expand_wildcards" : ["closed"]}}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}
{}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}
{"search_type" : "dfs_query_then_fetch"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}
{"query" : {"match_all" {}}}
{"query" : {"match_all" :{}}}

View File

@ -1,10 +1,10 @@
{"index":"test"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"index" : "test", "type" : "type1"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"search_type" : "dfs_query_then_fetch"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}

View File

@ -1,8 +1,8 @@
{"index":["test0", "test1"]}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"index" : "test2,test3", "type" : "type1"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"index" : ["test4", "test1"], "type" : [ "type2", "type1" ]}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"search_type" : "dfs_query_then_fetch"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}

View File

@ -1,6 +1,6 @@
{"index":["test0", "test1"], "request_cache": true}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"index" : "test2,test3", "type" : "type1", "preference": "_local"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}
{"index" : ["test4", "test1"], "type" : [ "type2", "type1" ], "routing": "123"}
{"query" : {"match_all" {}}}
{"query" : {"match_all" : {}}}

View File

@ -1,6 +1,6 @@
{"index":["test0", "test1"], "request_cache": true}
{"template": {"query" : {"match_{{template}}" {}}}, "params": {"template": "all" } } }
{"template": {"query" : {"match_{{template}}" :{}}}, "params": {"template": "all" } } }
{"index" : "test2,test3", "type" : "type1", "preference": "_local"}
{"template": {"query" : {"match_{{template}}" {}}}, "params": {"template": "all" } } }
{"template": {"query" : {"match_{{template}}" :{}}}, "params": {"template": "all" } } }
{"index" : ["test4", "test1"], "type" : [ "type2", "type1" ], "routing": "123"}
{"template": {"query" : {"match_{{template}}" {}}}, "params": {"template": "all" } } }
{"template": {"query" : {"match_{{template}}" :{}}}, "params": {"template": "all" } } }

View File

@ -22,6 +22,6 @@ setup:
---
"Expressions scripting test":
- do: { search: { body: { script_fields : { my_field : { lang: expression, script: 'doc["age"].value + 19' } } } } }
- do: { search: { body: { script_fields : { my_field : { script: { lang: expression, inline: 'doc["age"].value + 19' } } } } } }
- match: { hits.hits.0.fields.my_field.0: 42.0 }

View File

@ -14,12 +14,12 @@
- do:
search:
# stringified for boolean value
body: "{ _source: true, query: { match_all: {} } }"
body: { _source: true, query: { match_all: {} } }
- length: { hits.hits: 1 }
- match: { hits.hits.0._source.count: 1 }
- do: { search: { body: "{ _source: false, query: { match_all: {} } }" } }
- do: { search: { body: { _source: false, query: { match_all: {} } } } }
- length: { hits.hits: 1 }
- is_false: hits.hits.0._source

View File

@ -26,11 +26,6 @@
indices.refresh: {}
- do:
search_template:
body: { "template": { "id" : "1" }, "params" : { "my_value" : "value1_foo", "my_size" : 1 } }
- match: { hits.total: 1 }
- do:
search_template:
body: { "id" : "1", "params" : { "my_value" : "value1_foo", "my_size" : 1 } }
@ -39,5 +34,5 @@
- do:
catch: /Unable.to.find.on.disk.file.script.\[simple1\].using.lang.\[mustache\]/
search_template:
body: { "template" : "simple1" }
body: { "file" : "simple1"}