From 7bd84d193700f035d8776ae7278d7f6a5119be7a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:26:03 +0000 Subject: [PATCH 1/8] Initial plan From d9f2aa93090925529ecaed19e91102447eb99734 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:43:55 +0000 Subject: [PATCH 2/8] Add intervals query tutorial with runnable examples and advanced prefix use case Co-authored-by: leemthompo <32779855+leemthompo@users.noreply.github.com> Agent-Logs-Url: https://github.com/elastic/docs-content/sessions/bc2dc533-b754-466a-b219-02e150b9c84b --- .../query-filter/languages/querydsl.md | 1 + solutions/search/full-text.md | 6 + .../full-text/intervals-query-tutorial.md | 293 ++++++++++++++++++ solutions/toc.yml | 1 + 4 files changed, 301 insertions(+) create mode 100644 solutions/search/full-text/intervals-query-tutorial.md diff --git a/explore-analyze/query-filter/languages/querydsl.md b/explore-analyze/query-filter/languages/querydsl.md index 47f97da7211..340e0f8e24b 100644 --- a/explore-analyze/query-filter/languages/querydsl.md +++ b/explore-analyze/query-filter/languages/querydsl.md @@ -23,6 +23,7 @@ The [`_search` endpoint](../../../solutions/search/querying-for-search.md) accep Query DSL supports a wide range of search techniques, including the following: * [**Full-text search**](/solutions/search/full-text.md): Search text that has been analyzed and indexed to support phrase or proximity queries, fuzzy matches, and more. + * Use the [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) to search for terms based on their order and proximity. Refer to [Use the intervals query](/solutions/search/full-text/intervals-query-tutorial.md) for a hands-on example. * [**Keyword search**](elasticsearch://reference/elasticsearch/mapping-reference/keyword.md): Search for exact matches using `keyword` fields. * [**Semantic search**](/solutions/search/semantic-search/semantic-search-semantic-text.md): Search `semantic_text` fields using dense or sparse vector search on embeddings generated in your {{es}} cluster. * [**Vector search**](/solutions/search/vector/knn.md): Search for similar dense vectors using the kNN algorithm for embeddings generated outside of {{es}}. diff --git a/solutions/search/full-text.md b/solutions/search/full-text.md index c3901cc26b0..dfe224904b0 100644 --- a/solutions/search/full-text.md +++ b/solutions/search/full-text.md @@ -49,6 +49,12 @@ Learn how to build full-text search queries using {{es}}'s query languages: * [Full-text queries using Query DSL](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) * [Full-text search functions in {{esql}}](elasticsearch://reference/query-languages/esql/functions-operators/search-functions.md) +**Proximity and ordering searches** + +The [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) lets you search for terms based on their order and proximity in the text. This is useful when you need to find phrases where terms must appear in a specific order or within a limited distance of each other. + +* [Use the intervals query](full-text/intervals-query-tutorial.md) — A hands-on tutorial with sample data, runnable examples, and an advanced use case for prefix-based proximity search. + **Advanced topics** For a technical deep dive into {{es}}'s BM25 implementation read this blog post: [The BM25 Algorithm and its Variables](https://www.elastic.co/blog/practical-bm25-part-2-the-bm25-algorithm-and-its-variables). diff --git a/solutions/search/full-text/intervals-query-tutorial.md b/solutions/search/full-text/intervals-query-tutorial.md new file mode 100644 index 00000000000..72c83fc4ceb --- /dev/null +++ b/solutions/search/full-text/intervals-query-tutorial.md @@ -0,0 +1,293 @@ +--- +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch +--- + +# Use the intervals query [intervals-query-tutorial] + +The [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) returns documents based on the **order and proximity** of matching terms. Unlike the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md), it lets you define flexible rules about how terms appear relative to each other — allowing gaps, enforcing ordering, and combining multiple term sequences. + +Use this tutorial to learn how to: + +* Index sample data and run a basic intervals query +* Perform ordered proximity searches using `all_of` with `any_of` +* Narrow results further using the `prefix` rule + +::::{tip} +The code examples use [Console](../../../explore-analyze/query-filter/tools/console.md) syntax. +You can [convert examples into other programming languages](../../../explore-analyze/query-filter/tools/console.md#import-export-console-requests) in the Console UI. +:::: + +## Requirements [intervals-query-tutorial-requirements] + +You can follow these steps with any {{es}} deployment. +Refer to [Choosing your deployment type](../../../deploy-manage/deploy.md) for deployment options. + +## Create an index [intervals-query-tutorial-create-index] + +Create a `products` index: + +```console +PUT /products +``` + +## Add sample documents [intervals-query-tutorial-index-data] + +Index several product descriptions to use as sample data: + +```console +POST /products/_bulk?refresh=wait_for +{"index":{"_id":"1"}} +{"description":"fast full text search for developers"} +{"index":{"_id":"2"}} +{"description":"full text search with machine learning"} +{"index":{"_id":"3"}} +{"description":"machine learning performance optimization"} +{"index":{"_id":"4"}} +{"description":"developer tools for fast search"} +{"index":{"_id":"5"}} +{"description":"high performance machine learning platform"} +``` + +The [`standard` analyzer](elasticsearch://reference/text-analysis/analyzer-reference/standard-analyzer.md) is used by default for `text` fields. +It lowercases and tokenizes the text, so each word becomes a searchable term at a specific position. +For example, document 1 produces the tokens `fast`(0), `full`(1), `text`(2), `search`(3), `for`(4), `developers`(5). + +To learn more about how text is analyzed and indexed, refer to [Text analysis during search](text-analysis-during-search.md). + +## Basic ordered proximity search [intervals-query-tutorial-basic-example] + +Find products where `full text` appears immediately before `search`: + +```console +GET /products/_search +{ + "query": { + "intervals": { + "description": { + "all_of": { + "ordered": true, <1> + "intervals": [ + { + "match": { + "query": "full text", + "max_gaps": 0, <2> + "ordered": true + } + }, + { + "match": { + "query": "search" + } + } + ] + } + } + } + } +} +``` + +1. `ordered: true` on `all_of` enforces that `full text` must appear before `search`. +2. `max_gaps: 0` on the inner `match` requires `full` and `text` to be adjacent with no words in between. + +::::{dropdown} Example response +```console-result +{ + "hits": { + "total": { + "value": 2, + "relation": "eq" + }, + "hits": [ + { + "_id": "1", + "_score": 0.5, + "_source": { + "description": "fast full text search for developers" + } + }, + { + "_id": "2", + "_score": 0.5, + "_source": { + "description": "full text search with machine learning" + } + } + ] + } +} +``` +:::: + +Documents 1 and 2 match because both contain `full text search` in that exact order with no gaps. +Documents 3, 4, and 5 don't contain `full text` followed immediately by `search`. + +## Combining multiple intervals rules [intervals-query-tutorial-any-of-example] + +Find products that describe `machine learning` near either `search` or `performance`, in any order and within two positions: + +```console +GET /products/_search +{ + "query": { + "intervals": { + "description": { + "all_of": { + "ordered": false, <1> + "max_gaps": 2, <2> + "intervals": [ + { + "match": { + "query": "machine learning" + } + }, + { + "any_of": { <3> + "intervals": [ + { "match": { "query": "search" } }, + { "match": { "query": "performance" } } + ] + } + } + ] + } + } + } + } +} +``` + +1. `ordered: false` allows `machine learning` and the other term to appear in either order. +2. `max_gaps: 2` limits the number of unmatched positions between the two intervals to two. +3. `any_of` matches whichever alternative appears in the text. + +::::{dropdown} Example response +```console-result +{ + "hits": { + "total": { + "value": 3, + "relation": "eq" + }, + "hits": [ + { + "_id": "2", + "_score": 0.5, + "_source": { + "description": "full text search with machine learning" + } + }, + { + "_id": "3", + "_score": 0.5, + "_source": { + "description": "machine learning performance optimization" + } + }, + { + "_id": "5", + "_score": 0.5, + "_source": { + "description": "high performance machine learning platform" + } + } + ] + } +} +``` +:::: + +Document 2 matches because `search` and `machine learning` are within two positions of each other (`with` is the only word between them). +Documents 3 and 5 match because `performance` immediately precedes `machine learning` in both. +Documents 1 and 4 don't contain `machine learning`. + +## Advanced use case: Searching for terms by prefix [intervals-query-tutorial-prefix-example] + +The `prefix` rule matches any term that starts with a given set of characters, letting you broaden an interval without enumerating every possible form. +Use it when the exact term varies but the leading characters are consistent. + +Find products that mention something starting with `fast` near `search`: + +```console +GET /products/_search +{ + "query": { + "intervals": { + "description": { + "all_of": { + "ordered": false, + "max_gaps": 2, + "intervals": [ + { + "prefix": { <1> + "prefix": "fast" + } + }, + { + "match": { + "query": "search" + } + } + ] + } + } + } + } +} +``` + +1. The `prefix` rule expands to match any term beginning with `fast`, such as `fast`, `faster`, or `fastest`. + +::::{warning} +The `prefix` rule can expand to match many terms depending on your data. To avoid errors caused by exceeding the `indices.query.bool.max_clause_count` [search setting](/reference/elasticsearch/configuration-reference/search-settings.md), use the [`index-prefixes`](/reference/elasticsearch/mapping-reference/index-prefixes.md) option in your field mapping, or keep prefix patterns specific enough to limit expansion. +:::: + +::::{dropdown} Example response +```console-result +{ + "hits": { + "total": { + "value": 2, + "relation": "eq" + }, + "hits": [ + { + "_id": "1", + "_score": 0.5, + "_source": { + "description": "fast full text search for developers" + } + }, + { + "_id": "4", + "_score": 0.5, + "_source": { + "description": "developer tools for fast search" + } + } + ] + } +} +``` +:::: + +Documents 1 and 4 match because both contain a term starting with `fast` within two positions of `search`. + +## Clean up [intervals-query-tutorial-cleanup] + +Delete the `products` index when you're done: + +```console +DELETE /products +``` + +## Next steps [intervals-query-tutorial-next-steps] + +* Refer to the full [intervals query reference](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) for all available rules and parameters, including `filter`, `fuzzy`, `wildcard`, and `regexp` rules. +* Learn how [text analysis](../../../manage-data/data-store/text-analysis.md) affects how terms are stored and matched. +* Explore [full-text queries](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) for other proximity and matching options. +* Use the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for strict phrase matching without gaps. diff --git a/solutions/toc.yml b/solutions/toc.yml index 57ae7eec2b5..360cc3eded4 100644 --- a/solutions/toc.yml +++ b/solutions/toc.yml @@ -19,6 +19,7 @@ toc: children: - file: search/full-text/how-full-text-works.md - file: search/full-text/text-analysis-during-search.md + - file: search/full-text/intervals-query-tutorial.md - file: search/full-text/search-relevance.md children: - file: search/full-text/search-relevance/mixing-exact-search-with-stemming.md From f0a37402fcceffc069b9e1970d7d87a40972a694 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 16:19:23 +0000 Subject: [PATCH 3/8] Polish intervals query tutorial: align with tutorial template, fix accuracy, add filter example Major improvements: - Restructure to follow Elastic tutorial content type template (frontmatter with description/navigation_title, "Before you begin", numbered steps, summary section) - Replace thin sample data with richer book synopses that better demonstrate each feature - Fix factual error in any_of example (doc 5 matches too, gap=2) - Add max_gaps: 0 to outer all_of in basic example to actually enforce adjacency (was misleading before) - Add Step 5: filter example with not_containing (demonstrates an additional advanced use case from the reference page) - Fix prefix example: sample data now includes both "fast" and "faster" to meaningfully demonstrate prefix expansion - Revert querydsl.md (sub-bullet was inconsistent with page structure) - Simplify full-text.md change to a single bullet under existing section Co-authored-by: leemthompo <32779855+leemthompo@users.noreply.github.com> Agent-Logs-Url: https://github.com/elastic/docs-content/sessions/8101e7ca-119f-4e37-a334-76fe7a08b9dd --- .../query-filter/languages/querydsl.md | 1 - solutions/search/full-text.md | 7 +- .../full-text/intervals-query-tutorial.md | 220 ++++++++++++------ 3 files changed, 153 insertions(+), 75 deletions(-) diff --git a/explore-analyze/query-filter/languages/querydsl.md b/explore-analyze/query-filter/languages/querydsl.md index 340e0f8e24b..47f97da7211 100644 --- a/explore-analyze/query-filter/languages/querydsl.md +++ b/explore-analyze/query-filter/languages/querydsl.md @@ -23,7 +23,6 @@ The [`_search` endpoint](../../../solutions/search/querying-for-search.md) accep Query DSL supports a wide range of search techniques, including the following: * [**Full-text search**](/solutions/search/full-text.md): Search text that has been analyzed and indexed to support phrase or proximity queries, fuzzy matches, and more. - * Use the [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) to search for terms based on their order and proximity. Refer to [Use the intervals query](/solutions/search/full-text/intervals-query-tutorial.md) for a hands-on example. * [**Keyword search**](elasticsearch://reference/elasticsearch/mapping-reference/keyword.md): Search for exact matches using `keyword` fields. * [**Semantic search**](/solutions/search/semantic-search/semantic-search-semantic-text.md): Search `semantic_text` fields using dense or sparse vector search on embeddings generated in your {{es}} cluster. * [**Vector search**](/solutions/search/vector/knn.md): Search for similar dense vectors using the kNN algorithm for embeddings generated outside of {{es}}. diff --git a/solutions/search/full-text.md b/solutions/search/full-text.md index dfe224904b0..abdada29305 100644 --- a/solutions/search/full-text.md +++ b/solutions/search/full-text.md @@ -48,12 +48,7 @@ Learn how to build full-text search queries using {{es}}'s query languages: * [Full-text queries using Query DSL](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) * [Full-text search functions in {{esql}}](elasticsearch://reference/query-languages/esql/functions-operators/search-functions.md) - -**Proximity and ordering searches** - -The [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) lets you search for terms based on their order and proximity in the text. This is useful when you need to find phrases where terms must appear in a specific order or within a limited distance of each other. - -* [Use the intervals query](full-text/intervals-query-tutorial.md) — A hands-on tutorial with sample data, runnable examples, and an advanced use case for prefix-based proximity search. +* [Intervals query tutorial](full-text/intervals-query-tutorial.md) — Learn how to search by term proximity and order **Advanced topics** diff --git a/solutions/search/full-text/intervals-query-tutorial.md b/solutions/search/full-text/intervals-query-tutorial.md index 72c83fc4ceb..9d318979cb8 100644 --- a/solutions/search/full-text/intervals-query-tutorial.md +++ b/solutions/search/full-text/intervals-query-tutorial.md @@ -1,4 +1,6 @@ --- +navigation_title: "Intervals query" +description: "Learn how to use the Elasticsearch intervals query for proximity and order-sensitive full-text searches." applies_to: stack: ga serverless: ga @@ -6,75 +8,73 @@ products: - id: elasticsearch --- -# Use the intervals query [intervals-query-tutorial] +# Search by term proximity and order with the intervals query [intervals-query-tutorial] -The [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) returns documents based on the **order and proximity** of matching terms. Unlike the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md), it lets you define flexible rules about how terms appear relative to each other — allowing gaps, enforcing ordering, and combining multiple term sequences. +The [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) finds documents based on the **order and proximity** of matching terms. +Unlike the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md), it lets you define flexible rules about how terms relate to each other — allowing gaps between terms, enforcing ordering, and combining multiple term patterns. -Use this tutorial to learn how to: +By the end of this tutorial, you can: -* Index sample data and run a basic intervals query -* Perform ordered proximity searches using `all_of` with `any_of` -* Narrow results further using the `prefix` rule +* Run a basic ordered proximity search using `all_of` with `match` +* Combine `all_of` and `any_of` rules for flexible matching +* Use the `prefix` rule to match term variants by their leading characters +* Apply a `filter` rule to exclude unwanted terms from proximity matches ::::{tip} The code examples use [Console](../../../explore-analyze/query-filter/tools/console.md) syntax. You can [convert examples into other programming languages](../../../explore-analyze/query-filter/tools/console.md#import-export-console-requests) in the Console UI. :::: -## Requirements [intervals-query-tutorial-requirements] +## Before you begin [intervals-query-tutorial-prereqs] You can follow these steps with any {{es}} deployment. Refer to [Choosing your deployment type](../../../deploy-manage/deploy.md) for deployment options. -## Create an index [intervals-query-tutorial-create-index] +## Step 1: Create an index and add sample data [intervals-query-tutorial-setup] -Create a `products` index: +Create a `books` index and add several sample documents: ```console -PUT /products +PUT /books ``` -## Add sample documents [intervals-query-tutorial-index-data] - -Index several product descriptions to use as sample data: - ```console -POST /products/_bulk?refresh=wait_for +POST /books/_bulk?refresh=wait_for {"index":{"_id":"1"}} -{"description":"fast full text search for developers"} +{"title":"Elasticsearch in Action","synopsis":"A practical guide to full text search with Elasticsearch. Covers queries, filters, and performance tuning."} {"index":{"_id":"2"}} -{"description":"full text search with machine learning"} +{"title":"Search Fundamentals","synopsis":"Learn the basics of full text search including tokenization, analyzers, and relevance scoring."} {"index":{"_id":"3"}} -{"description":"machine learning performance optimization"} +{"title":"Faster Elasticsearch","synopsis":"Tips for fast and efficient search at scale. Covers caching, faster queries, and cluster optimization."} {"index":{"_id":"4"}} -{"description":"developer tools for fast search"} +{"title":"Machine Learning for Search","synopsis":"Apply machine learning to improve search relevance. Covers learning to rank and query classification."} {"index":{"_id":"5"}} -{"description":"high performance machine learning platform"} +{"title":"Advanced Text Processing","synopsis":"Deep dive into text analysis and search pipelines. Full coverage of custom analyzers and token filters."} ``` The [`standard` analyzer](elasticsearch://reference/text-analysis/analyzer-reference/standard-analyzer.md) is used by default for `text` fields. It lowercases and tokenizes the text, so each word becomes a searchable term at a specific position. -For example, document 1 produces the tokens `fast`(0), `full`(1), `text`(2), `search`(3), `for`(4), `developers`(5). -To learn more about how text is analyzed and indexed, refer to [Text analysis during search](text-analysis-during-search.md). +To learn more, refer to [Text analysis](../../../manage-data/data-store/text-analysis.md). -## Basic ordered proximity search [intervals-query-tutorial-basic-example] +## Step 2: Run a basic ordered proximity search [intervals-query-tutorial-basic-example] -Find products where `full text` appears immediately before `search`: +Use `all_of` with `ordered: true` to find books where `full text` appears immediately before `search`, with no gaps allowed: ```console -GET /products/_search +GET /books/_search { "query": { "intervals": { - "description": { + "synopsis": { "all_of": { "ordered": true, <1> + "max_gaps": 0, <2> "intervals": [ { "match": { "query": "full text", - "max_gaps": 0, <2> + "max_gaps": 0, "ordered": true } }, @@ -91,8 +91,8 @@ GET /products/_search } ``` -1. `ordered: true` on `all_of` enforces that `full text` must appear before `search`. -2. `max_gaps: 0` on the inner `match` requires `full` and `text` to be adjacent with no words in between. +1. `ordered: true` requires the first interval (`full text`) to appear before the second (`search`). +2. `max_gaps: 0` on `all_of` requires both intervals to be adjacent — no words between `text` and `search`. ::::{dropdown} Example response ```console-result @@ -107,14 +107,16 @@ GET /products/_search "_id": "1", "_score": 0.5, "_source": { - "description": "fast full text search for developers" + "title": "Elasticsearch in Action", + "synopsis": "A practical guide to full text search with Elasticsearch. Covers queries, filters, and performance tuning." } }, { "_id": "2", "_score": 0.5, "_source": { - "description": "full text search with machine learning" + "title": "Search Fundamentals", + "synopsis": "Learn the basics of full text search including tokenization, analyzers, and relevance scoring." } } ] @@ -123,33 +125,34 @@ GET /products/_search ``` :::: -Documents 1 and 2 match because both contain `full text search` in that exact order with no gaps. -Documents 3, 4, and 5 don't contain `full text` followed immediately by `search`. +Documents 1 and 2 match because both contain `full text search` as three contiguous, ordered terms. +The other documents don't contain the phrase `full text search`. -## Combining multiple intervals rules [intervals-query-tutorial-any-of-example] +## Step 3: Combine rules with `any_of` [intervals-query-tutorial-any-of-example] -Find products that describe `machine learning` near either `search` or `performance`, in any order and within two positions: +Use `any_of` inside `all_of` to match alternative terms. +This query finds books where `search` appears within two positions of either `machine learning` or `text`, in any order: ```console -GET /products/_search +GET /books/_search { "query": { "intervals": { - "description": { + "synopsis": { "all_of": { "ordered": false, <1> "max_gaps": 2, <2> "intervals": [ { "match": { - "query": "machine learning" + "query": "search" } }, { "any_of": { <3> "intervals": [ - { "match": { "query": "search" } }, - { "match": { "query": "performance" } } + { "match": { "query": "machine learning" } }, + { "match": { "query": "text" } } ] } } @@ -161,38 +164,49 @@ GET /products/_search } ``` -1. `ordered: false` allows `machine learning` and the other term to appear in either order. -2. `max_gaps: 2` limits the number of unmatched positions between the two intervals to two. -3. `any_of` matches whichever alternative appears in the text. +1. `ordered: false` allows the intervals to appear in any order. +2. `max_gaps: 2` allows up to two unmatched positions between the intervals. +3. `any_of` matches either `machine learning` or `text`. ::::{dropdown} Example response ```console-result { "hits": { "total": { - "value": 3, + "value": 4, "relation": "eq" }, "hits": [ + { + "_id": "1", + "_score": 0.5, + "_source": { + "title": "Elasticsearch in Action", + "synopsis": "A practical guide to full text search with Elasticsearch. Covers queries, filters, and performance tuning." + } + }, { "_id": "2", "_score": 0.5, "_source": { - "description": "full text search with machine learning" + "title": "Search Fundamentals", + "synopsis": "Learn the basics of full text search including tokenization, analyzers, and relevance scoring." } }, { - "_id": "3", + "_id": "4", "_score": 0.5, "_source": { - "description": "machine learning performance optimization" + "title": "Machine Learning for Search", + "synopsis": "Apply machine learning to improve search relevance. Covers learning to rank and query classification." } }, { "_id": "5", "_score": 0.5, "_source": { - "description": "high performance machine learning platform" + "title": "Advanced Text Processing", + "synopsis": "Deep dive into text analysis and search pipelines. Full coverage of custom analyzers and token filters." } } ] @@ -201,26 +215,26 @@ GET /products/_search ``` :::: -Document 2 matches because `search` and `machine learning` are within two positions of each other (`with` is the only word between them). -Documents 3 and 5 match because `performance` immediately precedes `machine learning` in both. -Documents 1 and 4 don't contain `machine learning`. +Documents 1 and 2 match because `text` appears immediately before `search` (zero gaps). +Document 4 matches because `search` appears two positions after `machine learning` (`to` and `improve` are the intervening tokens). +Document 5 matches because `text` and `search` are two positions apart (`analysis` and `and` are between them). +Document 3 doesn't match because its synopsis contains neither `text` nor `machine learning` near `search`. -## Advanced use case: Searching for terms by prefix [intervals-query-tutorial-prefix-example] +## Step 4: Match term variants with `prefix` [intervals-query-tutorial-prefix-example] -The `prefix` rule matches any term that starts with a given set of characters, letting you broaden an interval without enumerating every possible form. -Use it when the exact term varies but the leading characters are consistent. +The `prefix` rule matches any term that starts with a given set of characters, so you can match term variants without listing every form. -Find products that mention something starting with `fast` near `search`: +Find books where any term starting with `fast` appears within three positions of `search`: ```console -GET /products/_search +GET /books/_search { "query": { "intervals": { - "description": { + "synopsis": { "all_of": { "ordered": false, - "max_gaps": 2, + "max_gaps": 3, "intervals": [ { "prefix": { <1> @@ -240,12 +254,70 @@ GET /products/_search } ``` -1. The `prefix` rule expands to match any term beginning with `fast`, such as `fast`, `faster`, or `fastest`. +1. The `prefix` rule matches any indexed term beginning with `fast`, including `fast`, `faster`, and `fastest`. ::::{warning} -The `prefix` rule can expand to match many terms depending on your data. To avoid errors caused by exceeding the `indices.query.bool.max_clause_count` [search setting](/reference/elasticsearch/configuration-reference/search-settings.md), use the [`index-prefixes`](/reference/elasticsearch/mapping-reference/index-prefixes.md) option in your field mapping, or keep prefix patterns specific enough to limit expansion. +The `prefix` rule can expand to match many terms depending on your data. +To avoid errors from exceeding the `indices.query.bool.max_clause_count` [search setting](/reference/elasticsearch/configuration-reference/search-settings.md), use the [`index-prefixes`](/reference/elasticsearch/mapping-reference/index-prefixes.md) mapping option or keep prefix patterns specific enough to limit expansion. :::: +::::{dropdown} Example response +```console-result +{ + "hits": { + "total": { + "value": 1, + "relation": "eq" + }, + "hits": [ + { + "_id": "3", + "_score": 0.5, + "_source": { + "title": "Faster Elasticsearch", + "synopsis": "Tips for fast and efficient search at scale. Covers caching, faster queries, and cluster optimization." + } + } + ] + } +} +``` +:::: + +Document 3 matches because `fast` appears two positions before `search` (`and efficient` are the intervening tokens). +A regular `match` for `fast` would also find this document, but the `prefix` rule additionally catches variants like `faster` in the same document — ensuring the query works even if the data uses different word forms. + +## Step 5: Exclude terms with a filter [intervals-query-tutorial-filter-example] + +Use the `filter` rule to exclude unwanted terms from a proximity match. +This query finds books where `search` appears near `text`, but only when `analysis` does not appear between them: + +```console +GET /books/_search +{ + "query": { + "intervals": { + "synopsis": { + "match": { + "query": "text search", + "max_gaps": 5, + "ordered": false, + "filter": { <1> + "not_containing": { + "match": { + "query": "analysis" + } + } + } + } + } + } + } +} +``` + +1. The `not_containing` filter excludes intervals where `analysis` appears between `text` and `search`. + ::::{dropdown} Example response ```console-result { @@ -259,14 +331,16 @@ The `prefix` rule can expand to match many terms depending on your data. To avoi "_id": "1", "_score": 0.5, "_source": { - "description": "fast full text search for developers" + "title": "Elasticsearch in Action", + "synopsis": "A practical guide to full text search with Elasticsearch. Covers queries, filters, and performance tuning." } }, { - "_id": "4", + "_id": "2", "_score": 0.5, "_source": { - "description": "developer tools for fast search" + "title": "Search Fundamentals", + "synopsis": "Learn the basics of full text search including tokenization, analyzers, and relevance scoring." } } ] @@ -275,19 +349,29 @@ The `prefix` rule can expand to match many terms depending on your data. To avoi ``` :::: -Documents 1 and 4 match because both contain a term starting with `fast` within two positions of `search`. +Documents 1 and 2 match because both contain `text` near `search` without `analysis` between them. +Document 5 also contains `text` near `search` (and matched in [Step 3](#intervals-query-tutorial-any-of-example)), but `analysis` appears between them (the tokens `text`, `analysis`, `and`, `search` are contiguous), so the filter excludes it. ## Clean up [intervals-query-tutorial-cleanup] -Delete the `products` index when you're done: +Delete the `books` index: ```console -DELETE /products +DELETE /books ``` +## Summary [intervals-query-tutorial-summary] + +In this tutorial, you learned how to: + +* Search for ordered, contiguous phrases with `all_of` and `max_gaps` +* Match alternative terms using `any_of` +* Broaden interval matching to term variants using the `prefix` rule +* Exclude unwanted terms from proximity matches using a `filter` rule + ## Next steps [intervals-query-tutorial-next-steps] -* Refer to the full [intervals query reference](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) for all available rules and parameters, including `filter`, `fuzzy`, `wildcard`, and `regexp` rules. +* Refer to the full [intervals query reference](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) for all available rules and parameters, including `fuzzy`, `wildcard`, `regexp`, and `range` rules. * Learn how [text analysis](../../../manage-data/data-store/text-analysis.md) affects how terms are stored and matched. -* Explore [full-text queries](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) for other proximity and matching options. +* Explore [full-text queries](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) for other matching options. * Use the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for strict phrase matching without gaps. From a51da081dffb0d3c68ab5c1ce710d5a7b8c719e4 Mon Sep 17 00:00:00 2001 From: Liam Thompson Date: Thu, 9 Jul 2026 09:40:53 +0100 Subject: [PATCH 4/8] Fix intervals tutorial cross-repo links --- solutions/search/full-text/intervals-query-tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/search/full-text/intervals-query-tutorial.md b/solutions/search/full-text/intervals-query-tutorial.md index 9d318979cb8..ad2f44f96e5 100644 --- a/solutions/search/full-text/intervals-query-tutorial.md +++ b/solutions/search/full-text/intervals-query-tutorial.md @@ -52,7 +52,7 @@ POST /books/_bulk?refresh=wait_for {"title":"Advanced Text Processing","synopsis":"Deep dive into text analysis and search pipelines. Full coverage of custom analyzers and token filters."} ``` -The [`standard` analyzer](elasticsearch://reference/text-analysis/analyzer-reference/standard-analyzer.md) is used by default for `text` fields. +The [`standard` analyzer](elasticsearch://reference/text-analysis/analysis-standard-analyzer.md) is used by default for `text` fields. It lowercases and tokenizes the text, so each word becomes a searchable term at a specific position. To learn more, refer to [Text analysis](../../../manage-data/data-store/text-analysis.md). @@ -258,7 +258,7 @@ GET /books/_search ::::{warning} The `prefix` rule can expand to match many terms depending on your data. -To avoid errors from exceeding the `indices.query.bool.max_clause_count` [search setting](/reference/elasticsearch/configuration-reference/search-settings.md), use the [`index-prefixes`](/reference/elasticsearch/mapping-reference/index-prefixes.md) mapping option or keep prefix patterns specific enough to limit expansion. +To avoid errors from exceeding the `indices.query.bool.max_clause_count` [search setting](elasticsearch://reference/elasticsearch/configuration-reference/search-settings.md), use the [`index_prefixes`](elasticsearch://reference/elasticsearch/mapping-reference/index-prefixes.md) mapping option or keep prefix patterns specific enough to limit expansion. :::: ::::{dropdown} Example response From 10ec5cb64dce9a24328b925578c3030ae134f2a5 Mon Sep 17 00:00:00 2001 From: Liam Thompson Date: Mon, 26 Oct 2026 15:08:11 +0100 Subject: [PATCH 5/8] Fix intervals tutorial responses verified against 9.6 - Correct step 3 hit order and scores to match actual responses - Rewrite step 4 so the prefix rule matches only through a term variant - Clarify the prefix expansion warning and move it after the example - Remove em-dashes from tutorial prose and the full-text.md link Co-Authored-By: Claude Opus 5.5 --- solutions/search/full-text.md | 2 +- .../full-text/intervals-query-tutorial.md | 49 ++++++++++--------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/solutions/search/full-text.md b/solutions/search/full-text.md index e83e3c7a4d5..1dfb9b8c73b 100644 --- a/solutions/search/full-text.md +++ b/solutions/search/full-text.md @@ -49,7 +49,7 @@ Learn how to build full-text search queries using {{es}}'s query languages: * [Full-text queries using Query DSL](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) * [Full-text search functions in {{esql}}](elasticsearch://reference/query-languages/esql/functions-operators/search-functions.md) -* [Intervals query tutorial](full-text/intervals-query-tutorial.md) — Learn how to search by term proximity and order +* [Search by term proximity and order with the intervals query](full-text/intervals-query-tutorial.md) **Advanced topics** diff --git a/solutions/search/full-text/intervals-query-tutorial.md b/solutions/search/full-text/intervals-query-tutorial.md index ad2f44f96e5..3e923b2f61f 100644 --- a/solutions/search/full-text/intervals-query-tutorial.md +++ b/solutions/search/full-text/intervals-query-tutorial.md @@ -11,7 +11,8 @@ products: # Search by term proximity and order with the intervals query [intervals-query-tutorial] The [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) finds documents based on the **order and proximity** of matching terms. -Unlike the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md), it lets you define flexible rules about how terms relate to each other — allowing gaps between terms, enforcing ordering, and combining multiple term patterns. +Unlike the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md), it lets you define flexible rules about how terms relate to each other. +You can allow gaps between terms, enforce term order, and combine multiple term patterns. By the end of this tutorial, you can: @@ -92,7 +93,7 @@ GET /books/_search ``` 1. `ordered: true` requires the first interval (`full text`) to appear before the second (`search`). -2. `max_gaps: 0` on `all_of` requires both intervals to be adjacent — no words between `text` and `search`. +2. `max_gaps: 0` on `all_of` requires both intervals to be adjacent, with no words between `text` and `search`. ::::{dropdown} Example response ```console-result @@ -194,19 +195,19 @@ GET /books/_search } }, { - "_id": "4", - "_score": 0.5, + "_id": "5", + "_score": 0.25, "_source": { - "title": "Machine Learning for Search", - "synopsis": "Apply machine learning to improve search relevance. Covers learning to rank and query classification." + "title": "Advanced Text Processing", + "synopsis": "Deep dive into text analysis and search pipelines. Full coverage of custom analyzers and token filters." } }, { - "_id": "5", - "_score": 0.5, + "_id": "4", + "_score": 0.19999999, "_source": { - "title": "Advanced Text Processing", - "synopsis": "Deep dive into text analysis and search pipelines. Full coverage of custom analyzers and token filters." + "title": "Machine Learning for Search", + "synopsis": "Apply machine learning to improve search relevance. Covers learning to rank and query classification." } } ] @@ -216,15 +217,15 @@ GET /books/_search :::: Documents 1 and 2 match because `text` appears immediately before `search` (zero gaps). -Document 4 matches because `search` appears two positions after `machine learning` (`to` and `improve` are the intervening tokens). Document 5 matches because `text` and `search` are two positions apart (`analysis` and `and` are between them). +Document 4 matches because `search` appears two positions after `machine learning` (`to` and `improve` are the intervening tokens). Document 3 doesn't match because its synopsis contains neither `text` nor `machine learning` near `search`. ## Step 4: Match term variants with `prefix` [intervals-query-tutorial-prefix-example] The `prefix` rule matches any term that starts with a given set of characters, so you can match term variants without listing every form. -Find books where any term starting with `fast` appears within three positions of `search`: +Find books where any term starting with `fast` appears immediately before `queries`: ```console GET /books/_search @@ -233,8 +234,8 @@ GET /books/_search "intervals": { "synopsis": { "all_of": { - "ordered": false, - "max_gaps": 3, + "ordered": true, + "max_gaps": 0, "intervals": [ { "prefix": { <1> @@ -243,7 +244,7 @@ GET /books/_search }, { "match": { - "query": "search" + "query": "queries" } } ] @@ -254,12 +255,7 @@ GET /books/_search } ``` -1. The `prefix` rule matches any indexed term beginning with `fast`, including `fast`, `faster`, and `fastest`. - -::::{warning} -The `prefix` rule can expand to match many terms depending on your data. -To avoid errors from exceeding the `indices.query.bool.max_clause_count` [search setting](elasticsearch://reference/elasticsearch/configuration-reference/search-settings.md), use the [`index_prefixes`](elasticsearch://reference/elasticsearch/mapping-reference/index-prefixes.md) mapping option or keep prefix patterns specific enough to limit expansion. -:::: +1. The `prefix` rule matches any indexed term that starts with `fast`, such as `fast`, `faster`, and `fastest`. ::::{dropdown} Example response ```console-result @@ -284,8 +280,15 @@ To avoid errors from exceeding the `indices.query.bool.max_clause_count` [search ``` :::: -Document 3 matches because `fast` appears two positions before `search` (`and efficient` are the intervening tokens). -A regular `match` for `fast` would also find this document, but the `prefix` rule additionally catches variants like `faster` in the same document — ensuring the query works even if the data uses different word forms. +Document 3 matches because its synopsis contains `faster queries`. +If you replace the `prefix` rule with a `match` rule for `fast`, the query returns no results. +The index stores `fast` and `faster` as separate terms, and the only `fast` in document 3 is followed by `and`, not `queries`. + +::::{warning} +The `prefix` rule can expand to match many terms depending on your data. +If a prefix matches more terms than the `indices.query.bool.max_clause_count` [search setting](elasticsearch://reference/elasticsearch/configuration-reference/search-settings.md) allows, {{es}} returns an error. +To avoid this, use the [`index_prefixes`](elasticsearch://reference/elasticsearch/mapping-reference/index-prefixes.md) mapping option or keep prefixes specific enough to limit expansion. +:::: ## Step 5: Exclude terms with a filter [intervals-query-tutorial-filter-example] From 90b9f96b15ee5af5cceff0d8ff892bc6dcc9f40d Mon Sep 17 00:00:00 2001 From: Liam Thompson Date: Mon, 26 Oct 2026 15:24:39 +0100 Subject: [PATCH 6/8] Name the Query DSL intervals query explicitly in the tutorial Co-Authored-By: Claude Opus 5.5 --- solutions/search/full-text.md | 2 +- solutions/search/full-text/intervals-query-tutorial.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/solutions/search/full-text.md b/solutions/search/full-text.md index 1dfb9b8c73b..058e38558f6 100644 --- a/solutions/search/full-text.md +++ b/solutions/search/full-text.md @@ -49,7 +49,7 @@ Learn how to build full-text search queries using {{es}}'s query languages: * [Full-text queries using Query DSL](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) * [Full-text search functions in {{esql}}](elasticsearch://reference/query-languages/esql/functions-operators/search-functions.md) -* [Search by term proximity and order with the intervals query](full-text/intervals-query-tutorial.md) +* [Search by term proximity and order with the Query DSL intervals query](full-text/intervals-query-tutorial.md) **Advanced topics** diff --git a/solutions/search/full-text/intervals-query-tutorial.md b/solutions/search/full-text/intervals-query-tutorial.md index 3e923b2f61f..72c61fc99e9 100644 --- a/solutions/search/full-text/intervals-query-tutorial.md +++ b/solutions/search/full-text/intervals-query-tutorial.md @@ -1,6 +1,6 @@ --- -navigation_title: "Intervals query" -description: "Learn how to use the Elasticsearch intervals query for proximity and order-sensitive full-text searches." +navigation_title: "Query DSL intervals query" +description: "Learn how to use the Query DSL intervals query in Elasticsearch for proximity and order-sensitive full-text search." applies_to: stack: ga serverless: ga @@ -8,9 +8,9 @@ products: - id: elasticsearch --- -# Search by term proximity and order with the intervals query [intervals-query-tutorial] +# Search by term proximity and order with the Query DSL intervals query [intervals-query-tutorial] -The [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) finds documents based on the **order and proximity** of matching terms. +The Query DSL [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) finds documents based on the **order and proximity** of matching terms. Unlike the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md), it lets you define flexible rules about how terms relate to each other. You can allow gaps between terms, enforce term order, and combine multiple term patterns. @@ -374,7 +374,7 @@ In this tutorial, you learned how to: ## Next steps [intervals-query-tutorial-next-steps] -* Refer to the full [intervals query reference](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) for all available rules and parameters, including `fuzzy`, `wildcard`, `regexp`, and `range` rules. +* Refer to the full [Query DSL intervals query reference](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) for all available rules and parameters, including `fuzzy`, `wildcard`, `regexp`, and `range` rules. * Learn how [text analysis](../../../manage-data/data-store/text-analysis.md) affects how terms are stored and matched. * Explore [full-text queries](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) for other matching options. * Use the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for strict phrase matching without gaps. From 2681e0e36466ea457f5f5174fe0c87e84f5814f5 Mon Sep 17 00:00:00 2001 From: Liam Thompson Date: Mon, 26 Oct 2026 16:49:12 +0100 Subject: [PATCH 7/8] Address review findings in the intervals query tutorial - Expand Before you begin with access, privileges, and assumed knowledge - Add audience statement, Step 1 checkpoint, and type: tutorial - Fix match_phrase wording to account for slop - Style fixes: active voice, contractions, heading parallelism, split long sentence Co-Authored-By: Claude Opus 5.5 --- .../full-text/intervals-query-tutorial.md | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/solutions/search/full-text/intervals-query-tutorial.md b/solutions/search/full-text/intervals-query-tutorial.md index 72c61fc99e9..7ff5e63bb4b 100644 --- a/solutions/search/full-text/intervals-query-tutorial.md +++ b/solutions/search/full-text/intervals-query-tutorial.md @@ -6,14 +6,17 @@ applies_to: serverless: ga products: - id: elasticsearch +type: tutorial --- # Search by term proximity and order with the Query DSL intervals query [intervals-query-tutorial] -The Query DSL [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) finds documents based on the **order and proximity** of matching terms. +The Query DSL [intervals query](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) finds documents based on the order and proximity of matching terms. Unlike the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md), it lets you define flexible rules about how terms relate to each other. You can allow gaps between terms, enforce term order, and combine multiple term patterns. +This tutorial is for developers who know basic Query DSL queries and want finer control over how matching terms relate to each other. + By the end of this tutorial, you can: * Run a basic ordered proximity search using `all_of` with `match` @@ -28,8 +31,12 @@ You can [convert examples into other programming languages](../../../explore-ana ## Before you begin [intervals-query-tutorial-prereqs] -You can follow these steps with any {{es}} deployment. -Refer to [Choosing your deployment type](../../../deploy-manage/deploy.md) for deployment options. +To follow this tutorial, you need: + +* Access to an {{es}} project or deployment. Refer to [Choosing your deployment type](../../../deploy-manage/deploy.md) for deployment options. +* A way to send requests, such as [Console](../../../explore-analyze/query-filter/tools/console.md). +* Index privileges to create, write to, read, and delete the `books` index, such as the `all` [index privilege](elasticsearch://reference/elasticsearch/security-privileges.md#privileges-list-indices). +* Familiarity with basic [Query DSL](../../../explore-analyze/query-filter/languages/querydsl.md) queries. It also helps to know how [text analysis](../../../manage-data/data-store/text-analysis.md) breaks text into terms at specific positions, because intervals rules match on those positions. ## Step 1: Create an index and add sample data [intervals-query-tutorial-setup] @@ -53,7 +60,9 @@ POST /books/_bulk?refresh=wait_for {"title":"Advanced Text Processing","synopsis":"Deep dive into text analysis and search pipelines. Full coverage of custom analyzers and token filters."} ``` -The [`standard` analyzer](elasticsearch://reference/text-analysis/analysis-standard-analyzer.md) is used by default for `text` fields. +The response shows `"errors": false` when all five documents are indexed. + +By default, `text` fields use the [`standard` analyzer](elasticsearch://reference/text-analysis/analysis-standard-analyzer.md). It lowercases and tokenizes the text, so each word becomes a searchable term at a specific position. To learn more, refer to [Text analysis](../../../manage-data/data-store/text-analysis.md). @@ -218,7 +227,7 @@ GET /books/_search Documents 1 and 2 match because `text` appears immediately before `search` (zero gaps). Document 5 matches because `text` and `search` are two positions apart (`analysis` and `and` are between them). -Document 4 matches because `search` appears two positions after `machine learning` (`to` and `improve` are the intervening tokens). +Document 4 matches because `search` appears two positions after `machine learning` (`to` and `improve` are between them). Document 3 doesn't match because its synopsis contains neither `text` nor `machine learning` near `search`. ## Step 4: Match term variants with `prefix` [intervals-query-tutorial-prefix-example] @@ -287,13 +296,13 @@ The index stores `fast` and `faster` as separate terms, and the only `fast` in d ::::{warning} The `prefix` rule can expand to match many terms depending on your data. If a prefix matches more terms than the `indices.query.bool.max_clause_count` [search setting](elasticsearch://reference/elasticsearch/configuration-reference/search-settings.md) allows, {{es}} returns an error. -To avoid this, use the [`index_prefixes`](elasticsearch://reference/elasticsearch/mapping-reference/index-prefixes.md) mapping option or keep prefixes specific enough to limit expansion. +To avoid this error, use the [`index_prefixes`](elasticsearch://reference/elasticsearch/mapping-reference/index-prefixes.md) mapping option or keep prefixes specific enough to limit expansion. :::: -## Step 5: Exclude terms with a filter [intervals-query-tutorial-filter-example] +## Step 5: Exclude terms with a `filter` rule [intervals-query-tutorial-filter-example] Use the `filter` rule to exclude unwanted terms from a proximity match. -This query finds books where `search` appears near `text`, but only when `analysis` does not appear between them: +This query finds books where `search` appears near `text`, but only when `analysis` doesn't appear between them: ```console GET /books/_search @@ -353,7 +362,8 @@ GET /books/_search :::: Documents 1 and 2 match because both contain `text` near `search` without `analysis` between them. -Document 5 also contains `text` near `search` (and matched in [Step 3](#intervals-query-tutorial-any-of-example)), but `analysis` appears between them (the tokens `text`, `analysis`, `and`, `search` are contiguous), so the filter excludes it. +Document 5 also contains `text` near `search` and matched in [Step 3](#intervals-query-tutorial-any-of-example). +However, its synopsis contains `text analysis and search`, so `analysis` appears between the two terms and the filter excludes the document. ## Clean up [intervals-query-tutorial-cleanup] @@ -377,4 +387,4 @@ In this tutorial, you learned how to: * Refer to the full [Query DSL intervals query reference](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md) for all available rules and parameters, including `fuzzy`, `wildcard`, `regexp`, and `range` rules. * Learn how [text analysis](../../../manage-data/data-store/text-analysis.md) affects how terms are stored and matched. * Explore [full-text queries](elasticsearch://reference/query-languages/query-dsl/full-text-queries.md) for other matching options. -* Use the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for strict phrase matching without gaps. +* Use the [`match_phrase` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) when you need to match a phrase, using `slop` to allow gaps between terms. From 803623d76aaec9b52e860e7bb471ef748f30485e Mon Sep 17 00:00:00 2001 From: Liam Thompson Date: Mon, 26 Oct 2026 18:18:50 +0100 Subject: [PATCH 8/8] Address technical review on intervals query tutorial - Replace the fast/faster prefix example, which stemming already handles, with a partial-word example - Explain how scores drop as matching terms get farther apart Co-Authored-By: Claude Opus 5.5 --- .../full-text/intervals-query-tutorial.md | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/solutions/search/full-text/intervals-query-tutorial.md b/solutions/search/full-text/intervals-query-tutorial.md index 7ff5e63bb4b..e72725e19d6 100644 --- a/solutions/search/full-text/intervals-query-tutorial.md +++ b/solutions/search/full-text/intervals-query-tutorial.md @@ -21,7 +21,7 @@ By the end of this tutorial, you can: * Run a basic ordered proximity search using `all_of` with `match` * Combine `all_of` and `any_of` rules for flexible matching -* Use the `prefix` rule to match term variants by their leading characters +* Use the `prefix` rule to match partial words * Apply a `filter` rule to exclude unwanted terms from proximity matches ::::{tip} @@ -230,11 +230,16 @@ Document 5 matches because `text` and `search` are two positions apart (`analysi Document 4 matches because `search` appears two positions after `machine learning` (`to` and `improve` are between them). Document 3 doesn't match because its synopsis contains neither `text` nor `machine learning` near `search`. -## Step 4: Match term variants with `prefix` [intervals-query-tutorial-prefix-example] +The scores drop as the matching terms get farther apart. +Documents 1 and 2 score highest because their matching terms are adjacent, and documents 5 and 4 score lower because other terms sit between the matches. +The intervals query gives shorter matches a higher score. -The `prefix` rule matches any term that starts with a given set of characters, so you can match term variants without listing every form. +## Step 4: Match partial words with `prefix` [intervals-query-tutorial-prefix-example] -Find books where any term starting with `fast` appears immediately before `queries`: +The `prefix` rule matches any term that starts with a given set of characters. +This is useful when the input contains a partial word, such as when a user has typed only the start of a word in a search box. + +Find books where `search` is immediately followed by a term that starts with `relev`: ```console GET /books/_search @@ -247,13 +252,13 @@ GET /books/_search "max_gaps": 0, "intervals": [ { - "prefix": { <1> - "prefix": "fast" + "match": { + "query": "search" } }, { - "match": { - "query": "queries" + "prefix": { <1> + "prefix": "relev" } } ] @@ -264,7 +269,7 @@ GET /books/_search } ``` -1. The `prefix` rule matches any indexed term that starts with `fast`, such as `fast`, `faster`, and `fastest`. +1. The `prefix` rule matches any indexed term that starts with `relev`, such as `relevance` and `relevant`. ::::{dropdown} Example response ```console-result @@ -276,11 +281,11 @@ GET /books/_search }, "hits": [ { - "_id": "3", + "_id": "4", "_score": 0.5, "_source": { - "title": "Faster Elasticsearch", - "synopsis": "Tips for fast and efficient search at scale. Covers caching, faster queries, and cluster optimization." + "title": "Machine Learning for Search", + "synopsis": "Apply machine learning to improve search relevance. Covers learning to rank and query classification." } } ] @@ -289,9 +294,9 @@ GET /books/_search ``` :::: -Document 3 matches because its synopsis contains `faster queries`. -If you replace the `prefix` rule with a `match` rule for `fast`, the query returns no results. -The index stores `fast` and `faster` as separate terms, and the only `fast` in document 3 is followed by `and`, not `queries`. +Document 4 matches because its synopsis contains `search relevance`. +If you replace the `prefix` rule with a `match` rule for `relev`, the query returns no results, because `relev` isn't a complete term in the index. +Document 2 also contains `relevance`, but four other terms sit between it and `search`, so `max_gaps: 0` excludes it. ::::{warning} The `prefix` rule can expand to match many terms depending on your data. @@ -379,7 +384,7 @@ In this tutorial, you learned how to: * Search for ordered, contiguous phrases with `all_of` and `max_gaps` * Match alternative terms using `any_of` -* Broaden interval matching to term variants using the `prefix` rule +* Match partial words using the `prefix` rule * Exclude unwanted terms from proximity matches using a `filter` rule ## Next steps [intervals-query-tutorial-next-steps]