From 69340e758e59a6c0994e4175eee1dc8d8d1f77fe Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Wed, 15 Jul 2020 23:06:16 +0200 Subject: [PATCH 1/3] Scripted keyword field type: update family type and test field caps output --- .../mapper/RuntimeKeywordMappedFieldType.java | 19 ++++++- .../mapper/ScriptFieldMapperTests.java | 49 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) 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 18d36697c29a0..658352cd9a8f1 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 @@ -15,6 +15,7 @@ import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; @@ -62,13 +63,27 @@ 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 different methods? return ScriptFieldMapper.CONTENT_TYPE; } + @Override + public String familyTypeName() { + return KeywordFieldMapper.CONTENT_TYPE; + } + + @Override + public boolean isSearchable() { + return true; + } + + @Override + public boolean isAggregatable() { + return true; + } + @Override public ScriptBinaryFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { + assert fullyQualifiedIndexName.length() > 0 : "index name must not be empty"; // 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); } diff --git a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapperTests.java b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapperTests.java index 9e25a537787c6..3962e7d31c0f9 100644 --- a/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapperTests.java +++ b/x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapperTests.java @@ -6,11 +6,14 @@ package org.elasticsearch.xpack.runtimefields.mapper; +import org.elasticsearch.action.fieldcaps.FieldCapabilities; +import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.plugins.Plugin; @@ -26,6 +29,7 @@ import java.util.Map; import java.util.Set; +import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.hamcrest.Matchers.instanceOf; public class ScriptFieldMapperTests extends ESSingleNodeTestCase { @@ -93,6 +97,51 @@ public void testStoredScriptsAreNotSupported() throws Exception { ); } + public void testFieldCaps() throws Exception { + { + XContentBuilder mapping = XContentFactory.jsonBuilder() + .startObject() + .startObject("_doc") + .startObject("properties") + .startObject("field") + .field("type", "script") + .field("runtime_type", randomFrom(SUPPORTED_RUNTIME_TYPES)) + .startObject("script") + .field("source", "value('test')") + .field("lang", "test") + .endObject() + .endObject() + .endObject() + .endObject() + .endObject(); + createIndex("test_script", Settings.EMPTY, mapping); + } + { + XContentBuilder mapping = XContentFactory.jsonBuilder() + .startObject() + .startObject("_doc") + .startObject("properties") + .startObject("field") + .field("type", "keyword") + .endObject() + .endObject() + .endObject() + .endObject(); + createIndex("test_concrete", Settings.EMPTY, mapping); + } + FieldCapabilitiesResponse response = client().prepareFieldCaps("test_*").setFields("field").get(); + assertThat(response.getIndices(), arrayContainingInAnyOrder("test_script", "test_concrete")); + Map field = response.getField("field"); + assertEquals(1, field.size()); + FieldCapabilities fieldCapabilities = field.get(KeywordFieldMapper.CONTENT_TYPE); + assertTrue(fieldCapabilities.isSearchable()); + assertTrue(fieldCapabilities.isAggregatable()); + assertEquals(KeywordFieldMapper.CONTENT_TYPE, fieldCapabilities.getType()); + assertNull(fieldCapabilities.nonAggregatableIndices()); + assertNull(fieldCapabilities.nonSearchableIndices()); + assertEquals("field", fieldCapabilities.getName()); + } + public void testDefaultMapping() throws Exception { XContentBuilder mapping = XContentFactory.jsonBuilder() .startObject() From aa771b2a47920194bff6a3b5c42a0692a62c091b Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Fri, 17 Jul 2020 10:32:36 +0200 Subject: [PATCH 2/3] remove assertion --- .../runtimefields/mapper/RuntimeKeywordMappedFieldType.java | 1 - 1 file changed, 1 deletion(-) 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 7fa2f208042e4..a51e1a319a84f 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 @@ -85,7 +85,6 @@ public boolean isAggregatable() { @Override public ScriptBinaryFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { - assert fullyQualifiedIndexName.length() > 0 : "index name must not be empty"; // 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); } From 06875dc0eea5079a3b0ae1683710cfa7be98e037 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Fri, 17 Jul 2020 13:02:21 +0200 Subject: [PATCH 3/3] spotless --- .../runtimefields/mapper/ScriptFieldMapper.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) 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 340b1ef12ab85..3746c4cb8b6ea 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 @@ -72,11 +72,18 @@ protected String contentType() { public static class Builder extends ParametrizedFieldMapper.Builder { static final Map> FIELD_TYPE_RESOLVER = Map.of( - KeywordFieldMapper.CONTENT_TYPE, (builder, context) -> { + KeywordFieldMapper.CONTENT_TYPE, + (builder, context) -> { StringScriptFieldScript.Factory factory = builder.scriptCompiler.compile( - builder.script.getValue(), StringScriptFieldScript.CONTEXT); + builder.script.getValue(), + StringScriptFieldScript.CONTEXT + ); return new RuntimeKeywordMappedFieldType( - builder.buildFullName(context), builder.script.getValue(), factory, builder.meta.getValue()); + builder.buildFullName(context), + builder.script.getValue(), + factory, + builder.meta.getValue() + ); } ); @@ -123,7 +130,9 @@ protected List> getParameters() { @Override public ScriptFieldMapper build(BuilderContext context) { - BiFunction fieldTypeResolver = Builder.FIELD_TYPE_RESOLVER.get(runtimeType.getValue()); + BiFunction fieldTypeResolver = Builder.FIELD_TYPE_RESOLVER.get( + runtimeType.getValue() + ); if (fieldTypeResolver == null) { throw new IllegalArgumentException("runtime_type [" + runtimeType.getValue() + "] not supported"); }