Scripting: Created a parameter parse to standardised script options

This commit is contained in:
Colin Goodheart-Smithe 2014-10-03 17:13:24 +01:00
parent e799ac9bd6
commit c047fbda9b
11 changed files with 1663 additions and 185 deletions

View File

@ -39,6 +39,8 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService;
import java.io.IOException;
@ -578,6 +580,7 @@ public class UpdateRequest extends InstanceShardOperationRequest<UpdateRequest>
}
public UpdateRequest source(BytesReference source) throws Exception {
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
XContentType xContentType = XContentFactory.xContentType(source);
try (XContentParser parser = XContentFactory.xContent(xContentType).createParser(source)) {
XContentParser.Token token = parser.nextToken();
@ -588,16 +591,8 @@ public class UpdateRequest extends InstanceShardOperationRequest<UpdateRequest>
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if ("script".equals(currentFieldName)) {
script = parser.textOrNull();
scriptType = ScriptService.ScriptType.INLINE;
} else if ("script_id".equals(currentFieldName)) {
script = parser.textOrNull();
scriptType = ScriptService.ScriptType.INDEXED;
} else if ("params".equals(currentFieldName)) {
scriptParams = parser.map();
} else if ("lang".equals(currentFieldName)) {
scriptLang = parser.text();
} else if ("scripted_upsert".equals(currentFieldName)) {
scriptedUpsert = parser.booleanValue();
} else if ("upsert".equals(currentFieldName)) {
@ -612,8 +607,16 @@ public class UpdateRequest extends InstanceShardOperationRequest<UpdateRequest>
docAsUpsert(parser.booleanValue());
} else if ("detect_noop".equals(currentFieldName)) {
detectNoop(parser.booleanValue());
} else {
scriptParameterParser.token(currentFieldName, token, parser);
}
}
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
if (scriptValue != null) {
script = scriptValue.script();
scriptType = scriptValue.scriptType();
}
scriptLang = scriptParameterParser.lang();
}
return this;
}

View File

@ -46,6 +46,8 @@ import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
import org.elasticsearch.index.settings.IndexSettings;
import org.elasticsearch.index.similarity.SimilarityLookupService;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptService.ScriptType;
@ -301,18 +303,19 @@ public class DocumentMapperParser extends AbstractIndexComponent {
@SuppressWarnings("unchecked")
private void parseTransform(DocumentMapper.Builder docBuilder, Map<String, Object> transformConfig) {
String script = (String) transformConfig.remove("script_file");
ScriptType scriptType = ScriptType.FILE;
if (script == null) {
script = (String) transformConfig.remove("script_id");
scriptType = ScriptType.INDEXED;
}
if (script == null) {
script = (String) transformConfig.remove("script");
scriptType = ScriptType.INLINE;
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
scriptParameterParser.parseConfig(transformConfig, true);
String script = null;
ScriptType scriptType = null;
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
if (scriptValue != null) {
script = scriptValue.script();
scriptType = scriptValue.scriptType();
}
if (script != null) {
String scriptLang = (String) transformConfig.remove("lang");
String scriptLang = scriptParameterParser.lang();
Map<String, Object> params = (Map<String, Object>)transformConfig.remove("params");
docBuilder.transform(scriptService, script, scriptType, scriptLang, params);
}

View File

@ -30,6 +30,8 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.docset.MatchDocIdSet;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.cache.filter.support.CacheKeyFilter;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.lookup.SearchLookup;
@ -58,6 +60,7 @@ public class ScriptFilterParser implements FilterParser {
@Override
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
XContentParser parser = parseContext.parser();
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
XContentParser.Token token;
@ -82,29 +85,25 @@ public class ScriptFilterParser implements FilterParser {
throw new QueryParsingException(parseContext.index(), "[script] filter does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if ("script".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.INLINE;
} else if ("script_id".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.INDEXED;
} else if ("file".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.FILE;
} else if ("lang".equals(currentFieldName)) {
scriptLang = parser.text();
} else if ("_name".equals(currentFieldName)) {
if ("_name".equals(currentFieldName)) {
filterName = parser.text();
} else if ("_cache".equals(currentFieldName)) {
cache = parser.booleanValue();
} else if ("_cache_key".equals(currentFieldName) || "_cacheKey".equals(currentFieldName)) {
cacheKey = new CacheKeyFilter.Key(parser.text());
} else {
} else if (!scriptParameterParser.token(currentFieldName, token, parser)){
throw new QueryParsingException(parseContext.index(), "[script] filter does not support [" + currentFieldName + "]");
}
}
}
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
if (scriptValue != null) {
script = scriptValue.script();
scriptType = scriptValue.scriptType();
}
scriptLang = scriptParameterParser.lang();
if (script == null) {
throw new QueryParsingException(parseContext.index(), "script must be provided with a [script] filter");
}

View File

@ -28,6 +28,8 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.query.functionscore.ScoreFunctionParser;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.SearchScript;
@ -52,7 +54,7 @@ public class ScriptScoreFunctionParser implements ScoreFunctionParser {
@Override
public ScoreFunction parse(QueryParseContext parseContext, XContentParser parser) throws IOException, QueryParsingException {
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
String script = null;
String scriptLang = null;
Map<String, Object> vars = null;
@ -69,22 +71,19 @@ public class ScriptScoreFunctionParser implements ScoreFunctionParser {
throw new QueryParsingException(parseContext.index(), NAMES[0] + " query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if ("script".equals(currentFieldName)) {
script = parser.text();
} else if ("script_id".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.INDEXED;
} else if ("file".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.FILE;
} else if ("lang".equals(currentFieldName)) {
scriptLang = parser.text();
} else {
if (!scriptParameterParser.token(currentFieldName, token, parser)) {
throw new QueryParsingException(parseContext.index(), NAMES[0] + " query does not support [" + currentFieldName + "]");
}
}
}
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
if (scriptValue != null) {
script = scriptValue.script();
scriptType = scriptValue.scriptType();
}
scriptLang = scriptParameterParser.lang();
if (script == null) {
throw new QueryParsingException(parseContext.index(), NAMES[0] + " requires 'script' field");
}

View File

@ -34,7 +34,8 @@ import org.elasticsearch.index.VersionType;
import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import java.util.Map;
@ -69,14 +70,16 @@ public class RestUpdateAction extends BaseRestHandler {
updateRequest.consistencyLevel(WriteConsistencyLevel.fromString(consistencyLevel));
}
updateRequest.docAsUpsert(request.paramAsBoolean("doc_as_upsert", updateRequest.docAsUpsert()));
if( request.hasParam("script") ) {
updateRequest.script(request.param("script"), ScriptService.ScriptType.INLINE);
} else if( request.hasParam("script_id") ) {
updateRequest.script(request.param("script_id"), ScriptService.ScriptType.INDEXED);
} else if( request.hasParam("script_file") ) {
updateRequest.script(request.param("script_file"), ScriptService.ScriptType.FILE);
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
scriptParameterParser.parseParams(request);
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
if (scriptValue != null) {
updateRequest.script(scriptValue.script(), scriptValue.scriptType());
}
String scriptLang = scriptParameterParser.lang();
if (scriptLang != null) {
updateRequest.scriptLang(scriptLang);
}
updateRequest.scriptLang(request.param("lang"));
for (Map.Entry<String, String> entry : request.params().entrySet()) {
if (entry.getKey().startsWith("sp_")) {
updateRequest.addScriptParam(entry.getKey().substring(3), entry.getValue());

View File

@ -0,0 +1,236 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.script;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.ToXContent.Params;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ScriptService.ScriptType;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
public class ScriptParameterParser {
public static final String FILE_SUFFIX = "_file";
public static final String INDEXED_SUFFIX = "_id";
private Map<String, ScriptParameterValue> parameterValues = new HashMap<>();
private Set<ParseField> inlineParameters;
private Set<ParseField> fileParameters;
private Set<ParseField> indexedParameters;
private String lang = null;
public ScriptParameterParser() {
this(null);
}
public ScriptParameterParser(Set<String> parameterNames) {
if (parameterNames == null || parameterNames.isEmpty()) {
inlineParameters = Collections.singleton(ScriptService.SCRIPT_INLINE);
fileParameters = Collections.singleton(ScriptService.SCRIPT_FILE);
indexedParameters = Collections.singleton(ScriptService.SCRIPT_ID);
} else {
inlineParameters = new HashSet<>();
fileParameters = new HashSet<>();
indexedParameters = new HashSet<>();
for (String parameterName : parameterNames) {
if (ScriptService.SCRIPT_LANG.match(parameterName)) {
throw new IllegalArgumentException("lang is reserved and cannot be used as a parameter name");
}
inlineParameters.add(new ParseField(parameterName));
fileParameters.add(new ParseField(parameterName + FILE_SUFFIX));
indexedParameters.add(new ParseField(parameterName + INDEXED_SUFFIX));
}
}
}
public boolean token(String currentFieldName, XContentParser.Token token, XContentParser parser) throws IOException {
if (token == XContentParser.Token.VALUE_STRING) {
if (ScriptService.SCRIPT_LANG.match(currentFieldName)) {
lang = parser.text();
return true;
} else {
for (ParseField parameter : inlineParameters) {
if (parameter.match(currentFieldName)) {
String coreParameterName = parameter.getPreferredName();
putParameterValue(coreParameterName, parser.textOrNull(), ScriptType.INLINE);
return true;
}
}
for (ParseField parameter : fileParameters) {
if (parameter.match(currentFieldName)) {
String coreParameterName = parameter.getPreferredName().replace(FILE_SUFFIX, "");
putParameterValue(coreParameterName, parser.textOrNull(), ScriptType.FILE);
return true;
}
}
for (ParseField parameter : indexedParameters) {
if (parameter.match(currentFieldName)) {
String coreParameterName = parameter.getPreferredName().replace(INDEXED_SUFFIX, "");
putParameterValue(coreParameterName, parser.textOrNull(), ScriptType.INDEXED);
return true;
}
}
}
}
return false;
}
public void parseConfig(Map<String, Object> config, boolean removeMatchedEntries) {
for (Iterator<Entry<String, Object>> itr = config.entrySet().iterator(); itr.hasNext();) {
Entry<String, Object> entry = itr.next();
String parameterName = entry.getKey();
Object parameterValue = entry.getValue();
if (ScriptService.SCRIPT_LANG.match(parameterName)) {
if (parameterValue instanceof String) {
lang = (String) parameterValue;
if (removeMatchedEntries) {
itr.remove();
}
} else {
throw new ScriptParameterParseException("Value must be of type String: [" + parameterName + "]");
}
} else {
for (ParseField parameter : inlineParameters) {
if (parameter.match(parameterName)) {
String coreParameterName = parameter.getPreferredName();
String stringValue = null;
if (parameterValue instanceof String) {
stringValue = (String) parameterValue;
} else {
throw new ScriptParameterParseException("Value must be of type String: [" + parameterName + "]");
}
putParameterValue(coreParameterName, stringValue, ScriptType.INLINE);
if (removeMatchedEntries) {
itr.remove();
}
}
}
for (ParseField parameter : fileParameters) {
if (parameter.match(parameterName)) {
String coreParameterName = parameter.getPreferredName().replace(FILE_SUFFIX, "");;
String stringValue = null;
if (parameterValue instanceof String) {
stringValue = (String) parameterValue;
} else {
throw new ScriptParameterParseException("Value must be of type String: [" + parameterName + "]");
}
putParameterValue(coreParameterName, stringValue, ScriptType.FILE);
if (removeMatchedEntries) {
itr.remove();
}
}
}
for (ParseField parameter : indexedParameters) {
if (parameter.match(parameterName)) {
String coreParameterName = parameter.getPreferredName().replace(INDEXED_SUFFIX, "");
String stringValue = null;
if (parameterValue instanceof String) {
stringValue = (String) parameterValue;
} else {
throw new ScriptParameterParseException("Value must be of type String: [" + parameterName + "]");
}
putParameterValue(coreParameterName, stringValue, ScriptType.INDEXED);
if (removeMatchedEntries) {
itr.remove();
}
}
}
}
}
}
private void putParameterValue(String coreParameterName, String script, ScriptType scriptType) {
if (parameterValues.get(coreParameterName) == null) {
parameterValues.put(coreParameterName, new ScriptParameterValue(script, scriptType));
} else {
throw new ScriptParameterParseException("Only one of [" + coreParameterName + ", " + coreParameterName
+ FILE_SUFFIX + ", " + coreParameterName + INDEXED_SUFFIX + "] is allowed.");
}
}
public void parseParams(Params params) {
lang = params.param(ScriptService.SCRIPT_LANG.getPreferredName());
for (ParseField parameter : inlineParameters) {
String value = params.param(parameter.getPreferredName());
if (value != null) {
String coreParameterName = parameter.getPreferredName();
putParameterValue(coreParameterName, value, ScriptType.INLINE);
}
}
for (ParseField parameter : fileParameters) {
String value = params.param(parameter.getPreferredName());
if (value != null) {
String coreParameterName = parameter.getPreferredName().replace(FILE_SUFFIX, "");
putParameterValue(coreParameterName, value, ScriptType.FILE);
}
}
for (ParseField parameter : indexedParameters) {
String value = params.param(parameter.getPreferredName());
if (value != null) {
String coreParameterName = parameter.getPreferredName().replace(INDEXED_SUFFIX, "");
putParameterValue(coreParameterName, value, ScriptType.INDEXED);
}
}
}
public ScriptParameterValue getDefaultScriptParameterValue() {
return getScriptParameterValue(ScriptService.SCRIPT_INLINE.getPreferredName());
}
public ScriptParameterValue getScriptParameterValue(String parameterName) {
return parameterValues.get(parameterName);
}
public String lang() {
return lang;
}
public static class ScriptParameterValue {
private String script;
private ScriptType scriptType;
public ScriptParameterValue(String script, ScriptType scriptType) {
this.script = script;
this.scriptType = scriptType;
}
public String script() {
return script;
}
public ScriptType scriptType() {
return scriptType;
}
}
public static class ScriptParameterParseException extends ElasticsearchException {
public ScriptParameterParseException(String msg) {
super(msg);
}
}
}

View File

@ -20,6 +20,7 @@
package org.elasticsearch.search.aggregations.metrics.scripted;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.search.aggregations.metrics.MetricsAggregationBuilder;
import java.io.IOException;
@ -187,51 +188,51 @@ public class ScriptedMetricBuilder extends MetricsAggregationBuilder {
}
if (initScript != null) {
builder.field(ScriptedMetricParser.INIT_SCRIPT_FIELD.getPreferredName(), initScript);
builder.field(ScriptedMetricParser.INIT_SCRIPT, initScript);
}
if (mapScript != null) {
builder.field(ScriptedMetricParser.MAP_SCRIPT_FIELD.getPreferredName(), mapScript);
builder.field(ScriptedMetricParser.MAP_SCRIPT, mapScript);
}
if (combineScript != null) {
builder.field(ScriptedMetricParser.COMBINE_SCRIPT_FIELD.getPreferredName(), combineScript);
builder.field(ScriptedMetricParser.COMBINE_SCRIPT, combineScript);
}
if (reduceScript != null) {
builder.field(ScriptedMetricParser.REDUCE_SCRIPT_FIELD.getPreferredName(), reduceScript);
builder.field(ScriptedMetricParser.REDUCE_SCRIPT, reduceScript);
}
if (initScriptFile != null) {
builder.field(ScriptedMetricParser.INIT_SCRIPT_FILE_FIELD.getPreferredName(), initScriptFile);
builder.field(ScriptedMetricParser.INIT_SCRIPT + ScriptParameterParser.FILE_SUFFIX, initScriptFile);
}
if (mapScriptFile != null) {
builder.field(ScriptedMetricParser.MAP_SCRIPT_FILE_FIELD.getPreferredName(), mapScriptFile);
builder.field(ScriptedMetricParser.MAP_SCRIPT + ScriptParameterParser.FILE_SUFFIX, mapScriptFile);
}
if (combineScriptFile != null) {
builder.field(ScriptedMetricParser.COMBINE_SCRIPT_FILE_FIELD.getPreferredName(), combineScriptFile);
builder.field(ScriptedMetricParser.COMBINE_SCRIPT + ScriptParameterParser.FILE_SUFFIX, combineScriptFile);
}
if (reduceScriptFile != null) {
builder.field(ScriptedMetricParser.REDUCE_SCRIPT_FILE_FIELD.getPreferredName(), reduceScriptFile);
builder.field(ScriptedMetricParser.REDUCE_SCRIPT + ScriptParameterParser.FILE_SUFFIX, reduceScriptFile);
}
if (initScriptId != null) {
builder.field(ScriptedMetricParser.INIT_SCRIPT_ID_FIELD.getPreferredName(), initScriptId);
builder.field(ScriptedMetricParser.INIT_SCRIPT + ScriptParameterParser.INDEXED_SUFFIX, initScriptId);
}
if (mapScriptId != null) {
builder.field(ScriptedMetricParser.MAP_SCRIPT_ID_FIELD.getPreferredName(), mapScriptId);
builder.field(ScriptedMetricParser.MAP_SCRIPT + ScriptParameterParser.INDEXED_SUFFIX, mapScriptId);
}
if (combineScriptId != null) {
builder.field(ScriptedMetricParser.COMBINE_SCRIPT_ID_FIELD.getPreferredName(), combineScriptId);
builder.field(ScriptedMetricParser.COMBINE_SCRIPT + ScriptParameterParser.INDEXED_SUFFIX, combineScriptId);
}
if (reduceScriptId != null) {
builder.field(ScriptedMetricParser.REDUCE_SCRIPT_ID_FIELD.getPreferredName(), reduceScriptId);
builder.field(ScriptedMetricParser.REDUCE_SCRIPT + ScriptParameterParser.INDEXED_SUFFIX, reduceScriptId);
}
if (lang != null) {

View File

@ -21,6 +21,8 @@ package org.elasticsearch.search.aggregations.metrics.scripted;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.search.SearchParseException;
import org.elasticsearch.search.aggregations.Aggregator;
@ -28,24 +30,18 @@ import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ScriptedMetricParser implements Aggregator.Parser {
public static final String INIT_SCRIPT = "init_script";
public static final String MAP_SCRIPT = "map_script";
public static final String COMBINE_SCRIPT = "combine_script";
public static final String REDUCE_SCRIPT = "reduce_script";
public static final ParseField PARAMS_FIELD = new ParseField("params");
public static final ParseField REDUCE_PARAMS_FIELD = new ParseField("reduce_params");
public static final ParseField INIT_SCRIPT_FIELD = new ParseField("init_script");
public static final ParseField MAP_SCRIPT_FIELD = new ParseField("map_script");
public static final ParseField COMBINE_SCRIPT_FIELD = new ParseField("combine_script");
public static final ParseField REDUCE_SCRIPT_FIELD = new ParseField("reduce_script");
public static final ParseField INIT_SCRIPT_FILE_FIELD = new ParseField("init_script_file");
public static final ParseField MAP_SCRIPT_FILE_FIELD = new ParseField("map_script_file");
public static final ParseField COMBINE_SCRIPT_FILE_FIELD = new ParseField("combine_script_file");
public static final ParseField REDUCE_SCRIPT_FILE_FIELD = new ParseField("reduce_script_file");
public static final ParseField INIT_SCRIPT_ID_FIELD = new ParseField("init_script_id");
public static final ParseField MAP_SCRIPT_ID_FIELD = new ParseField("map_script_id");
public static final ParseField COMBINE_SCRIPT_ID_FIELD = new ParseField("combine_script_id");
public static final ParseField REDUCE_SCRIPT_ID_FIELD = new ParseField("reduce_script_id");
public static final ParseField LANG_FIELD = new ParseField("lang");
@Override
@ -55,19 +51,17 @@ public class ScriptedMetricParser implements Aggregator.Parser {
@Override
public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException {
String initScript = null;
String mapScript = null;
String combineScript = null;
String reduceScript = null;
String scriptLang = null;
ScriptType initScriptType = ScriptType.INLINE;
ScriptType mapScriptType = ScriptType.INLINE;
ScriptType combineScriptType = ScriptType.INLINE;
ScriptType reduceScriptType = ScriptType.INLINE;
Map<String, Object> params = null;
Map<String, Object> reduceParams = null;
XContentParser.Token token;
String currentFieldName = null;
Set<String> scriptParameters = new HashSet<>();
scriptParameters.add(INIT_SCRIPT);
scriptParameters.add(MAP_SCRIPT);
scriptParameters.add(COMBINE_SCRIPT);
scriptParameters.add(REDUCE_SCRIPT);
ScriptParameterParser scriptParameterParser = new ScriptParameterParser(scriptParameters);
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
@ -81,87 +75,44 @@ public class ScriptedMetricParser implements Aggregator.Parser {
throw new SearchParseException(context, "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "].");
}
} else if (token.isValue()) {
if (INIT_SCRIPT_FIELD.match(currentFieldName)) {
if (initScript != null) {
throw new SearchParseException(context, "Only one of [init_script, init_script_file, init_script_id] is allowed in [" + aggregationName + "].");
}
initScript = parser.text();
initScriptType = ScriptType.INLINE;
} else if (MAP_SCRIPT_FIELD.match(currentFieldName)) {
if (mapScript != null) {
throw new SearchParseException(context, "Only one of [map_script, map_script_file, map_script_id] is allowed in [" + aggregationName + "].");
}
mapScript = parser.text();
mapScriptType = ScriptType.INLINE;
} else if (COMBINE_SCRIPT_FIELD.match(currentFieldName)) {
if (combineScript != null) {
throw new SearchParseException(context, "Only one of [combine_script, combine_script_file, combine_script_id] is allowed in [" + aggregationName + "].");
}
combineScript = parser.text();
combineScriptType = ScriptType.INLINE;
} else if (REDUCE_SCRIPT_FIELD.match(currentFieldName)) {
if (reduceScript != null) {
throw new SearchParseException(context, "Only one of [reduce_script, reduce_script_file, reduce_script_id] is allowed in [" + aggregationName + "].");
}
reduceScript = parser.text();
reduceScriptType = ScriptType.INLINE;
} else if (INIT_SCRIPT_FILE_FIELD.match(currentFieldName)) {
if (initScript != null) {
throw new SearchParseException(context, "Only one of [init_script, init_script_file, init_script_id] is allowed in [" + aggregationName + "].");
}
initScript = parser.text();
initScriptType = ScriptType.FILE;
} else if (MAP_SCRIPT_FILE_FIELD.match(currentFieldName)) {
if (mapScript != null) {
throw new SearchParseException(context, "Only one of [map_script, map_script_file, map_script_id] is allowed in [" + aggregationName + "].");
}
mapScript = parser.text();
mapScriptType = ScriptType.FILE;
} else if (COMBINE_SCRIPT_FILE_FIELD.match(currentFieldName)) {
if (combineScript != null) {
throw new SearchParseException(context, "Only one of [combine_script, combine_script_file, combine_script_id] is allowed in [" + aggregationName + "].");
}
combineScript = parser.text();
combineScriptType = ScriptType.FILE;
} else if (REDUCE_SCRIPT_FILE_FIELD.match(currentFieldName)) {
if (reduceScript != null) {
throw new SearchParseException(context, "Only one of [reduce_script, reduce_script_file, reduce_script_id] is allowed in [" + aggregationName + "].");
}
reduceScript = parser.text();
reduceScriptType = ScriptType.FILE;
} else if (INIT_SCRIPT_ID_FIELD.match(currentFieldName)) {
if (initScript != null) {
throw new SearchParseException(context, "Only one of [init_script, init_script_file, init_script_id] is allowed in [" + aggregationName + "].");
}
initScript = parser.text();
initScriptType = ScriptType.INDEXED;
} else if (MAP_SCRIPT_ID_FIELD.match(currentFieldName)) {
if (mapScript != null) {
throw new SearchParseException(context, "Only one of [map_script, map_script_file, map_script_id] is allowed in [" + aggregationName + "].");
}
mapScript = parser.text();
mapScriptType = ScriptType.INDEXED;
} else if (COMBINE_SCRIPT_ID_FIELD.match(currentFieldName)) {
if (combineScript != null) {
throw new SearchParseException(context, "Only one of [combine_script, combine_script_file, combine_script_id] is allowed in [" + aggregationName + "].");
}
combineScript = parser.text();
combineScriptType = ScriptType.INDEXED;
} else if (REDUCE_SCRIPT_ID_FIELD.match(currentFieldName)) {
if (reduceScript != null) {
throw new SearchParseException(context, "Only one of [reduce_script, reduce_script_file, reduce_script_id] is allowed in [" + aggregationName + "].");
}
reduceScript = parser.text();
reduceScriptType = ScriptType.INDEXED;
} else if (LANG_FIELD.match(currentFieldName)) {
scriptLang = parser.text();
} else {
if (!scriptParameterParser.token(currentFieldName, token, parser)) {
throw new SearchParseException(context, "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "].");
}
} else {
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].");
}
}
ScriptParameterValue initScriptValue = scriptParameterParser.getScriptParameterValue(INIT_SCRIPT);
String initScript = null;
ScriptType initScriptType = null;
if (initScriptValue != null) {
initScript = initScriptValue.script();
initScriptType = initScriptValue.scriptType();
}
ScriptParameterValue mapScriptValue = scriptParameterParser.getScriptParameterValue(MAP_SCRIPT);
String mapScript = null;
ScriptType mapScriptType = null;
if (mapScriptValue != null) {
mapScript = mapScriptValue.script();
mapScriptType = mapScriptValue.scriptType();
}
ScriptParameterValue combineScriptValue = scriptParameterParser.getScriptParameterValue(COMBINE_SCRIPT);
String combineScript = null;
ScriptType combineScriptType = null;
if (combineScriptValue != null) {
combineScript = combineScriptValue.script();
combineScriptType = combineScriptValue.scriptType();
}
ScriptParameterValue reduceScriptValue = scriptParameterParser.getScriptParameterValue(REDUCE_SCRIPT);
String reduceScript = null;
ScriptType reduceScriptType = null;
if (reduceScriptValue != null) {
reduceScript = reduceScriptValue.script();
reduceScriptType = reduceScriptValue.scriptType();
}
scriptLang = scriptParameterParser.lang();
if (mapScript == null) {
throw new SearchParseException(context, "map_script field is required in [" + aggregationName + "].");
}

View File

@ -28,6 +28,8 @@ import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
import org.elasticsearch.index.mapper.ip.IpFieldMapper;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.SearchParseException;
@ -79,6 +81,7 @@ public class ValuesSourceParser<VS extends ValuesSource> {
private ValueType targetValueType = null;
private boolean requiresSortedValues = false;
private boolean requiresUniqueValues = false;
private ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
private Input input = new Input();
@ -96,25 +99,14 @@ public class ValuesSourceParser<VS extends ValuesSource> {
} else if (formattable && "format".equals(currentFieldName)) {
input.format = parser.text();
} else if (scriptable) {
if ("script".equals(currentFieldName)) {
input.script = parser.text();
input.scriptType = ScriptService.ScriptType.INLINE;
} else if ("script_id".equals(currentFieldName)) {
input.script = parser.text();
input.scriptType = ScriptService.ScriptType.INDEXED;
} else if ("script_file".equals(currentFieldName)) {
input.script = parser.text();
input.scriptType = ScriptService.ScriptType.FILE;
} else if ("lang".equals(currentFieldName)) {
input.lang = parser.text();
} else if ("value_type".equals(currentFieldName) || "valueType".equals(currentFieldName)) {
if ("value_type".equals(currentFieldName) || "valueType".equals(currentFieldName)) {
input.valueType = ValueType.resolveForScript(parser.text());
if (targetValueType != null && input.valueType.isNotA(targetValueType)) {
throw new SearchParseException(context, aggType.name() + " aggregation [" + aggName +
"] was configured with an incompatible value type [" + input.valueType + "]. [" + aggType +
"] aggregation can only work on value of type [" + targetValueType + "]");
}
} else {
} else if (!scriptParameterParser.token(currentFieldName, token, parser)) {
return false;
}
return true;
@ -135,7 +127,14 @@ public class ValuesSourceParser<VS extends ValuesSource> {
}
public ValuesSourceConfig<VS> config() {
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
if (scriptValue != null) {
input.script = scriptValue.script();
input.scriptType = scriptValue.scriptType();
}
input.lang = scriptParameterParser.lang();
ValueType valueType = input.valueType != null ? input.valueType : targetValueType;
if (input.field == null) {

View File

@ -20,6 +20,8 @@
package org.elasticsearch.search.fetch.script;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ScriptParameterParser;
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.SearchParseElement;
@ -52,6 +54,7 @@ public class ScriptFieldsParseElement implements SearchParseElement {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
String fieldName = currentFieldName;
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
String script = null;
String scriptLang = null;
ScriptService.ScriptType scriptType = null;
@ -63,22 +66,21 @@ public class ScriptFieldsParseElement implements SearchParseElement {
} else if (token == XContentParser.Token.START_OBJECT) {
params = parser.map();
} else if (token.isValue()) {
if ("script".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.INLINE;
} else if ("script_id".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.INDEXED;
} else if ("file".equals(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.FILE;
} else if ("lang".equals(currentFieldName)) {
scriptLang = parser.text();
} else if ("ignore_failure".equals(currentFieldName)) {
if ("ignore_failure".equals(currentFieldName)) {
ignoreException = parser.booleanValue();
} else {
scriptParameterParser.token(currentFieldName, token, parser);
}
}
}
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
if (scriptValue != null) {
script = scriptValue.script();
scriptType = scriptValue.scriptType();
}
scriptLang = scriptParameterParser.lang();
SearchScript searchScript = context.scriptService().search(context.lookup(), scriptLang, script, scriptType, params);
context.scriptFields().add(new ScriptFieldsContext.ScriptField(fieldName, searchScript, ignoreException));
}

File diff suppressed because it is too large Load Diff