diff --git a/x-pack/plugin/runtime-fields/qa/rest/build.gradle b/x-pack/plugin/runtime-fields/qa/rest/build.gradle index ac01bc3b2292c..9ca0108efb1d0 100644 --- a/x-pack/plugin/runtime-fields/qa/rest/build.gradle +++ b/x-pack/plugin/runtime-fields/qa/rest/build.gradle @@ -37,8 +37,6 @@ yamlRestTest { 'search/115_multiple_field_collapsing/two levels fields collapsing', // Broken. Gotta fix. 'field_caps/30_filter/Field caps with index filter', // We don't support filtering field caps on runtime fields. What should we do? 'search.aggregation/10_histogram/*', // runtime_script doesn't support sub-fields. Maybe it should? - 'search.aggregation/200_top_hits_metric/top_hits aggregation with sequence numbers', - 'search.aggregation/200_top_hits_metric/top_hits aggregation with nested documents', 'search/140_pre_filter_search_shards/pre_filter_shard_size with shards that have no hit', /////// TO FIX /////// diff --git a/x-pack/plugin/runtime-fields/qa/rest/src/yamlRestTest/java/org/elasticsearch/xpack/runtimefields/rest/CoreTestsWithRuntimeFieldsIT.java b/x-pack/plugin/runtime-fields/qa/rest/src/yamlRestTest/java/org/elasticsearch/xpack/runtimefields/rest/CoreTestsWithRuntimeFieldsIT.java index c8e1586fcb1fd..261c07cba6ac8 100644 --- a/x-pack/plugin/runtime-fields/qa/rest/src/yamlRestTest/java/org/elasticsearch/xpack/runtimefields/rest/CoreTestsWithRuntimeFieldsIT.java +++ b/x-pack/plugin/runtime-fields/qa/rest/src/yamlRestTest/java/org/elasticsearch/xpack/runtimefields/rest/CoreTestsWithRuntimeFieldsIT.java @@ -54,7 +54,14 @@ public static Iterable parameters() throws Exception { assert orig.length == 1; ClientYamlTestCandidate candidate = (ClientYamlTestCandidate) orig[0]; ClientYamlTestSuite suite = suites.computeIfAbsent(candidate.getTestPath(), k -> modifiedSuite(candidate)); - modifySection(candidate.getTestPath(), candidate.getTestSection().getExecutableSections()); + if (suite == null) { + // The setup section contains an unsupported option + continue; + } + if (false == modifySection(candidate.getTestPath(), candidate.getTestSection().getExecutableSections())) { + // The test section contains an unsupported option + continue; + } ClientYamlTestSection modified = new ClientYamlTestSection( candidate.getTestSection().getLocation(), candidate.getTestSection().getName(), @@ -73,7 +80,9 @@ public static Iterable parameters() throws Exception { * with scripts that load from source. */ private static ClientYamlTestSuite modifiedSuite(ClientYamlTestCandidate candidate) { - modifySection(candidate.getSuitePath() + "/setup", candidate.getSetupSection().getExecutableSections()); + if (false == modifySection(candidate.getSuitePath() + "/setup", candidate.getSetupSection().getExecutableSections())) { + return null; + } List setup = new ArrayList<>(candidate.getSetupSection().getExecutableSections().size() + 1); setup.add(ADD_TEMPLATE); setup.addAll(candidate.getSetupSection().getExecutableSections()); @@ -90,7 +99,7 @@ private static ClientYamlTestSuite modifiedSuite(ClientYamlTestCandidate candida * Replace field configuration in {@code indices.create} with scripts * that load from the source. */ - private static void modifySection(String sectionName, List executables) { + private static boolean modifySection(String sectionName, List executables) { for (ExecutableSection section : executables) { if (false == (section instanceof DoSection)) { continue; @@ -125,6 +134,10 @@ private static void modifySection(String sectionName, List ex Map propertyMap = (Map) property.getValue(); String name = property.getKey().toString(); String type = Objects.toString(propertyMap.get("type")); + if ("nested".equals(type)) { + // Our loading scripts can't be made to manage nested fields so we have to skip those tests. + return false; + } if ("false".equals(Objects.toString(propertyMap.get("doc_values")))) { // If doc_values is false we can't emulate with scripts. `null` and `true` are fine. continue; @@ -158,6 +171,7 @@ private static void modifySection(String sectionName, List ex } } } + return true; } private static String painlessToLoadFromSource(String name, String type) { diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/10_keyword.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/10_keyword.yml index 6139b4f999416..42c0f9847b049 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/10_keyword.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/10_keyword.yml @@ -181,3 +181,97 @@ setup: animal: cow - match: {hits.total.value: 1} - match: {hits.hits.0._source.animal: cow} + +--- +"nested": + - do: + indices.create: + index: test + body: + settings: + number_of_shards: 1 + number_of_replicas: 0 + mappings: + properties: + users: + type: nested + properties: + first: + type: keyword + last: + type: keyword + first_script: + type: runtime_script + runtime_type: keyword + script: emitValue(doc['users.first'].value) + last_script: + type: runtime_script + runtime_type: keyword + script: emitValue(doc['users.last'].value) + - do: + bulk: + index: test + refresh: true + body: | + {"index":{"_id": 1}} + {"group" : "fans", "users" : [{"first" : "John", "last" : "Smith"}, {"first": "Alice", "last": "White"}]} + {"index":{"_id": 2}} + {"group" : "fans", "users" : [{"first" : "Mark", "last" : "Doe"}]} + + - do: + search: + index: test + body: + query: + nested: + path: users + query: + bool: + must: + - match: + users.first_script: John + - match: + users.last_script: Smith + - match: {hits.total.value: 1} + + - do: + search: + index: test + body: + query: + nested: + path: users + query: + bool: + must: + - match: + users.first_script: John + - match: + users.last_script: White + - match: {hits.total.value: 0} + + - do: + search: + body: + aggs: + to-users: + nested: + path: users + aggs: + users: + top_hits: + sort: users.last_script + - match: { hits.total.value: 2 } + - length: { aggregations.to-users.users.hits.hits: 3 } + - match: { aggregations.to-users.users.hits.hits.0._id: "2" } + - match: { aggregations.to-users.users.hits.hits.0._index: test } + - match: { aggregations.to-users.users.hits.hits.0._nested.field: users } + - match: { aggregations.to-users.users.hits.hits.0._nested.offset: 0 } + - match: { aggregations.to-users.users.hits.hits.1._id: "1" } + - match: { aggregations.to-users.users.hits.hits.1._index: test } + - match: { aggregations.to-users.users.hits.hits.1._nested.field: users } + - match: { aggregations.to-users.users.hits.hits.1._nested.offset: 0 } + - match: { aggregations.to-users.users.hits.hits.2._id: "1" } + - match: { aggregations.to-users.users.hits.hits.2._index: test } + - match: { aggregations.to-users.users.hits.hits.2._nested.field: users } + - match: { aggregations.to-users.users.hits.hits.2._nested.offset: 1 } diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/20_long.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/20_long.yml index 747ac39cd86b9..506be13a83ebd 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/20_long.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/20_long.yml @@ -129,3 +129,97 @@ setup: voltage_times_ten: 58 - match: {hits.total.value: 1} - match: {hits.hits.0._source.voltage: 5.8} + +--- +"nested": + - do: + indices.create: + index: test + body: + settings: + number_of_shards: 1 + number_of_replicas: 0 + mappings: + properties: + users: + type: nested + properties: + first: + type: keyword + last: + type: keyword + first_script: + type: runtime_script + runtime_type: long + script: emitValue(doc['users.first'].value.length()) + last_script: + type: runtime_script + runtime_type: long + script: emitValue(doc['users.last'].value.length()) + - do: + bulk: + index: test + refresh: true + body: | + {"index":{"_id": 1}} + {"group" : "fans", "users" : [{"first" : "John", "last" : "Smith"}, {"first": "Alice", "last": "Whighte"}]} + {"index":{"_id": 2}} + {"group" : "fans", "users" : [{"first" : "Mark", "last" : "Doe"}]} + + - do: + search: + index: test + body: + query: + nested: + path: users + query: + bool: + must: + - match: + users.first_script: 4 + - match: + users.last_script: 5 + - match: {hits.total.value: 1} + + - do: + search: + index: test + body: + query: + nested: + path: users + query: + bool: + must: + - match: + users.first_script: 4 + - match: + users.last_script: 7 + - match: {hits.total.value: 0} + + - do: + search: + body: + aggs: + to-users: + nested: + path: users + aggs: + users: + top_hits: + sort: users.last_script + - match: { hits.total.value: 2 } + - length: { aggregations.to-users.users.hits.hits: 3 } + - match: { aggregations.to-users.users.hits.hits.0._id: "2" } + - match: { aggregations.to-users.users.hits.hits.0._index: test } + - match: { aggregations.to-users.users.hits.hits.0._nested.field: users } + - match: { aggregations.to-users.users.hits.hits.0._nested.offset: 0 } + - match: { aggregations.to-users.users.hits.hits.1._id: "1" } + - match: { aggregations.to-users.users.hits.hits.1._index: test } + - match: { aggregations.to-users.users.hits.hits.1._nested.field: users } + - match: { aggregations.to-users.users.hits.hits.1._nested.offset: 0 } + - match: { aggregations.to-users.users.hits.hits.2._id: "1" } + - match: { aggregations.to-users.users.hits.hits.2._index: test } + - match: { aggregations.to-users.users.hits.hits.2._nested.field: users } + - match: { aggregations.to-users.users.hits.hits.2._nested.offset: 1 }