diff --git a/redirects.yml b/redirects.yml
index e9d430f1b2..277e403f2d 100644
--- a/redirects.yml
+++ b/redirects.yml
@@ -290,3 +290,5 @@ redirects:
# Related to https://github.com/elastic/docs-content/pull/2097
'explore-analyze/machine-learning/machine-learning-in-kibana/xpack-ml-anomalies.md': 'explore-analyze/machine-learning/anomaly-detection.md'
'explore-analyze/machine-learning/machine-learning-in-kibana/xpack-ml-dfa-analytics.md': 'explore-analyze/machine-learning/data-frame-analytics.md'
+
+ 'solutions/search/retrievers-examples.md': 'elasticsearch://reference/elasticsearch/rest-apis/retrievers/retrievers-examples.md'
\ No newline at end of file
diff --git a/solutions/search/retrievers-examples.md b/solutions/search/retrievers-examples.md
deleted file mode 100644
index 696e45374e..0000000000
--- a/solutions/search/retrievers-examples.md
+++ /dev/null
@@ -1,1639 +0,0 @@
----
-mapped_pages:
- - https://www.elastic.co/guide/en/elasticsearch/reference/current/_retrievers_examples.html
-applies_to:
- stack:
- serverless:
-products:
- - id: elasticsearch
----
-
-# Retrievers examples [retrievers-examples]
-
-Learn how to combine different retrievers in these hands-on examples.
-
-
-## Add example data [retrievers-examples-setup]
-
-To begin with, let's create the `retrievers_example` index, and add some documents to it.
-We will set `number_of_shards=1` for our examples to ensure consistent and reproducible ordering.
-
-```console
-PUT retrievers_example
-{
- "settings": {
- "number_of_shards": 1
- },
- "mappings": {
- "properties": {
- "vector": {
- "type": "dense_vector",
- "dims": 3,
- "similarity": "l2_norm",
- "index": true,
- "index_options": {
- "type": "flat"
- }
- },
- "text": {
- "type": "text",
- "copy_to": "text_semantic"
- },
- "text_semantic": {
- "type": "semantic_text"
- },
- "year": {
- "type": "integer"
- },
- "topic": {
- "type": "keyword"
- },
- "timestamp": {
- "type": "date"
- }
- }
- }
-}
-
-POST /retrievers_example/_doc/1
-{
- "vector": [0.23, 0.67, 0.89],
- "text": "Large language models are revolutionizing information retrieval by boosting search precision, deepening contextual understanding, and reshaping user experiences in data-rich environments.",
- "year": 2024,
- "topic": ["llm", "ai", "information_retrieval"],
- "timestamp": "2021-01-01T12:10:30"
-}
-
-POST /retrievers_example/_doc/2
-{
- "vector": [0.12, 0.56, 0.78],
- "text": "Artificial intelligence is transforming medicine, from advancing diagnostics and tailoring treatment plans to empowering predictive patient care for improved health outcomes.",
- "year": 2023,
- "topic": ["ai", "medicine"],
- "timestamp": "2022-01-01T12:10:30"
-}
-
-POST /retrievers_example/_doc/3
-{
- "vector": [0.45, 0.32, 0.91],
- "text": "AI is redefining security by enabling advanced threat detection, proactive risk analysis, and dynamic defenses against increasingly sophisticated cyber threats.",
- "year": 2024,
- "topic": ["ai", "security"],
- "timestamp": "2023-01-01T12:10:30"
-}
-
-POST /retrievers_example/_doc/4
-{
- "vector": [0.34, 0.21, 0.98],
- "text": "Elastic introduces Elastic AI Assistant, the open, generative AI sidekick powered by ESRE to democratize cybersecurity and enable users of every skill level.",
- "year": 2023,
- "topic": ["ai", "elastic", "assistant"],
- "timestamp": "2024-01-01T12:10:30"
-}
-
-POST /retrievers_example/_doc/5
-{
- "vector": [0.11, 0.65, 0.47],
- "text": "Learn how to spin up a deployment on Elastic Cloud and use Elastic Observability to gain deeper insight into the behavior of your applications and systems.",
- "year": 2024,
- "topic": ["documentation", "observability", "elastic"],
- "timestamp": "2025-01-01T12:10:30"
-}
-
-POST /retrievers_example/_refresh
-```
-
-Now that we have our documents in place, let’s try to run some queries using retrievers.
-
-
-## Example: Combining query and kNN with RRF [retrievers-examples-combining-standard-knn-retrievers-with-rrf]
-
-First, let’s examine how to combine two different types of queries: a `kNN` query and a `query_string` query.
-While these queries may produce scores in different ranges, we can use Reciprocal Rank Fusion (`rrf`) to combine the results and generate a merged final result list.
-
-To implement this in the retriever framework, we start with the top-level element: our `rrf` retriever.
-This retriever operates on top of two other retrievers: a `knn` retriever and a `standard` retriever. Our query structure would look like this:
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "query_string": {
- "query": "(information retrieval) OR (artificial intelligence)",
- "default_field": "text"
- }
- }
- }
- },
- {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "_source": false
-}
-```
-
-This returns the following response based on the final rrf score for each result.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 0.8333334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.8333334
- },
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 0.8333334
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.25
- }
- ]
- }
-}
-```
-
-::::
-
-
-
-## Example: Hybrid search with linear retriever [retrievers-examples-linear-retriever]
-
-A different, and more intuitive, way to provide hybrid search, is to linearly combine the top documents of different retrievers using a weighted sum of the original scores.
-Since, as above, the scores could lie in different ranges, we can also specify a `normalizer` that would ensure that all scores for the top ranked documents of a retriever lie in a specific range.
-
-To implement this, we define a `linear` retriever, and along with a set of retrievers that will generate the heterogeneous results sets that we will combine.
-We will solve a problem similar to the above, by merging the results of a `standard` and a `knn` retriever.
-As the `standard` retriever’s scores are based on BM25 and are not strictly bounded, we will also define a `minmax` normalizer to ensure that the scores lie in the [0, 1] range.
-We will apply the same normalizer to `knn` as well to ensure that we capture the importance of each document within the result set.
-
-So, let’s now specify the `linear` retriever whose final score is computed as follows:
-
-```text
-score = weight(standard) * score(standard) + weight(knn) * score(knn)
-score = 2 * score(standard) + 1.5 * score(knn)
-```
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "linear": {
- "retrievers": [
- {
- "retriever": {
- "standard": {
- "query": {
- "query_string": {
- "query": "(information retrieval) OR (artificial intelligence)",
- "default_field": "text"
- }
- }
- }
- },
- "weight": 2,
- "normalizer": "minmax"
- },
- {
- "retriever": {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- },
- "weight": 1.5,
- "normalizer": "minmax"
- }
- ],
- "rank_window_size": 10
- }
- },
- "_source": false
-}
-```
-
-This returns the following response based on the normalized weighted score for each result.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 3.5,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 3.5
- },
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 2.3
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.1
- }
- ]
- }
-}
-```
-
-::::
-
-
-By normalizing scores and leveraging `function_score` queries, we can also implement more complex ranking strategies, such as sorting results based on their timestamps, assign the timestamp as a score, and then normalizing this score to [0, 1].
-Then, we can easily combine the above with a `knn` retriever as follows:
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "linear": {
- "retrievers": [
- {
- "retriever": {
- "standard": {
- "query": {
- "function_score": {
- "query": {
- "term": {
- "topic": "ai"
- }
- },
- "functions": [
- {
- "script_score": {
- "script": {
- "source": "doc['timestamp'].value.millis"
- }
- }
- }
- ],
- "boost_mode": "replace"
- }
- },
- "sort": {
- "timestamp": {
- "order": "asc"
- }
- }
- }
- },
- "weight": 2,
- "normalizer": "minmax"
- },
- {
- "retriever": {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- },
- "weight": 1.5
- }
- ],
- "rank_window_size": 10
- }
- },
- "_source": false
-}
-```
-
-Which would return the following results:
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 4,
- "relation": "eq"
- },
- "max_score": 3.5,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 3.5
- },
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 2.0
- },
- {
- "_index": "retrievers_example",
- "_id": "4",
- "_score": 1.1
- },
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.1
- }
- ]
- }
-}
-```
-
-::::
-
-
-## Example: RRF with the multi-field query format [retrievers-examples-rrf-multi-field-query-format]
-```yaml {applies_to}
-stack: ga 9.1
-```
-
-There's an even simpler way to execute a hybrid search though: We can use the [multi-field query format](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#multi-field-query-format), which allows us to query multiple fields without explicitly specifying inner retrievers.
-
-One of the major challenges with hybrid search is normalizing the scores across matches on all field types.
-Scores from [`text`](elasticsearch://reference/elasticsearch/mapping-reference/text.md) and [`semantic_text`](elasticsearch://reference/elasticsearch/mapping-reference/semantic-text.md) fields don't always fall in the same range, so we need to normalize the ranks across matches on these fields to generate a result set.
-For example, BM25 scores from `text` fields are unbounded, while vector similarity scores from `text_embedding` models are bounded between [0, 1].
-The multi-field query format [handles this normalization for us automatically](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#multi-field-field-grouping).
-
-The following example uses the multi-field query format to query every field specified in the `index.query.default_field` index setting, which is set to `*` by default.
-This default value will cause the retriever to query every field that either:
-
-- Supports term queries, such as `keyword` and `text` fields
-- Is a `semantic_text` field
-
-In this example, that would translate to the `text`, `text_semantic`, `year`, `topic`, and `timestamp` fields.
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "query": "artificial intelligence"
- }
- }
-}
-```
-
-This returns the following response based on the final rrf score for each result.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 0.8333334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.8333334
- },
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 0.8333334
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.25
- }
- ]
- }
-}
-```
-
-::::
-
-We can also use the `fields` parameter to explicitly specify the fields to query.
-The following example uses the multi-field query format to query the `text` and `text_semantic` fields.
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "query": "artificial intelligence",
- "fields": ["text", "text_semantic"]
- }
- }
-}
-```
-
-::::{note}
-The `fields` parameter also accepts [wildcard field patterns](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#multi-field-wildcard-field-patterns).
-::::
-
-This returns the following response based on the final rrf score for each result.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 0.8333334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.8333334
- },
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 0.8333334
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.25
- }
- ]
- }
-}
-```
-
-::::
-
-
-## Example: Linear retriever with the multi-field query format [retrievers-examples-linear-multi-field-query-format]
-```yaml {applies_to}
-stack: ga 9.1
-```
-
-We can also use the [multi-field query format](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#multi-field-query-format) with the `linear` retriever.
-It works much the same way as [on the `rrf` retriever](#retrievers-examples-rrf-multi-field-query-format), with a couple key differences:
-
-- We can use `^` notation to specify a [per-field boost](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#multi-field-field-boosting)
-- We must set the `normalizer` parameter to specify the normalization method used to combine [field group scores](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#multi-field-field-grouping)
-
-The following example uses the `linear` retriever to query the `text`, `text_semantic`, and `topic` fields, with a boost of 2 on the `topic` field:
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "linear": {
- "query": "artificial intelligence",
- "fields": ["text", "text_semantic", "topic^2"],
- "normalizer": "minmax"
- }
- }
-}
-```
-
-This returns the following response based on the normalized score for each result:
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 2.0,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 2.0
- },
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 1.2
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.1
- }
- ]
- }
-}
-```
-
-::::
-
-## Example: Grouping results by year with `collapse` [retrievers-examples-collapsing-retriever-results]
-
-In our result set, we have many documents with the same `year` value. We can clean this up using the `collapse` parameter with our retriever. This, as with the standard [collapse](elasticsearch://reference/elasticsearch/rest-apis/collapse-search-results.md) feature,
-enables grouping results by any field and returns only the highest-scoring document from each group. In this example we’ll collapse our results based on the `year` field.
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "query_string": {
- "query": "(information retrieval) OR (artificial intelligence)",
- "default_field": "text"
- }
- }
- }
- },
- {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "collapse": {
- "field": "year",
- "inner_hits": {
- "name": "topic related documents",
- "_source": [
- "year"
- ]
- }
- },
- "_source": false
-}
-```
-
-This returns the following response with collapsed results.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 0.8333334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.8333334,
- "fields": {
- "year": [
- 2024
- ]
- },
- "inner_hits": {
- "topic related documents": {
- "hits": {
- "total": {
- "value": 2,
- "relation": "eq"
- },
- "max_score": 0.8333334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.8333334,
- "_source": {
- "year": 2024
- }
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.25,
- "_source": {
- "year": 2024
- }
- }
- ]
- }
- }
- }
- },
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 0.8333334,
- "fields": {
- "year": [
- 2023
- ]
- },
- "inner_hits": {
- "topic related documents": {
- "hits": {
- "total": {
- "value": 1,
- "relation": "eq"
- },
- "max_score": 0.8333334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 0.8333334,
- "_source": {
- "year": 2023
- }
- }
- ]
- }
- }
- }
- }
- ]
- }
-}
-```
-
-::::
-
-
-
-## Example: Highlighting results based on nested sub-retrievers [retrievers-examples-highlighting-retriever-results]
-
-Highlighting is now also available for nested sub-retrievers matches. For example, consider the same `rrf` retriever as above, with a `knn` and `standard` retriever as its sub-retrievers. We can specify a `highlight` section, as defined in the [highlighting](elasticsearch://reference/elasticsearch/rest-apis/highlighting.md) documentation, and compute highlights for the top results.
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "query_string": {
- "query": "(information retrieval) OR (artificial intelligence)",
- "default_field": "text"
- }
- }
- }
- },
- {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "highlight": {
- "fields": {
- "text": {
- "fragment_size": 150,
- "number_of_fragments": 3
- }
- }
- },
- "_source": false
-}
-```
-
-This would highlight the `text` field, based on the matches produced by the `standard` retriever. The highlighted snippets would then be included in the response as usual, i.e. under each search hit.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 0.8333334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.8333334,
- "highlight": {
- "text": [
- "Large language models are revolutionizing information retrieval by boosting search precision, deepening contextual understanding, and reshaping user experiences"
- ]
- }
- },
- {
- "_index": "retrievers_example",
- "_id": "2",
- "_score": 0.8333334,
- "highlight": {
- "text": [
- "Artificial intelligence is transforming medicine, from advancing diagnostics and tailoring treatment plans to empowering predictive patient care for improved"
- ]
- }
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.25
- }
- ]
- }
-}
-```
-
-::::
-
-
-
-## Example: Computing inner hits from nested sub-retrievers [retrievers-examples-inner-hits-retriever-results]
-
-We can also define `inner_hits` to be computed on any of the sub-retrievers, and propagate those computations to the top level compound retriever. For example, let’s create a new index with a `knn` field, nested under the `nested_field` field, and index a couple of documents.
-
-```console
-PUT retrievers_example_nested
-{
- "settings": {
- "number_of_shards": 1
- },
- "mappings": {
- "properties": {
- "nested_field": {
- "type": "nested",
- "properties": {
- "paragraph_id": {
- "type": "keyword"
- },
- "nested_vector": {
- "type": "dense_vector",
- "dims": 3,
- "similarity": "l2_norm",
- "index": true,
- "index_options": {
- "type": "flat"
- }
- }
- }
- },
- "topic": {
- "type": "keyword"
- }
- }
- }
-}
-
-POST /retrievers_example_nested/_doc/1
-{
- "nested_field": [
- {
- "paragraph_id": "1a",
- "nested_vector": [
- -1.12,
- -0.59,
- 0.78
- ]
- },
- {
- "paragraph_id": "1b",
- "nested_vector": [
- -0.12,
- 1.56,
- 0.42
- ]
- },
- {
- "paragraph_id": "1c",
- "nested_vector": [
- 1,
- -1,
- 0
- ]
- }
- ],
- "topic": [
- "ai"
- ]
-}
-
-POST /retrievers_example_nested/_doc/2
-{
- "nested_field": [
- {
- "paragraph_id": "2a",
- "nested_vector": [
- 0.23,
- 1.24,
- 0.65
- ]
- }
- ],
- "topic": [
- "information_retrieval"
- ]
-}
-
-POST /retrievers_example_nested/_doc/3
-{
- "topic": [
- "ai"
- ]
-}
-
-POST /retrievers_example_nested/_refresh
-```
-
-Now we can run an `rrf` retriever query and also compute [inner hits](elasticsearch://reference/elasticsearch/rest-apis/retrieve-inner-hits.md) for the `nested_field.nested_vector` field, based on the `knn` query specified.
-
-```console
-GET /retrievers_example_nested/_search
-{
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "nested": {
- "path": "nested_field",
- "inner_hits": {
- "name": "nested_vector",
- "_source": false,
- "fields": [
- "nested_field.paragraph_id"
- ]
- },
- "query": {
- "knn": {
- "field": "nested_field.nested_vector",
- "query_vector": [
- 1,
- 0,
- 0.5
- ],
- "k": 10
- }
- }
- }
- }
- }
- },
- {
- "standard": {
- "query": {
- "term": {
- "topic": "ai"
- }
- }
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "_source": [
- "topic"
- ]
-}
-```
-
-This would propagate the `inner_hits` defined for the `knn` query to the `rrf` retriever, and compute inner hits for `rrf`'s top results.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 1.0,
- "hits": [
- {
- "_index": "retrievers_example_nested",
- "_id": "1",
- "_score": 1.0,
- "_source": {
- "topic": [
- "ai"
- ]
- },
- "inner_hits": {
- "nested_vector": {
- "hits": {
- "total": {
- "value": 3,
- "relation": "eq"
- },
- "max_score": 0.44444445,
- "hits": [
- {
- "_index": "retrievers_example_nested",
- "_id": "1",
- "_nested": {
- "field": "nested_field",
- "offset": 2
- },
- "_score": 0.44444445,
- "fields": {
- "nested_field": [
- {
- "paragraph_id": [
- "1c"
- ]
- }
- ]
- }
- },
- {
- "_index": "retrievers_example_nested",
- "_id": "1",
- "_nested": {
- "field": "nested_field",
- "offset": 1
- },
- "_score": 0.21301977,
- "fields": {
- "nested_field": [
- {
- "paragraph_id": [
- "1b"
- ]
- }
- ]
- }
- },
- {
- "_index": "retrievers_example_nested",
- "_id": "1",
- "_nested": {
- "field": "nested_field",
- "offset": 0
- },
- "_score": 0.16889325,
- "fields": {
- "nested_field": [
- {
- "paragraph_id": [
- "1a"
- ]
- }
- ]
- }
- }
- ]
- }
- }
- }
- },
- {
- "_index": "retrievers_example_nested",
- "_id": "2",
- "_score": 0.33333334,
- "_source": {
- "topic": [
- "information_retrieval"
- ]
- },
- "inner_hits": {
- "nested_vector": {
- "hits": {
- "total": {
- "value": 1,
- "relation": "eq"
- },
- "max_score": 0.31715825,
- "hits": [
- {
- "_index": "retrievers_example_nested",
- "_id": "2",
- "_nested": {
- "field": "nested_field",
- "offset": 0
- },
- "_score": 0.31715825,
- "fields": {
- "nested_field": [
- {
- "paragraph_id": [
- "2a"
- ]
- }
- ]
- }
- }
- ]
- }
- }
- }
- },
- {
- "_index": "retrievers_example_nested",
- "_id": "3",
- "_score": 0.33333334,
- "_source": {
- "topic": [
- "ai"
- ]
- },
- "inner_hits": {
- "nested_vector": {
- "hits": {
- "total": {
- "value": 0,
- "relation": "eq"
- },
- "max_score": null,
- "hits": []
- }
- }
- }
- }
- ]
- }
-}
-```
-
-::::
-
-
-Note: if using more than one `inner_hits` we need to provide custom names for each `inner_hits` so that they are unique across all retrievers within the request.
-
-
-## Example: Combine RRF with aggregations [retrievers-examples-rrf-and-aggregations]
-
-Retrievers support both composability and most of the standard `_search` functionality. For instance, we can compute aggregations with the `rrf` retriever. When using a compound retriever, the aggregations are computed based on its nested retrievers. In the following example, the `terms` aggregation for the `topic` field will include all results, not just the top `rank_window_size`, from the 2 nested retrievers, i.e. all documents whose `year` field is greater than 2023, and whose `topic` field matches the term `elastic`.
-
-```console
-GET retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "range": {
- "year": {
- "gt": 2023
- }
- }
- }
- }
- },
- {
- "standard": {
- "query": {
- "term": {
- "topic": "elastic"
- }
- }
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "_source": false,
- "aggs": {
- "topics": {
- "terms": {
- "field": "topic"
- }
- }
- }
-}
-```
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 4,
- "relation": "eq"
- },
- "max_score": 0.5833334,
- "hits": [
- {
- "_index": "retrievers_example",
- "_id": "5",
- "_score": 0.5833334
- },
- {
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.5
- },
- {
- "_index": "retrievers_example",
- "_id": "4",
- "_score": 0.5
- },
- {
- "_index": "retrievers_example",
- "_id": "3",
- "_score": 0.33333334
- }
- ]
- },
- "aggregations": {
- "topics": {
- "doc_count_error_upper_bound": 0,
- "sum_other_doc_count": 0,
- "buckets": [
- {
- "key": "ai",
- "doc_count": 3
- },
- {
- "key": "elastic",
- "doc_count": 2
- },
- {
- "key": "assistant",
- "doc_count": 1
- },
- {
- "key": "documentation",
- "doc_count": 1
- },
- {
- "key": "information_retrieval",
- "doc_count": 1
- },
- {
- "key": "llm",
- "doc_count": 1
- },
- {
- "key": "observability",
- "doc_count": 1
- },
- {
- "key": "security",
- "doc_count": 1
- }
- ]
- }
- }
-}
-```
-
-::::
-
-
-
-## Example: Explainability with multiple retrievers [retrievers-examples-explain-multiple-rrf]
-
-By adding `explain: true` to the request, each retriever will now provide a detailed explanation of all the steps and calculations required to compute the final score. Composability is fully supported in the context of `explain`, and each retriever will provide its own explanation, as shown in the example below.
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "term": {
- "topic": "elastic"
- }
- }
- }
- },
- {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "query_string": {
- "query": "(information retrieval) OR (artificial intelligence)",
- "default_field": "text"
- }
- }
- }
- },
- {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "_source": false,
- "size": 1,
- "explain": true
-}
-```
-
-The output of which, albeit a bit verbose, will provide all the necessary info to assist in debugging and reason with ranking.
-
-::::{dropdown} Example response
-```console-result
-{
- "took": 42,
- "timed_out": false,
- "_shards": {
- "total": 1,
- "successful": 1,
- "skipped": 0,
- "failed": 0
- },
- "hits": {
- "total": {
- "value": 5,
- "relation": "eq"
- },
- "max_score": 0.5,
- "hits": [
- {
- "_shard": "[retrievers_example][0]",
- "_node": "jnrdZFKS3abUgWVsVdj2Vg",
- "_index": "retrievers_example",
- "_id": "1",
- "_score": 0.5,
- "_explanation": {
- "value": 0.5,
- "description": "rrf score: [0.5] computed for initial ranks [0, 1] with rankConstant: [1] as sum of [1 / (rank + rankConstant)] for each query",
- "details": [
- {
- "value": 0.0,
- "description": "rrf score: [0], result not found in query at index [0]",
- "details": []
- },
- {
- "value": 1,
- "description": "rrf score: [0.5], for rank [1] in query at index [1] computed as [1 / (1 + 1)], for matching query with score",
- "details": [
- {
- "value": 0.8333334,
- "description": "rrf score: [0.8333334] computed for initial ranks [2, 1] with rankConstant: [1] as sum of [1 / (rank + rankConstant)] for each query",
- "details": [
- {
- "value": 2,
- "description": "rrf score: [0.33333334], for rank [2] in query at index [0] computed as [1 / (2 + 1)], for matching query with score",
- "details": [
- {
- "value": 2.8129659,
- "description": "sum of:",
- "details": [
- {
- "value": 1.4064829,
- "description": "weight(text:information in 0) [PerFieldSimilarity], result of:",
- "details": [
- ***
- ]
- },
- {
- "value": 1.4064829,
- "description": "weight(text:retrieval in 0) [PerFieldSimilarity], result of:",
- "details": [
- ***
- ]
- }
- ]
- }
- ]
- },
- {
- "value": 1,
- "description": "rrf score: [0.5], for rank [1] in query at index [1] computed as [1 / (1 + 1)], for matching query with score",
- "details": [
- {
- "value": 1,
- "description": "doc [0] with an original score of [1.0] is at rank [1] from the following source queries.",
- "details": [
- {
- "value": 1.0,
- "description": "found vector with calculated similarity: 1.0",
- "details": []
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- }
- ]
- }
-}
-```
-
-::::
-
-
-
-## Example: Rerank results of an RRF retriever [retrievers-examples-text-similarity-reranker-on-top-of-rrf]
-
-To demonstrate the full functionality of retrievers, the following examples also require access to a [semantic reranking model](/solutions/search/ranking/semantic-reranking.md) set up using the [Elastic inference APIs](https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-inference).
-
-In this example we’ll set up a reranking service and use it with the `text_similarity_reranker` retriever to rerank our top results.
-
-```console
-PUT _inference/rerank/my-rerank-model
-{
- "service": "cohere",
- "service_settings": {
- "model_id": "rerank-english-v3.0",
- "api_key": "{{COHERE_API_KEY}}"
- }
-}
-```
-
-Let’s start by reranking the results of the `rrf` retriever in our previous example.
-
-```console
-GET retrievers_example/_search
-{
- "retriever": {
- "text_similarity_reranker": {
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "standard": {
- "query": {
- "query_string": {
- "query": "(information retrieval) OR (artificial intelligence)",
- "default_field": "text"
- }
- }
- }
- },
- {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "field": "text",
- "inference_id": "my-rerank-model",
- "inference_text": "What are the state of the art applications of AI in information retrieval?"
- }
- },
- "_source": false
-}
-```
-
-
-## Example: RRF with semantic reranker [retrievers-examples-rrf-ranking-on-text-similarity-reranker-results]
-
-For this example, we’ll replace the rrf’s `standard` retriever with the `text_similarity_reranker` retriever, using the `my-rerank-model` reranker we previously configured. Since this is a reranker, it needs an initial pool of documents to work with. In this case, we’ll rerank the top `rank_window_size` documents matching the `ai` topic.
-
-```console
-GET /retrievers_example/_search
-{
- "retriever": {
- "rrf": {
- "retrievers": [
- {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- },
- {
- "text_similarity_reranker": {
- "retriever": {
- "standard": {
- "query": {
- "term": {
- "topic": "ai"
- }
- }
- }
- },
- "field": "text",
- "inference_id": "my-rerank-model",
- "inference_text": "Can I use generative AI to identify user intent and improve search relevance?"
- }
- }
- ],
- "rank_window_size": 10,
- "rank_constant": 1
- }
- },
- "_source": false
-}
-```
-
-
-## Example: Chaining multiple semantic rerankers [retrievers-examples-chaining-text-similarity-reranker-retrievers]
-
-Full composability means we can chain together multiple retrievers of the same type. For instance, imagine we have a computationally expensive reranker that’s specialized for AI content. We can rerank the results of a `text_similarity_reranker` using another `text_similarity_reranker` retriever. Each reranker can operate on different fields and/or use different inference services.
-
-```console
-GET retrievers_example/_search
-{
- "retriever": {
- "text_similarity_reranker": {
- "retriever": {
- "text_similarity_reranker": {
- "retriever": {
- "knn": {
- "field": "vector",
- "query_vector": [
- 0.23,
- 0.67,
- 0.89
- ],
- "k": 3,
- "num_candidates": 5
- }
- },
- "rank_window_size": 100,
- "field": "text",
- "inference_id": "my-rerank-model",
- "inference_text": "What are the state of the art applications of AI in information retrieval?"
- }
- },
- "rank_window_size": 10,
- "field": "text",
- "inference_id": "my-other-more-expensive-rerank-model",
- "inference_text": "Applications of Large Language Models in technology and their impact on user satisfaction"
- }
- },
- "_source": false
-}
-```
-
-Note that our example applies two reranking steps. First, we rerank the top 100 documents from the `knn` search using the `my-rerank-model` reranker. Then we pick the top 10 results and rerank them using the more fine-grained `my-other-more-expensive-rerank-model`.
-
diff --git a/solutions/search/retrievers-overview.md b/solutions/search/retrievers-overview.md
index aa1a7da919..061b17c38f 100644
--- a/solutions/search/retrievers-overview.md
+++ b/solutions/search/retrievers-overview.md
@@ -15,24 +15,23 @@ A retriever is an abstraction that was added to the `_search` API in **8.14.0**
This syntax enables the configuration of multi-stage retrieval pipelines within a single `_search` call. This simplifies your search application logic, because you no longer need to configure complex searches via multiple {{es}} calls or implement additional client-side logic to combine results from different queries.
::::{note}
-This document provides a general overview of the retriever abstraction. For a full syntax reference and implementation overview, check out the [reference documentation](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md) in the `_search` API docs.
-::::
-
-::::{tip}
-Prefer to start with some sample code? Check out [](retrievers-examples.md) for a collection of retriever examples.
+This document provides a general overview of the retriever abstraction. For a full syntax reference and implementation overview, check out the [reference documentation](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md).
::::
## Retriever types [retrievers-overview-types]
+% KEEP IN SYNC with https://github.com/elastic/elasticsearch/blob/main/docs/reference/elasticsearch/rest-apis/retrievers.md
+
Retrievers come in various types, each tailored for different search operations. The following retrievers are currently available:
-* [**Standard Retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#standard-retriever). Returns top documents from a traditional [query](/explore-analyze/query-filter/languages/querydsl.md). Mimics a traditional query but in the context of a retriever framework. This ensures backward compatibility as existing `_search` requests remain supported. That way you can transition to the new abstraction at your own pace without mixing syntaxes.
-* [**kNN Retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#knn-retriever). Returns top documents from a [knn search](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search#search-api-knn), in the context of a retriever framework.
-* [**Linear Retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#linear-retriever). Combines the top results from multiple sub-retrievers using a weighted sum of their scores. Allows to specify different weights for each retriever, as well as independently normalize the scores from each result set.
-* [**Rescorer retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#rescorer-retriever). Re-scores the results produced by its child retriever. Replaces the functionality of the [query rescorer](elasticsearch://reference/elasticsearch/rest-apis/filter-search-results.md#rescore).
-* [**RRF Retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#rrf-retriever). Combines and ranks multiple first-stage retrievers using the reciprocal rank fusion (RRF) algorithm. Allows you to combine multiple result sets with different relevance indicators into a single result set. An RRF retriever is a **compound retriever**, where its `filter` element is propagated to its sub retrievers.
-* [**Rule Retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#rule-retriever). Applies [query rules](elasticsearch://reference/elasticsearch/rest-apis/searching-with-query-rules.md#query-rules) to the query before returning results.
-* [**Text Similarity Re-ranker Retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#text-similarity-reranker-retriever). Used for semantic reranking.
+* [**kNN retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#knn-retriever). Returns top documents from a [knn search](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search#search-api-knn), in the context of a retriever framework.
+* [**Linear retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#linear-retriever). Combines the top results from multiple sub-retrievers using a weighted sum of their scores.
+* [**Pinned retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#pinned-retriever). Always places specified documents at the top of the results, with the remaining hits provided by a secondary retriever.
+* [**Rescorer retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#rescorer-retriever). Re-scores the results produced by its child retriever.
+* [**RRF retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#rrf-retriever). Compound retriever which combines and ranks multiple first-stage retrievers using the reciprocal rank fusion (RRF) algorithm.
+* [**Rule retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#rule-retriever). Applies [query rules](elasticsearch://reference/elasticsearch/rest-apis/searching-with-query-rules.md#query-rules) to the query before returning results.
+* [**Standard retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#standard-retriever). Returns top documents from a traditional [query](/explore-analyze/query-filter/languages/querydsl.md).
+* [**Text Similarity Re-ranker retriever**](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md#text-similarity-reranker-retriever). Used for semantic reranking.
## What makes retrievers useful? [retrievers-overview-why-are-they-useful]
@@ -120,8 +119,7 @@ GET example-index/_search
```
::::
-For more examples, refer to [retriever examples](retrievers-examples.md).
-
+For more examples, refer to [retriever examples](elasticsearch://reference/elasticsearch/rest-apis/retrievers/retrievers-examples.md).
## Glossary [retrievers-overview-glossary]
@@ -144,8 +142,10 @@ You can use the Playground to experiment with different retriever configurations
Refer to the [Playground documentation](rag/playground.md) for more information.
-## API reference [retrievers-overview-api-reference]
+## Reference docs and examples [retrievers-overview-api-reference]
+
+For implementation details, including notable restrictions, refer to the [reference documentation](elasticsearch://reference/elasticsearch/rest-apis/retrievers.md).
-For implementation details, including notable restrictions, check out the [reference documentation](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search#operation-search-body-application-json-retriever) in the Search API docs.
+For additional examples, refer to [Retrievers examples](elasticsearch://reference/elasticsearch/rest-apis/retrievers/retrievers-examples.md).
diff --git a/solutions/toc.yml b/solutions/toc.yml
index 336a5603ec..a8a3c9b20b 100644
--- a/solutions/toc.yml
+++ b/solutions/toc.yml
@@ -77,8 +77,6 @@ toc:
- file: search/async-search-api.md
- file: search/esql-for-search.md
- file: search/retrievers-overview.md
- children:
- - file: search/retrievers-examples.md
- file: search/search-templates.md
- file: search/site-or-app.md
children: