diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.aggregation/200_top_hits.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.aggregation/200_top_hits.yml
new file mode 100644
index 0000000000000..aae0408ff67e8
--- /dev/null
+++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.aggregation/200_top_hits.yml
@@ -0,0 +1,347 @@
+setup:
+ - do:
+ indices.create:
+ index: test
+ body:
+ settings:
+ number_of_shards: 1
+ mappings:
+ properties:
+ page:
+ type: integer
+ text:
+ type: text
+ store: true
+
+ - do:
+ bulk:
+ index: test
+ refresh: true
+ body:
+ - '{ "index": {} }'
+ - '{ "page": 1, "text": "the quick brown fox" }'
+ - '{ "index": {} }'
+ - '{ "page": 1, "text": "jumped over the lazy dog" }'
+ - '{ "index": {} }'
+ - '{ "page": 2, "text": "The vorpal blade went snicker-snack!" }'
+
+---
+highlight:
+ - do:
+ search:
+ index: test
+ body:
+ query:
+ match:
+ text: the
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ highlight:
+ fields:
+ text: {}
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0.highlight.text.0: "the quick brown fox" }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1.highlight.text.0: "jumped over the lazy dog" }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0.highlight.text.0: "The vorpal blade went snicker-snack!" }
+
+---
+highlight_query:
+ - do:
+ search:
+ index: test
+ body:
+ query:
+ match:
+ text: the
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ highlight:
+ fields:
+ text:
+ highlight_query:
+ match:
+ text: snack
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - is_false: aggregations.page.buckets.0.top_hits.hits.hits.0.highlight.text.0
+ - is_false: aggregations.page.buckets.0.top_hits.hits.hits.1.highlight.text.0
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0.highlight.text.0: "The vorpal blade went snicker-snack!" }
+
+---
+explain:
+ - skip:
+ features: close_to
+
+ - do:
+ search:
+ index: test
+ body:
+ query:
+ match:
+ text: the
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ explain: true
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - close_to: { aggregations.page.buckets.0.top_hits.hits.hits.0._explanation.value: { value: 0.14543022, error: 0.001 }}
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0._explanation.description: "weight(text:the in 0) [PerFieldSimilarity], result of:" }
+ - close_to: { aggregations.page.buckets.0.top_hits.hits.hits.1._explanation.value: { value: 0.13353139, error: 0.001 }}
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1._explanation.description: "weight(text:the in 1) [PerFieldSimilarity], result of:" }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - close_to: { aggregations.page.buckets.1.top_hits.hits.hits.0._explanation.value: { value: 0.12343238, error: 0.001 }}
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0._explanation.description: "weight(text:the in 2) [PerFieldSimilarity], result of:" }
+
+---
+from:
+ - do:
+ search:
+ index: test
+ body:
+ query:
+ match:
+ text: the
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ from: 1
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - length: { aggregations.page.buckets.0.top_hits.hits.hits: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0._source.text: "jumped over the lazy dog" }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - length: { aggregations.page.buckets.1.top_hits.hits.hits: 0 }
+
+---
+size:
+ - do:
+ search:
+ index: test
+ body:
+ query:
+ match:
+ text: the
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ size: 1
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - length: { aggregations.page.buckets.0.top_hits.hits.hits: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0._source.text: "the quick brown fox" }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - length: { aggregations.page.buckets.1.top_hits.hits.hits: 1 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0._source.text: "The vorpal blade went snicker-snack!" }
+
+---
+named queries:
+ - do:
+ search:
+ index: test
+ body:
+ query:
+ bool:
+ should:
+ - match:
+ text:
+ query: the
+ _name: the
+ - match:
+ text:
+ query: snack
+ _name: snack
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits: {}
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0.matched_queries: [the] }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1.matched_queries: [the] }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0.matched_queries: [the, snack] }
+
+---
+fetch fields:
+ - do:
+ search:
+ index: test
+ body:
+ fields: [text, page]
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits: {}
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0.fields.text: [the quick brown fox] }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0.fields.page: [1] }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1.fields.text: [jumped over the lazy dog] }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1.fields.page: [1] }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0.fields.text: [The vorpal blade went snicker-snack!] }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0.fields.page: [2] }
+
+---
+source filtering:
+ - do:
+ search:
+ index: test
+ body:
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ _source: text
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0._source: {"text": "the quick brown fox" }}
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1._source: {"text": "jumped over the lazy dog" }}
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0._source: {"text": "The vorpal blade went snicker-snack!" }}
+
+---
+stored fields:
+ - do:
+ search:
+ index: test
+ body:
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ stored_fields: text
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0.fields.text: [the quick brown fox] }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1.fields.text: [jumped over the lazy dog] }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0.fields.text: [The vorpal blade went snicker-snack!] }
+
+---
+docvalue fields:
+ - do:
+ search:
+ index: test
+ body:
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ docvalue_fields: [page]
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0.fields.page: [1] }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1.fields.page: [1] }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0.fields.page: [2] }
+
+---
+version:
+ - do:
+ search:
+ index: test
+ body:
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ version: true
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.0._version: 1 }
+ - match: { aggregations.page.buckets.0.top_hits.hits.hits.1._version: 1 }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - match: { aggregations.page.buckets.1.top_hits.hits.hits.0._version: 1 }
+
+---
+sequence number and primary term:
+ - do:
+ search:
+ index: test
+ body:
+ aggs:
+ page:
+ terms:
+ field: page
+ aggs:
+ top_hits:
+ top_hits:
+ seq_no_primary_term: true
+
+ - match: { hits.total.value: 3 }
+ - length: { aggregations.page.buckets: 2 }
+ - match: { aggregations.page.buckets.0.key: 1 }
+ - gte: { aggregations.page.buckets.0.top_hits.hits.hits.0._seq_no: 0 }
+ - gte: { aggregations.page.buckets.0.top_hits.hits.hits.0._primary_term: 0 }
+ - gte: { aggregations.page.buckets.0.top_hits.hits.hits.1._seq_no: 0 }
+ - gte: { aggregations.page.buckets.0.top_hits.hits.hits.1._primary_term: 0 }
+ - match: { aggregations.page.buckets.1.key: 2 }
+ - gte: { aggregations.page.buckets.1.top_hits.hits.hits.0._seq_no: 0 }
+ - gte: { aggregations.page.buckets.1.top_hits.hits.hits.0._primary_term: 0 }
diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.aggregation/200_top_hits_metric.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.aggregation/210_top_hits_nested_metric.yml
similarity index 100%
rename from rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.aggregation/200_top_hits_metric.yml
rename to rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.aggregation/210_top_hits_nested_metric.yml