From 39edc3cfb9db926ae7ef1ba866516e5d3a8061ca Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Fri, 19 Jun 2020 00:28:21 +0200 Subject: [PATCH 1/4] WIP: runtime keyword field --- .../xpack/runtimefields/RuntimeFields.java | 30 +++- .../StringScriptFieldScript.java | 4 +- .../fielddata/ScriptBinaryDocValues.java | 41 +++++ .../fielddata/ScriptBinaryFieldData.java | 151 ++++++++++++++++++ .../mapper/RuntimeKeywordMappedFieldType.java | 73 +++++++++ .../mapper/ScriptFieldMapper.java | 135 ++++++++++++++++ 6 files changed, 432 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryDocValues.java create mode 100644 x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java create mode 100644 x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java create mode 100644 x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java index 6b97b0dcb795c..0303834293900 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java @@ -6,25 +6,53 @@ package org.elasticsearch.xpack.runtimefields; +import org.apache.lucene.util.SetOnce; +import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; +import org.elasticsearch.env.Environment; +import org.elasticsearch.env.NodeEnvironment; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.plugins.MapperPlugin; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ScriptPlugin; +import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.script.ScriptContext; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.watcher.ResourceWatcherService; +import org.elasticsearch.xpack.runtimefields.mapper.ScriptFieldMapper; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Supplier; public final class RuntimeFields extends Plugin implements MapperPlugin, ScriptPlugin { + private final SetOnce scriptService = new SetOnce<>(); + @Override public Map getMappers() { - return Collections.emptyMap(); + return Collections.singletonMap(ScriptFieldMapper.CONTENT_TYPE, new ScriptFieldMapper.TypeParser(scriptService.get())); } @Override public List> getContexts() { return List.of(DoubleScriptFieldScript.CONTEXT, LongScriptFieldScript.CONTEXT, StringScriptFieldScript.CONTEXT); } + + @Override + public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, ScriptService scriptService, + NamedXContentRegistry xContentRegistry, Environment environment, + NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier repositoriesServiceSupplier) { + this.scriptService.set(scriptService); + return Collections.emptyList(); + } } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java index 2556381981236..ea95a1ebd4b4e 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java @@ -20,7 +20,7 @@ import java.util.function.Consumer; public abstract class StringScriptFieldScript extends AbstractScriptFieldScript { - static final ScriptContext CONTEXT = new ScriptContext<>("string_script_field", Factory.class); + public static final ScriptContext CONTEXT = new ScriptContext<>("string_script_field", Factory.class); static List whitelist() { return List.of(WhitelistLoader.loadFromResourceFiles(RuntimeFieldsPainlessExtension.class, "string_whitelist.txt")); @@ -49,6 +49,8 @@ public StringScriptFieldScript( this.sync = sync; } + + public static class Value { private final StringScriptFieldScript script; diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryDocValues.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryDocValues.java new file mode 100644 index 0000000000000..ae0edeae46b4e --- /dev/null +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryDocValues.java @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.runtimefields.fielddata; + +import org.elasticsearch.index.fielddata.SortingBinaryDocValues; +import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; + +public final class ScriptBinaryDocValues extends SortingBinaryDocValues { + + private final StringScriptFieldScript script; + private final ScriptBinaryFieldData.ScriptBinaryResult scriptBinaryResult; + + ScriptBinaryDocValues(StringScriptFieldScript script, ScriptBinaryFieldData.ScriptBinaryResult scriptBinaryResult) { + this.script = script; + this.scriptBinaryResult = scriptBinaryResult; + } + + @Override + public boolean advanceExact(int doc) { + script.setDocument(doc); + script.execute(); + + count = scriptBinaryResult.getResult().size(); + if (count == 0) { + grow(); + return false; + } + + int i = 0; + for (String value : scriptBinaryResult.getResult()) { + grow(); + values[i++].copyChars(value); + } + sort(); + return true; + } +} diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java new file mode 100644 index 0000000000000..a58dabb0f397f --- /dev/null +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.runtimefields.fielddata; + +import org.apache.lucene.index.LeafReaderContext; +import org.apache.lucene.search.SortField; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.index.AbstractIndexComponent; +import org.elasticsearch.index.IndexSettings; +import org.elasticsearch.index.fielddata.IndexFieldData; +import org.elasticsearch.index.fielddata.IndexFieldDataCache; +import org.elasticsearch.index.fielddata.LeafFieldData; +import org.elasticsearch.index.fielddata.ScriptDocValues; +import org.elasticsearch.index.fielddata.SortedBinaryDocValues; +import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource; +import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.indices.breaker.CircuitBreakerService; +import org.elasticsearch.search.DocValueFormat; +import org.elasticsearch.search.MultiValueMode; +import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; +import org.elasticsearch.search.aggregations.support.ValuesSourceType; +import org.elasticsearch.search.sort.BucketedSort; +import org.elasticsearch.search.sort.SortOrder; +import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public final class ScriptBinaryFieldData extends AbstractIndexComponent + implements IndexFieldData { + + public static class Builder implements IndexFieldData.Builder { + private final StringScriptFieldScript.LeafFactory scriptFactory; + + public Builder(StringScriptFieldScript.LeafFactory scriptFactory) { + this.scriptFactory = scriptFactory; + } + + @Override + public IndexFieldData build(IndexSettings indexSettings, MappedFieldType fieldType, IndexFieldDataCache cache, + CircuitBreakerService breakerService, MapperService mapperService) { + return new ScriptBinaryFieldData(indexSettings, fieldType.name(), scriptFactory); + } + } + + private final String fieldName; + private final StringScriptFieldScript.LeafFactory scriptFactory; + + private ScriptBinaryFieldData(IndexSettings indexSettings, String fieldName, StringScriptFieldScript.LeafFactory scriptFactory) { + super(indexSettings); + this.fieldName = fieldName; + this.scriptFactory = scriptFactory; + } + + @Override + public String getFieldName() { + return fieldName; + } + + @Override + public ValuesSourceType getValuesSourceType() { + return CoreValuesSourceType.BYTES; + } + + @Override + public ScriptBinaryLeafFieldData load(LeafReaderContext context) { + try { + return loadDirect(context); + } catch (Exception e) { + if (e instanceof ElasticsearchException) { + throw (ElasticsearchException) e; + } else { + throw new ElasticsearchException(e); + } + } + } + + @Override + public ScriptBinaryLeafFieldData loadDirect(LeafReaderContext context) throws IOException { + + ScriptBinaryResult scriptBinaryResult = new ScriptBinaryResult(); + return new ScriptBinaryLeafFieldData( + new ScriptBinaryDocValues(scriptFactory.newInstance(context, scriptBinaryResult::accept), scriptBinaryResult)); + } + + @Override + public SortField sortField(Object missingValue, MultiValueMode sortMode, XFieldComparatorSource.Nested nested, boolean reverse) { + final XFieldComparatorSource source = new BytesRefFieldComparatorSource(this, missingValue, sortMode, nested); + return new SortField(getFieldName(), source, reverse); + + } + + @Override + public BucketedSort newBucketedSort(BigArrays bigArrays, Object missingValue, MultiValueMode sortMode, + XFieldComparatorSource.Nested nested, SortOrder sortOrder, DocValueFormat format, + int bucketSize, BucketedSort.ExtraData extra) { + throw new IllegalArgumentException("only supported on numeric fields"); + } + + @Override + public void clear() { + + } + + static class ScriptBinaryLeafFieldData implements LeafFieldData { + private final ScriptBinaryDocValues scriptBinaryDocValues; + + ScriptBinaryLeafFieldData(ScriptBinaryDocValues scriptBinaryDocValues) { + this.scriptBinaryDocValues = scriptBinaryDocValues; + } + + @Override + public ScriptDocValues getScriptValues() { + return new ScriptDocValues.Strings(getBytesValues()); + } + + @Override + public SortedBinaryDocValues getBytesValues() { + return scriptBinaryDocValues; + } + + @Override + public long ramBytesUsed() { + return 0; + } + + @Override + public void close() { + + } + } + + static class ScriptBinaryResult { + private final List result = new ArrayList<>(); + + void accept(String value) { + this.result.add(value); + } + + List getResult() { + return result; + } + } +} diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java new file mode 100644 index 0000000000000..73fe84f50dc73 --- /dev/null +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.runtimefields.mapper; + +import org.apache.lucene.search.Query; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.index.fielddata.IndexFieldData; +import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; +import org.elasticsearch.xpack.runtimefields.fielddata.ScriptBinaryFieldData; + +import java.util.Map; + +public final class RuntimeKeywordMappedFieldType extends MappedFieldType { + + private final StringScriptFieldScript.Factory scriptFactory; + + RuntimeKeywordMappedFieldType(String name, StringScriptFieldScript.Factory scriptFactory, Map meta) { + super(name, false, false, meta); + this.scriptFactory = scriptFactory; + } + + RuntimeKeywordMappedFieldType(RuntimeKeywordMappedFieldType ref) { + super(ref); + this.scriptFactory = ref.scriptFactory; + } + + @Override + public MappedFieldType clone() { + return new RuntimeKeywordMappedFieldType(this); + } + + @Override + public Object valueForDisplay(Object value) { + if (value == null) { + return null; + } + // keywords are internally stored as utf8 bytes + BytesRef binaryValue = (BytesRef) value; + return binaryValue.utf8ToString(); + } + + @Override + public String typeName() { + //TODO not sure what we should return here: the runtime type or the field type? + // why is the same string returned from three methods? + return ScriptFieldMapper.CONTENT_TYPE; + } + + @Override + public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { + //TODO need to find an ok way to get SourceLookup from the QueryShardContext, as well as the rest of the stuff + StringScriptFieldScript.LeafFactory leafFactory = scriptFactory.newFactory(null, null, null); + return new ScriptBinaryFieldData.Builder(leafFactory); + } + + @Override + public Query termQuery(Object value, QueryShardContext context) { + return null; + } + + @Override + public Query existsQuery(QueryShardContext context) { + return null; + } + + //TODO do we need to override equals/hashcode? +} diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java new file mode 100644 index 0000000000000..3d921a2d56966 --- /dev/null +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java @@ -0,0 +1,135 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.runtimefields.mapper; + +import org.apache.lucene.document.FieldType; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.support.XContentMapValues; +import org.elasticsearch.index.mapper.BooleanFieldMapper; +import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.Mapper; +import org.elasticsearch.index.mapper.MapperParsingException; +import org.elasticsearch.index.mapper.ParseContext; +import org.elasticsearch.script.Script; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public final class ScriptFieldMapper extends FieldMapper { + + public static final String CONTENT_TYPE = "script"; + + private static final FieldType FIELD_TYPE = new FieldType(); + + ScriptFieldMapper(String simpleName, MappedFieldType mappedFieldType, + Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { + super(simpleName, FIELD_TYPE, mappedFieldType, indexSettings, multiFields, copyTo); + } + + @Override + protected void parseCreateField(ParseContext context) { + //there is no field! + } + + @Override + protected void mergeOptions(FieldMapper other, List conflicts) { + //TODO implement this + } + + @Override + protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { + super.doXContentBody(builder, includeDefaults, params); + //TODO I think that this one needs to be overridden + } + + @Override + protected String contentType() { + return CONTENT_TYPE; + } + + public static class Builder extends FieldMapper.Builder { + + private final ScriptService scriptService; + + private String runtimeType; + private Script script; + + protected Builder(String name, ScriptService scriptService) { + super(name, FIELD_TYPE); + this.scriptService = scriptService; + } + + public void runtimeType(String runtimeType) { + this.runtimeType = runtimeType; + } + + public void script(Script script) { + this.script = script; + } + + @Override + public ScriptFieldMapper build(BuilderContext context) { + if (runtimeType == null) { + throw new IllegalArgumentException("runtime_type must be specified"); + } + if (script == null) { + throw new IllegalArgumentException("script must be specified"); + } + + MappedFieldType mappedFieldType; + if (runtimeType.equals("keyword")) { + StringScriptFieldScript.Factory factory = scriptService.compile(script, StringScriptFieldScript.CONTEXT); + mappedFieldType = new RuntimeKeywordMappedFieldType(buildFullName(context), factory, meta); + } else { + throw new IllegalArgumentException("runtime_type [" + runtimeType + "] not supported"); + } + //TODO copy to and multi_fields... look at what needs to be done. + return new ScriptFieldMapper(name, mappedFieldType, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); + } + } + + public static class TypeParser implements Mapper.TypeParser { + + private final ScriptService scriptService; + + public TypeParser(ScriptService scriptService) { + this.scriptService = scriptService; + } + + @Override + public ScriptFieldMapper.Builder parse(String name, Map node, ParserContext parserContext) + throws MapperParsingException { + Builder builder = new Builder(name, scriptService); + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); + String propName = entry.getKey(); + Object propNode = entry.getValue(); + if (propName.equals("runtime_type")) { + if (propNode == null) { + throw new MapperParsingException("Property [runtime_type] cannot be null."); + } + builder.runtimeType(XContentMapValues.nodeStringValue(propNode, name + ".runtime_type")); + iterator.remove(); + } else if (propName.equals("script")) { + if (propNode == null) { + throw new MapperParsingException("Property [script] cannot be null."); + } + //TODO this should become an object and support the usual script syntax + builder.script(new Script(XContentMapValues.nodeStringValue(propNode, name + ".script"))); + iterator.remove(); + } + } + return builder; + } + } +} From e7fbaab08b486d8aea22df0c8dab8e0df11211ae Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Sun, 28 Jun 2020 12:21:12 +0200 Subject: [PATCH 2/4] iter --- .../index/fielddata/SearchLookupAware.java | 28 +++++++++++++++++++ .../index/query/QueryShardContext.java | 9 +++++- .../AbstractScriptFieldScript.java | 22 +++++++-------- .../DoubleScriptFieldScript.java | 8 +++--- .../runtimefields/LongScriptFieldScript.java | 8 +++--- .../xpack/runtimefields/RuntimeFields.java | 7 +++-- .../StringScriptFieldScript.java | 10 +++---- .../fielddata/ScriptBinaryFieldData.java | 25 +++++++++++------ .../mapper/RuntimeKeywordMappedFieldType.java | 10 +++---- .../mapper/ScriptFieldMapper.java | 22 +++++++-------- .../xpack/runtimefields/double_whitelist.txt | 2 +- .../xpack/runtimefields/string_whitelist.txt | 2 +- .../DoubleScriptFieldScriptTests.java | 6 ++-- .../LongScriptFieldScriptTests.java | 6 ++-- .../ScriptFieldScriptTestCase.java | 12 ++++---- .../StringScriptFieldScriptTests.java | 6 ++-- 16 files changed, 112 insertions(+), 71 deletions(-) create mode 100644 server/src/main/java/org/elasticsearch/index/fielddata/SearchLookupAware.java diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/SearchLookupAware.java b/server/src/main/java/org/elasticsearch/index/fielddata/SearchLookupAware.java new file mode 100644 index 0000000000000..a7b33090ca6f9 --- /dev/null +++ b/server/src/main/java/org/elasticsearch/index/fielddata/SearchLookupAware.java @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.index.fielddata; + +import org.elasticsearch.search.lookup.SearchLookup; + +//TODO this is a temporary interface only to avoid changing signature of MappedFieldType#fielddataBuilder +public interface SearchLookupAware { + + void setSearchLookup(SearchLookup searchLookup); +} diff --git a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java index 0c85ebd1852b2..69334d88d9ce2 100644 --- a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java +++ b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java @@ -44,6 +44,7 @@ import org.elasticsearch.index.analysis.IndexAnalyzers; import org.elasticsearch.index.cache.bitset.BitsetFilterCache; import org.elasticsearch.index.fielddata.IndexFieldData; +import org.elasticsearch.index.fielddata.SearchLookupAware; import org.elasticsearch.index.mapper.ContentPath; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.Mapper; @@ -210,7 +211,13 @@ public boolean allowExpensiveQueries() { @SuppressWarnings("unchecked") public > IFD getForField(MappedFieldType fieldType) { - return (IFD) indexFieldDataService.apply(fieldType, fullyQualifiedIndex.getName()); + IFD indexFieldData = (IFD) indexFieldDataService.apply(fieldType, fullyQualifiedIndex.getName()); + //TODO this is a temporary hack to inject search lookup to the scripted fielddata + // implementations without changing MappedFieldType#fielddataBuilder signature + if (indexFieldData instanceof SearchLookupAware) { + ((SearchLookupAware) indexFieldData).setSearchLookup(lookup()); + } + return indexFieldData; } public void addNamedQuery(String name, Query query) { diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java index b9d605c796530..b6a9caff577e1 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java @@ -11,8 +11,11 @@ import org.elasticsearch.script.AggregationScript; import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.LeafDocLookup; +import org.elasticsearch.search.lookup.LeafSearchLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; +import java.util.HashMap; import java.util.Map; /** @@ -21,23 +24,19 @@ */ public abstract class AbstractScriptFieldScript { private final Map params; - private final LeafReaderContext ctx; - private final SourceLookup source; - private final LeafDocLookup fieldData; + private final LeafSearchLookup leafSearchLookup; - public AbstractScriptFieldScript(Map params, SourceLookup source, DocLookup fieldData, LeafReaderContext ctx) { + public AbstractScriptFieldScript(Map params, SearchLookup searchLookup, LeafReaderContext ctx) { + this.leafSearchLookup = searchLookup.getLeafSearchLookup(ctx); + //TODO how do other scripts get stored fields exposed? Through asMap? I don't see any getters for them. this.params = params; - this.source = source; - this.fieldData = fieldData.getLeafDocLookup(ctx); - this.ctx = ctx; } /** * Set the document to run the script against. */ public final void setDocument(int docId) { - source.setSegmentAndDocument(ctx, docId); - fieldData.setDocument(docId); + this.leafSearchLookup.setDocument(docId); } /** @@ -51,16 +50,15 @@ public final Map getParams() { * Expose the {@code _source} to the script. */ public final Map getSource() { - return source; + return leafSearchLookup.source(); } /** * Expose field data to the script as {@code doc}. */ public final Map> getDoc() { - return fieldData; + return leafSearchLookup.doc(); } public abstract void execute(); - } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java index e86bfb20f71b6..3086d250344f8 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java @@ -12,6 +12,7 @@ import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptFactory; import org.elasticsearch.search.lookup.DocLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; @@ -29,7 +30,7 @@ static List whitelist() { public static final String[] PARAMETERS = {}; public interface Factory extends ScriptFactory { - LeafFactory newFactory(Map params, SourceLookup source, DocLookup fieldData); + LeafFactory newFactory(Map params, SearchLookup searchLookup); } public interface LeafFactory { @@ -40,12 +41,11 @@ public interface LeafFactory { public DoubleScriptFieldScript( Map params, - SourceLookup source, - DocLookup fieldData, + SearchLookup searchLookup, LeafReaderContext ctx, DoubleConsumer sync ) { - super(params, source, fieldData, ctx); + super(params, searchLookup, ctx); this.sync = sync; } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java index e99fa4a944ba3..59d9a1c4f8317 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java @@ -12,6 +12,7 @@ import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptFactory; import org.elasticsearch.search.lookup.DocLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; @@ -29,7 +30,7 @@ static List whitelist() { public static final String[] PARAMETERS = {}; public interface Factory extends ScriptFactory { - LeafFactory newFactory(Map params, SourceLookup source, DocLookup fieldData); + LeafFactory newFactory(Map params, SearchLookup searchLookup); } public interface LeafFactory { @@ -40,12 +41,11 @@ public interface LeafFactory { public LongScriptFieldScript( Map params, - SourceLookup source, - DocLookup fieldData, + SearchLookup searchLookup, LeafReaderContext ctx, LongConsumer sync ) { - super(params, source, fieldData, ctx); + super(params, searchLookup, ctx); this.sync = sync; } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java index 0303834293900..0acbb041f1ded 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java @@ -33,11 +33,11 @@ public final class RuntimeFields extends Plugin implements MapperPlugin, ScriptPlugin { - private final SetOnce scriptService = new SetOnce<>(); + private final ScriptFieldMapper.TypeParser scriptTypeParser = new ScriptFieldMapper.TypeParser(); @Override public Map getMappers() { - return Collections.singletonMap(ScriptFieldMapper.CONTENT_TYPE, new ScriptFieldMapper.TypeParser(scriptService.get())); + return Collections.singletonMap(ScriptFieldMapper.CONTENT_TYPE, scriptTypeParser); } @Override @@ -52,7 +52,8 @@ public Collection createComponents(Client client, ClusterService cluster NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry, IndexNameExpressionResolver indexNameExpressionResolver, Supplier repositoriesServiceSupplier) { - this.scriptService.set(scriptService); + //looks like createComponents gets called after getMappers + this.scriptTypeParser.setScriptService(scriptService); return Collections.emptyList(); } } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java index ea95a1ebd4b4e..c17d37c07cbfa 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java @@ -12,6 +12,7 @@ import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptFactory; import org.elasticsearch.search.lookup.DocLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; @@ -29,7 +30,7 @@ static List whitelist() { public static final String[] PARAMETERS = {}; public interface Factory extends ScriptFactory { - LeafFactory newFactory(Map params, SourceLookup source, DocLookup fieldData); + LeafFactory newFactory(Map params, SearchLookup searchLookup); } public interface LeafFactory { @@ -40,17 +41,14 @@ public interface LeafFactory { public StringScriptFieldScript( Map params, - SourceLookup source, - DocLookup fieldData, + SearchLookup searchLookup, LeafReaderContext ctx, Consumer sync ) { - super(params, source, fieldData, ctx); + super(params, searchLookup, ctx); this.sync = sync; } - - public static class Value { private final StringScriptFieldScript script; diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java index a58dabb0f397f..7b0eac8edfb46 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java @@ -8,6 +8,7 @@ import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.SortField; +import org.apache.lucene.util.SetOnce; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.index.AbstractIndexComponent; @@ -16,6 +17,7 @@ import org.elasticsearch.index.fielddata.IndexFieldDataCache; import org.elasticsearch.index.fielddata.LeafFieldData; import org.elasticsearch.index.fielddata.ScriptDocValues; +import org.elasticsearch.index.fielddata.SearchLookupAware; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource; import org.elasticsearch.index.mapper.MappedFieldType; @@ -25,21 +27,24 @@ import org.elasticsearch.search.MultiValueMode; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceType; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.sort.BucketedSort; import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public final class ScriptBinaryFieldData extends AbstractIndexComponent - implements IndexFieldData { + implements IndexFieldData, SearchLookupAware { public static class Builder implements IndexFieldData.Builder { - private final StringScriptFieldScript.LeafFactory scriptFactory; - public Builder(StringScriptFieldScript.LeafFactory scriptFactory) { + private final StringScriptFieldScript.Factory scriptFactory; + + public Builder(StringScriptFieldScript.Factory scriptFactory) { this.scriptFactory = scriptFactory; } @@ -51,14 +56,20 @@ public IndexFieldData build(IndexSettings indexSettings, MappedFieldType fiel } private final String fieldName; - private final StringScriptFieldScript.LeafFactory scriptFactory; + private final StringScriptFieldScript.Factory scriptFactory; + private final SetOnce leafFactory = new SetOnce<>(); - private ScriptBinaryFieldData(IndexSettings indexSettings, String fieldName, StringScriptFieldScript.LeafFactory scriptFactory) { + private ScriptBinaryFieldData(IndexSettings indexSettings, String fieldName, StringScriptFieldScript.Factory scriptFactory) { super(indexSettings); this.fieldName = fieldName; this.scriptFactory = scriptFactory; } + public void setSearchLookup(SearchLookup searchLookup) { + //TODO wire the params from the mappings definition, we don't parse them yet + this.leafFactory.set(scriptFactory.newFactory(Collections.emptyMap(), searchLookup)); + } + @Override public String getFieldName() { return fieldName; @@ -84,17 +95,15 @@ public ScriptBinaryLeafFieldData load(LeafReaderContext context) { @Override public ScriptBinaryLeafFieldData loadDirect(LeafReaderContext context) throws IOException { - ScriptBinaryResult scriptBinaryResult = new ScriptBinaryResult(); return new ScriptBinaryLeafFieldData( - new ScriptBinaryDocValues(scriptFactory.newInstance(context, scriptBinaryResult::accept), scriptBinaryResult)); + new ScriptBinaryDocValues(leafFactory.get().newInstance(context, scriptBinaryResult::accept), scriptBinaryResult)); } @Override public SortField sortField(Object missingValue, MultiValueMode sortMode, XFieldComparatorSource.Nested nested, boolean reverse) { final XFieldComparatorSource source = new BytesRefFieldComparatorSource(this, missingValue, sortMode, nested); return new SortField(getFieldName(), source, reverse); - } @Override diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java index 73fe84f50dc73..c3e5c65edd30e 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java @@ -10,6 +10,7 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; import org.elasticsearch.xpack.runtimefields.fielddata.ScriptBinaryFieldData; @@ -21,7 +22,7 @@ public final class RuntimeKeywordMappedFieldType extends MappedFieldType { private final StringScriptFieldScript.Factory scriptFactory; RuntimeKeywordMappedFieldType(String name, StringScriptFieldScript.Factory scriptFactory, Map meta) { - super(name, false, false, meta); + super(name, false, false, TextSearchInfo.NONE, meta); this.scriptFactory = scriptFactory; } @@ -48,15 +49,14 @@ public Object valueForDisplay(Object value) { @Override public String typeName() { //TODO not sure what we should return here: the runtime type or the field type? - // why is the same string returned from three methods? + // why is the same string returned from three different methods? return ScriptFieldMapper.CONTENT_TYPE; } @Override public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { - //TODO need to find an ok way to get SourceLookup from the QueryShardContext, as well as the rest of the stuff - StringScriptFieldScript.LeafFactory leafFactory = scriptFactory.newFactory(null, null, null); - return new ScriptBinaryFieldData.Builder(leafFactory); + //TODO once we get SearchLookup as an argument here, we can already call scriptFactory.newFactory here and pass through the result + return new ScriptBinaryFieldData.Builder(scriptFactory); } @Override diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java index 3d921a2d56966..09162285f98b0 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.runtimefields.mapper; import org.apache.lucene.document.FieldType; +import org.apache.lucene.util.SetOnce; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.support.XContentMapValues; @@ -31,9 +32,8 @@ public final class ScriptFieldMapper extends FieldMapper { private static final FieldType FIELD_TYPE = new FieldType(); - ScriptFieldMapper(String simpleName, MappedFieldType mappedFieldType, - Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { - super(simpleName, FIELD_TYPE, mappedFieldType, indexSettings, multiFields, copyTo); + ScriptFieldMapper(String simpleName, MappedFieldType mappedFieldType, MultiFields multiFields, CopyTo copyTo) { + super(simpleName, FIELD_TYPE, mappedFieldType, multiFields, copyTo); } @Override @@ -49,7 +49,7 @@ protected void mergeOptions(FieldMapper other, List conflicts) { @Override protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { super.doXContentBody(builder, includeDefaults, params); - //TODO I think that this one needs to be overridden + //TODO overrice this } @Override @@ -93,23 +93,23 @@ public ScriptFieldMapper build(BuilderContext context) { } else { throw new IllegalArgumentException("runtime_type [" + runtimeType + "] not supported"); } - //TODO copy to and multi_fields... look at what needs to be done. - return new ScriptFieldMapper(name, mappedFieldType, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); + //TODO copy to and multi_fields... not sure what needs to be done. + return new ScriptFieldMapper(name, mappedFieldType, multiFieldsBuilder.build(this, context), copyTo); } } public static class TypeParser implements Mapper.TypeParser { - private final ScriptService scriptService; + private final SetOnce scriptService = new SetOnce<>(); - public TypeParser(ScriptService scriptService) { - this.scriptService = scriptService; + public void setScriptService(ScriptService scriptService) { + this.scriptService.set(scriptService); } @Override public ScriptFieldMapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { - Builder builder = new Builder(name, scriptService); + Builder builder = new Builder(name, scriptService.get()); for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { Map.Entry entry = iterator.next(); String propName = entry.getKey(); @@ -124,7 +124,7 @@ public ScriptFieldMapper.Builder parse(String name, Map node, Pa if (propNode == null) { throw new MapperParsingException("Property [script] cannot be null."); } - //TODO this should become an object and support the usual script syntax + //TODO this should become an object and support the usual script syntax, including lang and params builder.script(new Script(XContentMapValues.nodeStringValue(propNode, name + ".script"))); iterator.remove(); } diff --git a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt index 55a177f21579c..5d75876e45f08 100644 --- a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt +++ b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the Elastic License. # -# The whitelist for long-valued runtime fields +# The whitelist for double-valued runtime fields class org.elasticsearch.xpack.runtimefields.DoubleScriptFieldScript @no_import { } diff --git a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt index e0c4e367850f3..9fd1ffceb707d 100644 --- a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt +++ b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the Elastic License. # -# The whitelist for long-valued runtime fields +# The whitelist for string-valued runtime fields class org.elasticsearch.xpack.runtimefields.StringScriptFieldScript @no_import { } diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java index 37c6c5d35ce41..9196b92dc5324 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java @@ -17,6 +17,7 @@ import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.search.lookup.DocLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; @@ -107,10 +108,9 @@ protected ScriptContext scriptContext() { protected DoubleScriptFieldScript.LeafFactory newLeafFactory( DoubleScriptFieldScript.Factory factory, Map params, - SourceLookup source, - DocLookup fieldData + SearchLookup searchLookup ) { - return factory.newFactory(params, source, fieldData); + return factory.newFactory(params, searchLookup); } @Override diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java index 05d48808b5620..80d0d11fd8efd 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java @@ -16,6 +16,7 @@ import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.search.lookup.DocLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; @@ -93,10 +94,9 @@ protected ScriptContext scriptContext() { protected LongScriptFieldScript.LeafFactory newLeafFactory( LongScriptFieldScript.Factory factory, Map params, - SourceLookup source, - DocLookup fieldData + SearchLookup searchLookup ) { - return factory.newFactory(params, source, fieldData); + return factory.newFactory(params, searchLookup); } @Override diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java index a086953142662..6d1ce7468ff92 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java @@ -32,6 +32,7 @@ import org.elasticsearch.script.ScriptModule; import org.elasticsearch.script.ScriptService; import org.elasticsearch.search.lookup.DocLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; import org.elasticsearch.test.ESTestCase; @@ -50,7 +51,7 @@ public abstract class ScriptFieldScriptTestCase extends ESTestCase { protected abstract ScriptContext scriptContext(); - protected abstract LF newLeafFactory(F factory, Map params, SourceLookup source, DocLookup fieldData); + protected abstract LF newLeafFactory(F factory, Map params, SearchLookup searchLookup); protected abstract S newInstance(LF leafFactory, LeafReaderContext context, List results) throws IOException; @@ -67,14 +68,13 @@ public List loadExtensions(Class extensionPointType) { }); ScriptModule scriptModule = new ScriptModule(Settings.EMPTY, List.of(painlessPlugin, new RuntimeFields())); Map params = new HashMap<>(); - SourceLookup source = new SourceLookup(); MapperService mapperService = mock(MapperService.class); for (MappedFieldType type : types) { when(mapperService.fieldType(type.name())).thenReturn(type); } Function> fieldDataLookup = ft -> ft.fielddataBuilder("test") .build(indexSettings(), ft, null, new NoneCircuitBreakerService(), mapperService); - DocLookup fieldData = new DocLookup(mapperService, fieldDataLookup); + SearchLookup searchLookup = new SearchLookup(mapperService, fieldDataLookup); try (ScriptService scriptService = new ScriptService(Settings.EMPTY, scriptModule.engines, scriptModule.contexts)) { F factory = AccessController.doPrivileged( (PrivilegedAction) () -> scriptService.compile(new Script(script), scriptContext()) @@ -84,7 +84,7 @@ public List loadExtensions(Class extensionPointType) { indexBuilder.accept(indexWriter); try (DirectoryReader reader = indexWriter.getReader()) { IndexSearcher searcher = newSearcher(reader); - LF leafFactory = newLeafFactory(factory, params, source, fieldData); + LF leafFactory = newLeafFactory(factory, params, searchLookup); List result = new ArrayList<>(); searcher.search(new MatchAllDocsQuery(), new Collector() { @Override @@ -97,10 +97,10 @@ public LeafCollector getLeafCollector(LeafReaderContext context) throws IOExcept S compiled = newInstance(leafFactory, context, result); return new LeafCollector() { @Override - public void setScorer(Scorable scorer) throws IOException {} + public void setScorer(Scorable scorer) {} @Override - public void collect(int doc) throws IOException { + public void collect(int doc) { compiled.setDocument(doc); compiled.execute(); } diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java index 658001f743281..a6827a5f66656 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java @@ -15,6 +15,7 @@ import org.elasticsearch.index.mapper.KeywordFieldMapper.KeywordFieldType; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.search.lookup.DocLookup; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; @@ -99,10 +100,9 @@ protected ScriptContext scriptContext() { protected StringScriptFieldScript.LeafFactory newLeafFactory( StringScriptFieldScript.Factory factory, Map params, - SourceLookup source, - DocLookup fieldData + SearchLookup searchLookup ) { - return factory.newFactory(params, source, fieldData); + return factory.newFactory(params, searchLookup); } @Override From 6166bc16cf28aa04f23e31eb88f0219b2c6ae0d4 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Thu, 2 Jul 2020 18:11:24 +0200 Subject: [PATCH 3/4] make scripts work --- .../index/query/QueryShardContext.java | 2 +- .../mapper/RuntimeKeywordMappedFieldType.java | 16 ++++++++++++++-- .../runtimefields/mapper/ScriptFieldMapper.java | 9 ++++++--- .../xpack/runtimefields/double_whitelist.txt | 4 ++++ .../xpack/runtimefields/long_whitelist.txt | 4 ++++ .../xpack/runtimefields/string_whitelist.txt | 4 ++++ 6 files changed, 33 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java index a1fa3fde12ce8..b550c6b5552b2 100644 --- a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java +++ b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java @@ -211,7 +211,7 @@ public boolean allowExpensiveQueries() { public > IFD getForField(MappedFieldType fieldType) { IFD indexFieldData = (IFD) indexFieldDataService.apply(fieldType, fullyQualifiedIndex.getName()); //TODO this is a temporary hack to inject search lookup to the scripted fielddata - // implementations without changing MappedFieldType#fielddataBuilder signature + // implementations without changing MappedFieldType#fielddataBuilder signature, as that would cause daily merge conflicts if (indexFieldData instanceof SearchLookupAware) { ((SearchLookupAware) indexFieldData).setSearchLookup(lookup()); } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java index c3e5c65edd30e..e3a2553fef355 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java @@ -8,26 +8,33 @@ import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.script.Script; import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; import org.elasticsearch.xpack.runtimefields.fielddata.ScriptBinaryFieldData; +import java.io.IOException; import java.util.Map; public final class RuntimeKeywordMappedFieldType extends MappedFieldType { + private final Script script; private final StringScriptFieldScript.Factory scriptFactory; - RuntimeKeywordMappedFieldType(String name, StringScriptFieldScript.Factory scriptFactory, Map meta) { + RuntimeKeywordMappedFieldType(String name, Script script, StringScriptFieldScript.Factory scriptFactory, Map meta) { super(name, false, false, TextSearchInfo.NONE, meta); + this.script = script; this.scriptFactory = scriptFactory; } RuntimeKeywordMappedFieldType(RuntimeKeywordMappedFieldType ref) { super(ref); + this.script = ref.script; this.scriptFactory = ref.scriptFactory; } @@ -55,7 +62,7 @@ public String typeName() { @Override public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { - //TODO once we get SearchLookup as an argument here, we can already call scriptFactory.newFactory here and pass through the result + //TODO once we get SearchLookup as an argument, we can already call scriptFactory.newFactory here and pass through the result return new ScriptBinaryFieldData.Builder(scriptFactory); } @@ -69,5 +76,10 @@ public Query existsQuery(QueryShardContext context) { return null; } + void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { + builder.field("runtime_type", "keyword"); + builder.field("script", script.getIdOrCode()); //TODO For some reason this doesn't allow us to do the full xcontent of the script. + } + //TODO do we need to override equals/hashcode? } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java index 09162285f98b0..ef84f641eb875 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java @@ -8,7 +8,6 @@ import org.apache.lucene.document.FieldType; import org.apache.lucene.util.SetOnce; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.index.mapper.BooleanFieldMapper; @@ -49,7 +48,8 @@ protected void mergeOptions(FieldMapper other, List conflicts) { @Override protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { super.doXContentBody(builder, includeDefaults, params); - //TODO overrice this + RuntimeKeywordMappedFieldType fieldType = (RuntimeKeywordMappedFieldType) fieldType(); + fieldType.doXContentBody(builder, includeDefaults, params); } @Override @@ -89,7 +89,7 @@ public ScriptFieldMapper build(BuilderContext context) { MappedFieldType mappedFieldType; if (runtimeType.equals("keyword")) { StringScriptFieldScript.Factory factory = scriptService.compile(script, StringScriptFieldScript.CONTEXT); - mappedFieldType = new RuntimeKeywordMappedFieldType(buildFullName(context), factory, meta); + mappedFieldType = new RuntimeKeywordMappedFieldType(buildFullName(context), script, factory, meta); } else { throw new IllegalArgumentException("runtime_type [" + runtimeType + "] not supported"); } @@ -129,6 +129,9 @@ public ScriptFieldMapper.Builder parse(String name, Map node, Pa iterator.remove(); } } + // TODO these get passed in sometimes and we don't need them + node.remove("doc_values"); + node.remove("index"); return builder; } } diff --git a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt index 5d75876e45f08..ce8963b6f7cbf 100644 --- a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt +++ b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/double_whitelist.txt @@ -12,3 +12,7 @@ class org.elasticsearch.xpack.runtimefields.DoubleScriptFieldScript @no_import { static_import { void value(org.elasticsearch.xpack.runtimefields.DoubleScriptFieldScript, double) bound_to org.elasticsearch.xpack.runtimefields.DoubleScriptFieldScript$Value } + +# This import is required to make painless happy and it isn't 100% clear why +class org.elasticsearch.xpack.runtimefields.DoubleScriptFieldScript$Factory @no_import { +} diff --git a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/long_whitelist.txt b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/long_whitelist.txt index 630c679bc21cc..f5f3d0245f949 100644 --- a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/long_whitelist.txt +++ b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/long_whitelist.txt @@ -12,3 +12,7 @@ class org.elasticsearch.xpack.runtimefields.LongScriptFieldScript @no_import { static_import { void value(org.elasticsearch.xpack.runtimefields.LongScriptFieldScript, long) bound_to org.elasticsearch.xpack.runtimefields.LongScriptFieldScript$Value } + +# This import is required to make painless happy and it isn't 100% clear why +class org.elasticsearch.xpack.runtimefields.LongScriptFieldScript$Factory @no_import { +} diff --git a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt index 9fd1ffceb707d..5570891fb4b19 100644 --- a/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt +++ b/x-pack/plugin/runtime-fields/src/main/resources/org/elasticsearch/xpack/runtimefields/string_whitelist.txt @@ -12,3 +12,7 @@ class org.elasticsearch.xpack.runtimefields.StringScriptFieldScript @no_import { static_import { void value(org.elasticsearch.xpack.runtimefields.StringScriptFieldScript, String) bound_to org.elasticsearch.xpack.runtimefields.StringScriptFieldScript$Value } + +# This import is required to make painless happy and it isn't 100% clear why +class org.elasticsearch.xpack.runtimefields.StringScriptFieldScript$Factory @no_import { +} From 939e3f7fd7d9187ba0fc6c7f95b7209216f978ff Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Thu, 2 Jul 2020 18:51:58 +0200 Subject: [PATCH 4/4] spotless etc --- .../AbstractScriptFieldScript.java | 6 +--- .../DoubleScriptFieldScript.java | 9 +----- .../runtimefields/LongScriptFieldScript.java | 9 +----- .../xpack/runtimefields/RuntimeFields.java | 22 ++++++++----- .../StringScriptFieldScript.java | 9 +----- .../fielddata/ScriptBinaryFieldData.java | 31 ++++++++++++++----- .../mapper/RuntimeKeywordMappedFieldType.java | 8 ++--- .../mapper/ScriptFieldMapper.java | 8 ++--- .../DoubleScriptFieldScriptTests.java | 2 -- .../LongScriptFieldScriptTests.java | 2 -- .../ScriptFieldScriptTestCase.java | 2 -- .../StringScriptFieldScriptTests.java | 2 -- 12 files changed, 49 insertions(+), 61 deletions(-) diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java index b6a9caff577e1..ec49d38ef0a30 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/AbstractScriptFieldScript.java @@ -9,13 +9,9 @@ import org.apache.lucene.index.LeafReaderContext; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.script.AggregationScript; -import org.elasticsearch.search.lookup.DocLookup; -import org.elasticsearch.search.lookup.LeafDocLookup; import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; -import java.util.HashMap; import java.util.Map; /** @@ -28,7 +24,7 @@ public abstract class AbstractScriptFieldScript { public AbstractScriptFieldScript(Map params, SearchLookup searchLookup, LeafReaderContext ctx) { this.leafSearchLookup = searchLookup.getLeafSearchLookup(ctx); - //TODO how do other scripts get stored fields exposed? Through asMap? I don't see any getters for them. + // TODO how do other scripts get stored fields exposed? Through asMap? I don't see any getters for them. this.params = params; } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java index 3086d250344f8..8b66738b8bc74 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScript.java @@ -11,9 +11,7 @@ import org.elasticsearch.painless.spi.WhitelistLoader; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptFactory; -import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.util.List; @@ -39,12 +37,7 @@ public interface LeafFactory { private final DoubleConsumer sync; - public DoubleScriptFieldScript( - Map params, - SearchLookup searchLookup, - LeafReaderContext ctx, - DoubleConsumer sync - ) { + public DoubleScriptFieldScript(Map params, SearchLookup searchLookup, LeafReaderContext ctx, DoubleConsumer sync) { super(params, searchLookup, ctx); this.sync = sync; } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java index 59d9a1c4f8317..9850cab424642 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScript.java @@ -11,9 +11,7 @@ import org.elasticsearch.painless.spi.WhitelistLoader; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptFactory; -import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.util.List; @@ -39,12 +37,7 @@ public interface LeafFactory { private final LongConsumer sync; - public LongScriptFieldScript( - Map params, - SearchLookup searchLookup, - LeafReaderContext ctx, - LongConsumer sync - ) { + public LongScriptFieldScript(Map params, SearchLookup searchLookup, LeafReaderContext ctx, LongConsumer sync) { super(params, searchLookup, ctx); this.sync = sync; } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java index 0acbb041f1ded..f41c7efd44e69 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java @@ -6,7 +6,6 @@ package org.elasticsearch.xpack.runtimefields; -import org.apache.lucene.util.SetOnce; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.service.ClusterService; @@ -46,13 +45,20 @@ public List> getContexts() { } @Override - public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, - ResourceWatcherService resourceWatcherService, ScriptService scriptService, - NamedXContentRegistry xContentRegistry, Environment environment, - NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry, - IndexNameExpressionResolver indexNameExpressionResolver, - Supplier repositoriesServiceSupplier) { - //looks like createComponents gets called after getMappers + public Collection createComponents( + Client client, + ClusterService clusterService, + ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, + ScriptService scriptService, + NamedXContentRegistry xContentRegistry, + Environment environment, + NodeEnvironment nodeEnvironment, + NamedWriteableRegistry namedWriteableRegistry, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier repositoriesServiceSupplier + ) { + // looks like createComponents gets called after getMappers this.scriptTypeParser.setScriptService(scriptService); return Collections.emptyList(); } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java index c17d37c07cbfa..391be84b8d964 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScript.java @@ -11,9 +11,7 @@ import org.elasticsearch.painless.spi.WhitelistLoader; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptFactory; -import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.util.List; @@ -39,12 +37,7 @@ public interface LeafFactory { private final Consumer sync; - public StringScriptFieldScript( - Map params, - SearchLookup searchLookup, - LeafReaderContext ctx, - Consumer sync - ) { + public StringScriptFieldScript(Map params, SearchLookup searchLookup, LeafReaderContext ctx, Consumer sync) { super(params, searchLookup, ctx); this.sync = sync; } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java index 7b0eac8edfb46..42ca35731274b 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/fielddata/ScriptBinaryFieldData.java @@ -38,7 +38,9 @@ import java.util.List; public final class ScriptBinaryFieldData extends AbstractIndexComponent - implements IndexFieldData, SearchLookupAware { + implements + IndexFieldData, + SearchLookupAware { public static class Builder implements IndexFieldData.Builder { @@ -49,8 +51,13 @@ public Builder(StringScriptFieldScript.Factory scriptFactory) { } @Override - public IndexFieldData build(IndexSettings indexSettings, MappedFieldType fieldType, IndexFieldDataCache cache, - CircuitBreakerService breakerService, MapperService mapperService) { + public IndexFieldData build( + IndexSettings indexSettings, + MappedFieldType fieldType, + IndexFieldDataCache cache, + CircuitBreakerService breakerService, + MapperService mapperService + ) { return new ScriptBinaryFieldData(indexSettings, fieldType.name(), scriptFactory); } } @@ -66,7 +73,7 @@ private ScriptBinaryFieldData(IndexSettings indexSettings, String fieldName, Str } public void setSearchLookup(SearchLookup searchLookup) { - //TODO wire the params from the mappings definition, we don't parse them yet + // TODO wire the params from the mappings definition, we don't parse them yet this.leafFactory.set(scriptFactory.newFactory(Collections.emptyMap(), searchLookup)); } @@ -97,7 +104,8 @@ public ScriptBinaryLeafFieldData load(LeafReaderContext context) { public ScriptBinaryLeafFieldData loadDirect(LeafReaderContext context) throws IOException { ScriptBinaryResult scriptBinaryResult = new ScriptBinaryResult(); return new ScriptBinaryLeafFieldData( - new ScriptBinaryDocValues(leafFactory.get().newInstance(context, scriptBinaryResult::accept), scriptBinaryResult)); + new ScriptBinaryDocValues(leafFactory.get().newInstance(context, scriptBinaryResult::accept), scriptBinaryResult) + ); } @Override @@ -107,9 +115,16 @@ public SortField sortField(Object missingValue, MultiValueMode sortMode, XFieldC } @Override - public BucketedSort newBucketedSort(BigArrays bigArrays, Object missingValue, MultiValueMode sortMode, - XFieldComparatorSource.Nested nested, SortOrder sortOrder, DocValueFormat format, - int bucketSize, BucketedSort.ExtraData extra) { + public BucketedSort newBucketedSort( + BigArrays bigArrays, + Object missingValue, + MultiValueMode sortMode, + XFieldComparatorSource.Nested nested, + SortOrder sortOrder, + DocValueFormat format, + int bucketSize, + BucketedSort.ExtraData extra + ) { throw new IllegalArgumentException("only supported on numeric fields"); } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java index e3a2553fef355..5aef8e857408a 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/RuntimeKeywordMappedFieldType.java @@ -55,14 +55,14 @@ public Object valueForDisplay(Object value) { @Override public String typeName() { - //TODO not sure what we should return here: the runtime type or the field type? + // TODO not sure what we should return here: the runtime type or the field type? // why is the same string returned from three different methods? return ScriptFieldMapper.CONTENT_TYPE; } @Override public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { - //TODO once we get SearchLookup as an argument, we can already call scriptFactory.newFactory here and pass through the result + // TODO once we get SearchLookup as an argument, we can already call scriptFactory.newFactory here and pass through the result return new ScriptBinaryFieldData.Builder(scriptFactory); } @@ -78,8 +78,8 @@ public Query existsQuery(QueryShardContext context) { void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { builder.field("runtime_type", "keyword"); - builder.field("script", script.getIdOrCode()); //TODO For some reason this doesn't allow us to do the full xcontent of the script. + builder.field("script", script.getIdOrCode()); // TODO For some reason this doesn't allow us to do the full xcontent of the script. } - //TODO do we need to override equals/hashcode? + // TODO do we need to override equals/hashcode? } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java index ef84f641eb875..c6fcd43635865 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java @@ -37,12 +37,12 @@ public final class ScriptFieldMapper extends FieldMapper { @Override protected void parseCreateField(ParseContext context) { - //there is no field! + // there is no field! } @Override protected void mergeOptions(FieldMapper other, List conflicts) { - //TODO implement this + // TODO implement this } @Override @@ -93,7 +93,7 @@ public ScriptFieldMapper build(BuilderContext context) { } else { throw new IllegalArgumentException("runtime_type [" + runtimeType + "] not supported"); } - //TODO copy to and multi_fields... not sure what needs to be done. + // TODO copy to and multi_fields... not sure what needs to be done. return new ScriptFieldMapper(name, mappedFieldType, multiFieldsBuilder.build(this, context), copyTo); } } @@ -124,7 +124,7 @@ public ScriptFieldMapper.Builder parse(String name, Map node, Pa if (propNode == null) { throw new MapperParsingException("Property [script] cannot be null."); } - //TODO this should become an object and support the usual script syntax, including lang and params + // TODO this should become an object and support the usual script syntax, including lang and params builder.script(new Script(XContentMapValues.nodeStringValue(propNode, name + ".script"))); iterator.remove(); } diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java index 9196b92dc5324..23081d1ff3427 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/DoubleScriptFieldScriptTests.java @@ -16,9 +16,7 @@ import org.elasticsearch.index.mapper.NumberFieldMapper.NumberFieldType; import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType; import org.elasticsearch.script.ScriptContext; -import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.util.List; diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java index 80d0d11fd8efd..ef0c5cd304d0e 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/LongScriptFieldScriptTests.java @@ -15,9 +15,7 @@ import org.elasticsearch.index.mapper.NumberFieldMapper.NumberFieldType; import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType; import org.elasticsearch.script.ScriptContext; -import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.util.List; diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java index 6d1ce7468ff92..3b7a819d04b40 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/ScriptFieldScriptTestCase.java @@ -31,9 +31,7 @@ import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptModule; import org.elasticsearch.script.ScriptService; -import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; import org.elasticsearch.test.ESTestCase; import java.io.IOException; diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java index a6827a5f66656..5ecedd1762647 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/StringScriptFieldScriptTests.java @@ -14,9 +14,7 @@ import org.elasticsearch.common.CheckedConsumer; import org.elasticsearch.index.mapper.KeywordFieldMapper.KeywordFieldType; import org.elasticsearch.script.ScriptContext; -import org.elasticsearch.search.lookup.DocLookup; import org.elasticsearch.search.lookup.SearchLookup; -import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.util.List;