diff --git a/explore-analyze/query-filter/languages/querydsl.md b/explore-analyze/query-filter/languages/querydsl.md index 4ee072620c..6cebbb3c24 100644 --- a/explore-analyze/query-filter/languages/querydsl.md +++ b/explore-analyze/query-filter/languages/querydsl.md @@ -11,12 +11,6 @@ products: # Query DSL -$$$filter-context$$$ - -$$$query-dsl-allow-expensive-queries$$$ - -$$$relevance-scores$$$ - ## What's Query DSL? [search-analyze-query-dsl] **Query DSL** is a full-featured JSON-style query language that enables complex searching, filtering, and aggregations. It is the original and most powerful query language for {{es}} today. @@ -65,12 +59,12 @@ $$$query-dsl-allow-expensive-queries$$$ **Allow expensive queries**: Certain types of queries will generally execute slowly due to the way they are implemented, which can affect the stability of the cluster. Those queries can be categorized as follows: - - Queries that need to do linear scans to identify matches: + - Queries that need to do linear scans to identify matches: - [`script` queries](elasticsearch://reference/query-languages/query-dsl/query-dsl-script-query.md) - queries on [numeric](elasticsearch://reference/elasticsearch/mapping-reference/number.md), [date](elasticsearch://reference/elasticsearch/mapping-reference/date.md), [boolean](elasticsearch://reference/elasticsearch/mapping-reference/boolean.md), [ip](elasticsearch://reference/elasticsearch/mapping-reference/ip.md), [geo_point](elasticsearch://reference/elasticsearch/mapping-reference/geo-point.md) or [keyword](elasticsearch://reference/elasticsearch/mapping-reference/keyword.md) fields that are not indexed but have [doc values](elasticsearch://reference/elasticsearch/mapping-reference/doc-values.md) enabled - - Queries that have a high up-front cost: + - Queries that have a high up-front cost: - [`fuzzy` queries](elasticsearch://reference/query-languages/query-dsl/query-dsl-fuzzy-query.md) (except on [`wildcard`](elasticsearch://reference/elasticsearch/mapping-reference/keyword.md#wildcard-field-type) fields) - [`regexp` queries](elasticsearch://reference/query-languages/query-dsl/query-dsl-regexp-query.md) (except on [`wildcard`](elasticsearch://reference/elasticsearch/mapping-reference/keyword.md#wildcard-field-type) fields) @@ -78,8 +72,8 @@ $$$query-dsl-allow-expensive-queries$$$ - [`wildcard` queries](elasticsearch://reference/query-languages/query-dsl/query-dsl-wildcard-query.md) (except on [`wildcard`](elasticsearch://reference/elasticsearch/mapping-reference/keyword.md#wildcard-field-type) fields) - [`range` queries](elasticsearch://reference/query-languages/query-dsl/query-dsl-range-query.md) on [`text`](elasticsearch://reference/elasticsearch/mapping-reference/text.md) and [`keyword`](elasticsearch://reference/elasticsearch/mapping-reference/keyword.md) fields - - [Joining queries](elasticsearch://reference/query-languages/query-dsl/joining-queries.md) - - Queries that may have a high per-document cost: + - [Joining queries](elasticsearch://reference/query-languages/query-dsl/joining-queries.md) + - Queries that may have a high per-document cost: - [`script_score` queries](elasticsearch://reference/query-languages/query-dsl/query-dsl-script-score-query.md) - [`percolate` queries](elasticsearch://reference/query-languages/query-dsl/query-dsl-percolate-query.md) diff --git a/solutions/search/elasticsearch-basics-quickstart.md b/solutions/search/elasticsearch-basics-quickstart.md index 862576483a..e44a148e8a 100644 --- a/solutions/search/elasticsearch-basics-quickstart.md +++ b/solutions/search/elasticsearch-basics-quickstart.md @@ -6,7 +6,7 @@ applies_to: # Basics quickstart [getting-started] -This quick start guide is a hands-on introduction to the fundamental concepts of Elasticsearch: [indices, documents, and field type mappings](../../manage-data/data-store/index-basics.md). You’ll learn how to create an index, add data as documents, work with dynamic and explicit mappings, and perform your first basic searches. +This quickstart provides a hands-on introduction to the fundamental concepts of Elasticsearch: [indices, documents, and field type mappings](../../manage-data/data-store/index-basics.md). You'll learn how to create an index, add documents, work with dynamic and explicit mappings, and perform your first basic searches. ::::{tip} The code examples in this tutorial are in [Console](../../explore-analyze/query-filter/tools/console.md) syntax by default. You can [convert into other programming languages](../../explore-analyze/query-filter/tools/console.md#import-export-console-requests) in the Console UI. @@ -15,9 +15,7 @@ The code examples in this tutorial are in [Console](../../explore-analyze/query- ## Requirements [getting-started-requirements] -You can follow this guide using any {{es}} deployment. If you already have a deployment up and running, you can skip ahead to the [first step](#getting-started-index-creation). - -If not, refer to [choose your deployment type](/deploy-manage/deploy.md#choosing-your-deployment-type) for your options. To get started quickly, you can spin up a cluster [locally in Docker](get-started.md): +You can follow this guide using any {{es}} deployment. If you have a deployment setup ready, skip ahead to the [first step](#getting-started-index-creation). If not, refer [choose your deployment type](/deploy-manage/deploy.md#choosing-your-deployment-type) to see all deployment options. To get started quickly, spin up a cluster [locally in Docker](run-elasticsearch-locally.md): ```sh curl -fsSL https://elastic.co/start-local | sh @@ -45,8 +43,6 @@ The following response indicates the index was created successfully. :::: - - ## Step 2: Add data to your index [getting-started-add-documents] ::::{tip} @@ -60,10 +56,10 @@ You add data to {{es}} as JSON objects called documents. {{es}} stores these doc ### Add a single document [getting-started-add-single-document] -Submit the following indexing request to add a single document to the `books` index. +Use the following request to add a single document to the `books` index. -::::{tip} -If the index didn’t already exist, this request would automatically create it. +::::{note} +If the index doesn't already exist, this request will automatically create it. :::: @@ -97,25 +93,23 @@ The response includes metadata that {{es}} generates for the document, including } ``` -1. The `_index` field indicates the index the document was added to. -2. The `_id` field is the unique identifier for the document. -3. The `_version` field indicates the version of the document. -4. The `result` field indicates the result of the indexing operation. -5. The `_shards` field contains information about the number of [shards](../../deploy-manage/index.md) that the indexing operation was executed on and the number that succeeded. -6. The `total` field indicates the total number of shards for the index. -7. The `successful` field indicates the number of shards that the indexing operation was executed on. -8. The `failed` field indicates the number of shards that failed during the indexing operation. *0* indicates no failures. -9. The `_seq_no` field holds a monotonically increasing number incremented for each indexing operation on a shard. -10. The `_primary_term` field is a monotonically increasing number incremented each time a primary shard is assigned to a different node. +1. `_index`: The index the document was added to. +2. `_id`: The unique identifier for the document. +3. `_version`: The version of the document. +4. `result`: The result of the indexing operation. +5. `_shards`: Information about the number of [shards](../../deploy-manage/distributed-architecture/clusters-nodes-shards.md) that the indexing operation was executed on and the number that succeeded. +6. `total`: The total number of shards for the index. +7. `successful`: The number of shards that the indexing operation was executed on. +8. `failed`: The number of shards that failed during the indexing operation. *0* indicates no failures. +9. `_seq_no`: A monotonically increasing number incremented for each indexing operation on a shard. +10. `_primary_term`: A monotonically increasing number incremented each time a primary shard is assigned to a different node. :::: - - ### Add multiple documents [getting-started-add-multiple-documents] -Use the [`_bulk` endpoint](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-bulk) to add multiple documents in one request. Bulk data must be formatted as newline-delimited JSON (NDJSON). +Use the [`_bulk` endpoint](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-bulk) to add multiple documents in a single request. Bulk data must be formatted as newline-delimited JSON (NDJSON). ```console POST /_bulk @@ -131,8 +125,6 @@ POST /_bulk {"name": "The Handmaids Tale", "author": "Margaret Atwood", "release_date": "1985-06-01", "page_count": 311} ``` -You should receive a response indicating there were no errors. - ::::{dropdown} Example response ```console-result { @@ -227,16 +219,16 @@ You should receive a response indicating there were no errors. -## Step 3: Define mappings and data types [getting-started-mappings-and-data-types] +## Step 3: Define mappings [getting-started-mappings-and-data-types] [Mappings](../../manage-data/data-store/index-basics.md#elasticsearch-intro-documents-fields-mappings) define how data is stored and indexed in {{es}}, like a schema in a relational database. ### Use dynamic mapping [getting-started-dynamic-mapping] -When using dynamic mapping, {{es}} automatically creates mappings for new fields by default. The documents we’ve added so far have used dynamic mapping, because we didn’t specify a mapping when creating the index. +When you use dynamic mapping, {{es}} automatically creates mappings for new fields by default. The documents you’ve added so far have used dynamic mapping, because you didn’t specify a mapping while creating the index. -To see how dynamic mapping works, add a new document to the `books` index with a field that doesn’t appear in the existing documents. +To see how dynamic mapping works, add a new document to the `books` index with a field that isn't available in the existing documents. ```console POST /books/_doc @@ -251,13 +243,13 @@ POST /books/_doc 1. The new field. - View the mapping for the `books` index with the [Get mapping API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-mapping). The new field `language` has been added to the mapping with a `text` data type. ```console GET /books/_mapping ``` +The following response displays the mappings that were created by Elasticsearch. ::::{dropdown} Example response ```console-result { @@ -309,7 +301,7 @@ GET /books/_mapping ### Define explicit mapping [getting-started-explicit-mapping] -Create an index named `my-explicit-mappings-books` with explicit mappings. Pass each field’s properties as a JSON object. This object should contain the [field data type](elasticsearch://reference/elasticsearch/mapping-reference/field-data-types.md) and any additional [mapping parameters](elasticsearch://reference/elasticsearch/mapping-reference/mapping-parameters.md). +Create an index named `my-explicit-mappings-books` and specify the mappings yourself. Pass each field’s properties as a JSON object. This object should contain the [field data type](elasticsearch://reference/elasticsearch/mapping-reference/field-data-types.md) and any additional [mapping parameters](elasticsearch://reference/elasticsearch/mapping-reference/mapping-parameters.md). ```console PUT /my-explicit-mappings-books @@ -326,10 +318,10 @@ PUT /my-explicit-mappings-books } ``` -1. Disables dynamic mapping for the index. Fields not defined in the mapping will still be stored in the document's `_source` field, but they won’t be indexed or searchable. -2. The `properties` object defines the fields and their data types for documents in this index. - +1. `dynamic`: Disables dynamic mapping for the index. If you don't define fields in the mapping, they'll still be stored in the document's `_source` field, but you can't index or search them. +2. `properties`: Defines the fields and their corresponding data types. +The following response indicates a successful operation. ::::{dropdown} Example response ```console-result { @@ -350,14 +342,14 @@ Explicit mappings are defined at index creation, and documents must conform to t This allows you to combine explicit and dynamic mappings. Learn more about [managing and updating mappings](../../manage-data/data-store/mapping.md#mapping-manage-update). -## Step 4: Search your index [getting-started-search-data] +## Step 4: Search your data [getting-started-search-data] Indexed documents are available for search in near real-time, using the [`_search` API](querying-for-search.md). ### Search all documents [getting-started-search-all-documents] -Run the following command to search the `books` index for all documents: +Use the following request to search all documents in the `books` index: ```console GET books/_search @@ -398,27 +390,25 @@ GET books/_search } ``` -1. The `took` field indicates the time in milliseconds for {{es}} to execute the search -2. The `timed_out` field indicates whether the search timed out -3. The `_shards` field contains information about the number of [shards](/reference/glossary/index.md) that the search was executed on and the number that succeeded -4. The `hits` object contains the search results -5. The `total` object provides information about the total number of matching documents -6. The `max_score` field indicates the highest relevance score among all matching documents -7. The `_index` field indicates the index the document belongs to -8. The `_id` field is the document’s unique identifier -9. The `_score` field indicates the relevance score of the document -10. The `_source` field contains the original JSON object submitted during indexing +1. `took`: The time in milliseconds for {{es}} to execute the search +2. `timed_out`: Indicates if the search timed out +3. `_shards`: Information about the number of [shards](/reference/glossary/index.md) that the search was executed on and the number that succeeded +4. `hits`: Has the search results +5. `total`: Information about the total number of matching documents +6. `max_score`: The highest relevance score among all matching documents +7. `_index`: The index the document belongs to +8. `_id`: The document’s unique identifier +9. `_score`: The relevance score of the document +10. `_source`: The original JSON object submitted during indexing :::: +### Search using `match` query [getting-started-match-query] +Use the [`match` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query.md) to search for documents that contain a specific value in a specific field. This is the standard query for full-text searches. -### `match` query [getting-started-match-query] - -You can use the [`match` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query.md) to search for documents that contain a specific value in a specific field. This is the standard query for full-text searches. - -Run the following command to search the `books` index for documents containing `brave` in the `name` field: +Use the following request to search the `books` index for documents containing `brave` in the `name` field: ```console GET books/_search @@ -465,18 +455,18 @@ GET books/_search } ``` -1. The `max_score` is the score of the highest-scoring document in the results. In this case, there is only one matching document, so the `max_score` is the score of that document. +1. `max_score`: Score of the highest-scoring document in the results. In this case, there is only one matching document, so the `max_score` is the score of that document. :::: -## Step 5: Delete your indices (optional) [getting-started-delete-indices] +## Step 5: Delete your indices [getting-started-delete-indices] -When following along with examples, you might want to delete an index to start from scratch. You can delete indices using the [Delete index API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-delete). +If you want to delete an index to start from scratch at any point, use the [Delete index API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-delete). -For example, run the following command to delete the indices created in this tutorial: +For example, use the following request to delete the indices created in this tutorial: ```console DELETE /books @@ -487,3 +477,12 @@ DELETE /my-explicit-mappings-books Deleting an index permanently deletes its documents, shards, and metadata. :::: + +## Learn more [full-text-filter-tutorial-learn-more] + +This tutorial introduced the basics of creating indices, adding data and performing basic searches with {{es}}. Following resources will help you understand {{es}} concepts better and dive into the basics of query languages for searching data: + +* [Fundamentals of Elasticsearch](../../manage-data/data-store.md) +* [Search and filter with Query DSL](querydsl-full-text-filter-tutorial.md) +* [Search using ES|QL](esql-search-tutorial.md) + diff --git a/solutions/search/esql-search-tutorial.md b/solutions/search/esql-search-tutorial.md index 918507211f..49b3efddb7 100644 --- a/solutions/search/esql-search-tutorial.md +++ b/solutions/search/esql-search-tutorial.md @@ -5,7 +5,7 @@ applies_to: navigation_title: Search and filter with ES|QL --- -# Tutorial: Search and filter with {{esql}} +# Search and filter with {{esql}} :::{tip} This tutorial presents examples in {{esql}} syntax. Refer to [the Query DSL version](querydsl-full-text-filter-tutorial.md) for the equivalent examples in Query DSL syntax. @@ -13,15 +13,13 @@ This tutorial presents examples in {{esql}} syntax. Refer to [the Query DSL vers This is a hands-on introduction to the basics of full-text search and semantic search, using [{{esql}}](/explore-analyze/query-filter/languages/esql.md). -For an overview of all the search capabilities in {{esql}}, refer to [Using {{esql}} for search](/solutions/search/esql-for-search.md). - In this scenario, we're implementing search for a cooking blog. The blog contains recipes with various attributes including textual content, categorical data, and numerical ratings. ## Requirements You need a running {{es}} cluster, together with {{kib}} to use the Dev Tools API Console. Refer to [choose your deployment type](/deploy-manage/deploy.md#choosing-your-deployment-type) for deployment options. -Want to get started quickly? Run the following command in your terminal to set up a [single-node local cluster in Docker](get-started.md): +Want to get started quickly? Run the following command in your terminal to set up a [single-node local cluster in Docker](run-elasticsearch-locally.md): ```sh curl -fsSL https://elastic.co/start-local | sh @@ -119,9 +117,9 @@ PUT /cooking_blog/_mapping } ``` -1. The `standard` analyzer is used by default for `text` fields if an `analyzer` isn't specified. It's included here for demonstration purposes. -2. [Multi-fields](elasticsearch://reference/elasticsearch/mapping-reference/multi-fields.md) are used here to index `text` fields as both `text` and `keyword` [data types](elasticsearch://reference/elasticsearch/mapping-reference/field-data-types.md). This enables both full-text search and exact matching/filtering on the same field. Note that if you used [dynamic mapping](../../manage-data/data-store/mapping/dynamic-field-mapping.md), these multi-fields would be created automatically. -3. The [`ignore_above` parameter](elasticsearch://reference/elasticsearch/mapping-reference/ignore-above.md) prevents indexing values longer than 256 characters in the `keyword` field. Again this is the default value, but it's included here for demonstration purposes. It helps to save disk space and avoid potential issues with Lucene's term byte-length limit. +1. `analyzer`: Used for text analysis. If you don't specify it, the `standard` analyzer is used by default for `text` fields. It’s included here for demonstration purposes. To know more about analyzers, refer [Anatomy of an analyzer](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/manage-data/data-store/text-analysis/anatomy-of-an-analyzer). +2. `ignore_above`: Prevents indexing values longer than 256 characters in the `keyword` field. This is the default value and it’s included here for demonstration purposes. It helps to save disk space and avoid potential issues with Lucene’s term byte-length limit. For more information, refer [ignore_above parameter](elasticsearch://reference/elasticsearch/mapping-reference/ignore-above.md). +3. `description`: A field declared with both `text` and `keyword` [data types](elasticsearch://reference/elasticsearch/mapping-reference/field-data-types.md). Such fields are called [Multi-fields](elasticsearch://reference/elasticsearch/mapping-reference/multi-fields.md). This enables both full-text search and exact matching/filtering on the same field. If you use [dynamic mapping](../../manage-data/data-store/mapping/dynamic-field-mapping.md), these multi-fields will be created automatically. Other fields in the mapping like `author`, `category`, `tags` are also declared as multi-fields. ::::{tip} Full-text search is powered by [text analysis](full-text/text-analysis-during-search.md). Text analysis normalizes and standardizes text data so it can be efficiently stored in an inverted index and searched in near real-time. Analysis happens at both [index and search time](../../manage-data/data-store/text-analysis/index-search-analysis.md). This tutorial won't cover analysis in detail, but it's important to understand how text is processed to create effective search queries. @@ -129,7 +127,7 @@ Full-text search is powered by [text analysis](full-text/text-analysis-during-se ## Step 2: Add sample blog posts to your index [full-text-filter-tutorial-index-data] -Now you’ll need to index some example blog posts using the [Bulk API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-settings). Note that `text` fields are analyzed and multi-fields are generated at index time. +Next, you’ll need to index some example blog posts using the [Bulk API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-settings). Note that `text` fields are analyzed and multi-fields are generated at index time. ```console POST /cooking_blog/_bulk?refresh=wait_for @@ -147,7 +145,7 @@ POST /cooking_blog/_bulk?refresh=wait_for ## Step 3: Basic search operations -Full-text search involves executing text-based queries across one or more document fields. In this section, we start with simple text matching and build up to understanding how search results are ranked. +Full-text search involves executing text-based queries across one or more document fields. In this section, you'll start with simple text matching and build up to understanding how search results are ranked. {{esql}} provides multiple functions for full-text search, including `MATCH`, `MATCH_PHRASE`, and `QSTR`. For basic text matching, you can use either: @@ -158,7 +156,7 @@ Both are equivalent for basic matching and can be used interchangeably. The comp Refer to the [`MATCH` function](elasticsearch://reference/query-languages/esql/functions-operators/search-functions.md#esql-match) reference docs for advanced parameters available with the function syntax. -### Make your first search query +### Perform your first search query Let's start with the simplest possible search - looking for documents that contain specific words: @@ -172,7 +170,7 @@ This query searches the `description` field for documents containing either "flu ### Control which fields appear in results -You can specify exactly which fields to include in your results using the `KEEP` command: +You can specify the exact fields to include in your results using the `KEEP` command: ```esql FROM cooking_blog @@ -185,7 +183,7 @@ This helps reduce the amount of data returned and focuses on the information you ### Understand relevance scoring -Search results can be ranked by how well they match your query. To calaculate and use relevance scores, you need to explicitly request the `_score` metadata: +Search results can be ranked based on how well they match your query. To calculate and use relevance scores, you need to explicitly request the `_score` metadata: ```esql FROM cooking_blog METADATA _score @@ -223,9 +221,9 @@ This is fundamentally different from full-text search - it's a binary yes/no fil ## Step 4: Search precision control -Now that you understand basic searching, let's explore how to control the precision of your text matches. +Now that you understand basic searching, explore how to control the precision of your text matches. -### Require all search terms (AND logic) +### Include all search terms (AND logic) By default, searches with match use OR logic between terms. To require ALL terms to match, use the function syntax with the `operator` parameter to specify AND logic: @@ -311,7 +309,7 @@ FROM cooking_blog ``` :::{tip} -Follow this [tutorial](/solutions/search/semantic-search/semantic-search-semantic-text.md) if you'd like to test out the semantic search workflow against a large dataset. +If you'd like to test out the semantic search workflow against a large dataset, follow the [semantic-search-tutorial](/solutions/search/semantic-search/semantic-search-semantic-text.md). ::: ### Perform hybrid search @@ -332,7 +330,7 @@ Learn how to combine these with complex criteria in [Step 8](#step-8-complex-sea ## Step 6: Advanced search features -Once you're comfortable with basic search precision, these advanced features give you powerful search capabilities. +Once you're comfortable with basic search precision, use the following advanced features for powerful search capabilities. ### Use query string for complex patterns @@ -470,7 +468,7 @@ FROM cooking_blog METADATA _score This tutorial introduced the basics of search and filtering in {{esql}}. Building a real-world search experience requires understanding many more advanced concepts and techniques. Here are some resources once you're ready to dive deeper: -- [Search with {{esql}}](esql-for-search.md): Learn about all your options for search use cases with {{esql}}. +- [Search with {{esql}}](esql-for-search.md): Learn about all the search capabilities in ES|QL, refer to Using ES|QL for search. {{esql}}. - [{{esql}} search functions](elasticsearch://reference/query-languages/esql/functions-operators/search-functions.md): Explore the full list of search functions available in {{esql}}. - [Semantic search](/solutions/search/semantic-search.md): Understand your various options for semantic search in Elasticsearch. - [The `semantic_text` workflow](/solutions/search/semantic-search.md#_semantic_text_workflow): Learn how to use the `semantic_text` field type for semantic search. This is the recommended approach for most users looking to perform semantic search in {{es}}, because it abstracts away the complexity of setting up inference endpoints and models. diff --git a/solutions/search/querydsl-full-text-filter-tutorial.md b/solutions/search/querydsl-full-text-filter-tutorial.md index ac9ad9b06c..c2523df86b 100644 --- a/solutions/search/querydsl-full-text-filter-tutorial.md +++ b/solutions/search/querydsl-full-text-filter-tutorial.md @@ -9,31 +9,31 @@ products: - id: elasticsearch --- -# Tutorial: Full-text search and filtering with Query DSL [full-text-filter-tutorial] +# Full-text search and filtering with Query DSL [full-text-filter-tutorial] :::{tip} This tutorial presents examples in Query DSL syntax. Refer to [the {{esql}} version](esql-search-tutorial.md) for the equivalent examples in {{esql}} syntax. ::: -This is a hands-on introduction to the basics of [full-text search](full-text.md) with {{es}}, also known as *lexical search*, using the [`_search` API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search) and [Query DSL](../../explore-analyze/query-filter/languages/querydsl.md). You’ll also learn how to filter data, to narrow down search results based on exact criteria. +This is a hands-on introduction to the basics of [full-text search](full-text.md) with {{es}}, also known as *lexical search*, using the [`_search` API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search) and [Query DSL](../../explore-analyze/query-filter/languages/querydsl.md). You’ll also learn how to filter data to narrow down search results based on exact criteria. -In this scenario, we’re implementing a search function for a cooking blog. The blog contains recipes with various attributes including textual content, categorical data, and numerical ratings. +In this quickstart, you’ll implement a search function for a cooking blog. The blog contains recipes with various attributes including textual content, categorical data, and numerical ratings. The goal is to create search queries that enable users to: -* Find recipes based on ingredients they want to use or avoid -* Discover dishes suitable for their dietary needs -* Find highly-rated recipes in specific categories -* Find recent recipes from their favorite authors +* Find recipes based on preferred or avoided ingredients +* Explore dishes that meet specific dietary needs +* Find top-rated recipes in specific categories +* Find the latest recipes from favorite authors -To achieve these goals we’ll use different Elasticsearch queries to perform full-text search, apply filters, and combine multiple search criteria. +To achieve these goals, you’ll use different Elasticsearch queries to perform full-text search, apply filters, and combine multiple search criteria. ## Requirements [full-text-filter-tutorial-requirements] You’ll need a running {{es}} cluster, together with {{kib}} to use the Dev Tools API Console. Refer to [choose your deployment type](/deploy-manage/deploy.md#choosing-your-deployment-type) for deployment options. -Want to get started quickly? Run the following command in your terminal to set up a [single-node local cluster in Docker](get-started.md): +Want to get started quickly? Run the following command in your terminal to set up a [single-node local cluster in Docker](run-elasticsearch-locally.md): ```sh curl -fsSL https://elastic.co/start-local | sh @@ -48,7 +48,7 @@ Create the `cooking_blog` index to get started: PUT /cooking_blog ``` -Now define the mappings for the index: +Next, define the mappings for the index: ```console PUT /cooking_blog/_mapping @@ -57,14 +57,14 @@ PUT /cooking_blog/_mapping "title": { "type": "text", "analyzer": "standard", <1> - "fields": { <2> + "fields": { "keyword": { "type": "keyword", - "ignore_above": 256 <3> + "ignore_above": 256 <2> } } }, - "description": { + "description": { <3> "type": "text", "fields": { "keyword": { @@ -107,9 +107,10 @@ PUT /cooking_blog/_mapping } ``` -1. The `standard` analyzer is used by default for `text` fields if an `analyzer` isn’t specified. It’s included here for demonstration purposes. -2. [Multi-fields](elasticsearch://reference/elasticsearch/mapping-reference/multi-fields.md) are used here to index `text` fields as both `text` and `keyword` [data types](elasticsearch://reference/elasticsearch/mapping-reference/field-data-types.md). This enables both full-text search and exact matching/filtering on the same field. Note that if you used [dynamic mapping](../../manage-data/data-store/mapping/dynamic-field-mapping.md), these multi-fields would be created automatically. -3. The [`ignore_above` parameter](elasticsearch://reference/elasticsearch/mapping-reference/ignore-above.md) prevents indexing values longer than 256 characters in the `keyword` field. Again this is the default value, but it’s included here for demonstration purposes. It helps to save disk space and avoid potential issues with Lucene’s term byte-length limit. +1. `analyzer`: Used for text analysis. If you don't specify it, the `standard` analyzer is used by default for `text` fields. It’s included here for demonstration purposes. To know more about analyzers, refer [Anatomy of an analyzer](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/manage-data/data-store/text-analysis/anatomy-of-an-analyzer). +2. `ignore_above`: Prevents indexing values longer than 256 characters in the `keyword` field. This is the default value and it’s included here for demonstration purposes. It helps to save disk space and avoid potential issues with Lucene’s term byte-length limit. For more information, refer [ignore_above parameter](elasticsearch://reference/elasticsearch/mapping-reference/ignore-above.md). +3. `description`: A field declared with both `text` and `keyword` [data types](elasticsearch://reference/elasticsearch/mapping-reference/field-data-types.md). Such fields are called [Multi-fields](elasticsearch://reference/elasticsearch/mapping-reference/multi-fields.md). This enables both full-text search and exact matching/filtering on the same field. If you use [dynamic mapping](../../manage-data/data-store/mapping/dynamic-field-mapping.md), these multi-fields will be created automatically. A few other fields in the mapping like `author`, `category`, `tags` are also declared as multi-fields. + ::::{tip} @@ -117,11 +118,9 @@ Full-text search is powered by [text analysis](full-text/text-analysis-during-se :::: - - ## Step 2: Add sample blog posts to your index [full-text-filter-tutorial-index-data] -Now you’ll need to index some example blog posts using the [Bulk API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-settings). Note that `text` fields are analyzed and multi-fields are generated at index time. +Next, you’ll need to index some example blog posts using the [Bulk API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-bulk). Note that `text` fields are analyzed and multi-fields are generated at index time. ```console POST /cooking_blog/_bulk?refresh=wait_for @@ -143,7 +142,7 @@ POST /cooking_blog/_bulk?refresh=wait_for Full-text search involves executing text-based queries across one or more document fields. These queries calculate a relevance score for each matching document, based on how closely the document’s content aligns with the search terms. {{es}} offers various query types, each with its own method for matching text and [relevance scoring](../../explore-analyze/query-filter/languages/querydsl.md#relevance-scores). -### `match` query [_match_query] +### Use `match` query [_match_query] The [`match`](elasticsearch://reference/query-languages/query-dsl/query-dsl-match-query.md) query is the standard query for full-text, or "lexical", search. The query text will be analyzed according to the analyzer configuration specified on each field (or at query time). @@ -208,9 +207,9 @@ At search time, {{es}} defaults to the analyzer defined in the field mapping. In } ``` -1. The `hits` object contains the total number of matching documents and their relation to the total. -2. `max_score` is the highest relevance score among all matching documents. In this example, we only have one matching document. -3. `_score` is the relevance score for a specific document, indicating how well it matches the query. Higher scores indicate better matches. In this example the `max_score` is the same as the `_score`, as there is only one matching document. +1. `hits`: Contains the total number of matching documents and their relation to the total. +2. `max_score`: The highest relevance score among all matching documents. In this example, we only have one matching document. +3. `_score`: The relevance score for a specific document, indicating how well it matches the query. Higher scores indicate better matches. In this example the `max_score` is the same as the `_score`, as there is only one matching document. 4. The title contains both "Fluffy" and "Pancakes", matching our search terms exactly. 5. The description includes "fluffiest" and "pancakes", further contributing to the document’s relevance due to the analysis process. @@ -219,9 +218,9 @@ At search time, {{es}} defaults to the analyzer defined in the field mapping. In -### Require all terms in a match query [_require_all_terms_in_a_match_query] +### Include all terms match in a query [_require_all_terms_in_a_match_query] -Specify the `and` operator to require both terms in the `description` field. This stricter search returns *zero hits* on our sample data, as no document contains both "fluffy" and "pancakes" in the description. +Specify the `and` operator to include both terms in the `description` field. This stricter search returns *zero hits* on our sample data, as no document contains both "fluffy" and "pancakes" in the description. ```console GET /cooking_blog/_search @@ -322,10 +321,7 @@ GET /cooking_blog/_search * `description^2`: The description is 2 times more important * `tags`: No boost applied (equivalent to `^1`) - These boosts help tune relevance, prioritizing matches in the title over the description, and matches in the description over tags. - - - + These boosts help tune relevance, prioritizing matches in the title over the description, and matches in the description over tags. Learn more about fields and per-field boosting in the [`multi_match` query](elasticsearch://reference/query-languages/query-dsl/query-dsl-multi-match-query.md) reference. @@ -392,7 +388,7 @@ The `multi_match` query is often recommended over a single `match` query for mos [Filtering](../../explore-analyze/query-filter/languages/querydsl.md#filter-context) allows you to narrow down your search results based on exact criteria. Unlike full-text searches, filters are binary (yes/no) and do not affect the relevance score. Filters execute faster than queries because excluded results don’t need to be scored. -This [`bool`](elasticsearch://reference/query-languages/query-dsl/query-dsl-bool-query.md) query will return only blog posts in the "Breakfast" category. +The following [`bool`](elasticsearch://reference/query-languages/query-dsl/query-dsl-bool-query.md) query will return blog posts only in the "Breakfast" category. ```console GET /cooking_blog/_search @@ -422,7 +418,7 @@ The `.keyword` suffix accesses the unanalyzed version of a field, enabling exact ### Search for posts within a date range [full-text-filter-tutorial-range-query] -Often users want to find content published within a specific time frame. A [`range`](elasticsearch://reference/query-languages/query-dsl/query-dsl-range-query.md) query finds documents that fall within numeric or date ranges. +Users often want to find content published within a specific time frame. A [`range`](elasticsearch://reference/query-languages/query-dsl/query-dsl-range-query.md) query finds documents that fall within numeric or date ranges. ```console GET /cooking_blog/_search @@ -438,8 +434,8 @@ GET /cooking_blog/_search } ``` -1. Greater than or equal to May 1, 2023. -2. Less than or equal to May 31, 2023. +1. `gte`: Greater than or equal to May 1, 2023. +2. `lte`: Less than or equal to May 31, 2023. @@ -447,7 +443,7 @@ GET /cooking_blog/_search Sometimes users want to search for exact terms to eliminate ambiguity in their search results. A [`term`](elasticsearch://reference/query-languages/query-dsl/query-dsl-term-query.md) query searches for an exact term in a field without analyzing it. Exact, case-sensitive matches on specific terms are often referred to as "keyword" searches. -Here you’ll search for the author "Maria Rodriguez" in the `author.keyword` field. +In the following example, you’ll search for the author "Maria Rodriguez" in the `author.keyword` field. ```console GET /cooking_blog/_search @@ -460,7 +456,7 @@ GET /cooking_blog/_search } ``` -1. The `term` query has zero flexibility. For example, here the queries `maria` or `maria rodriguez` would have zero hits, due to case sensitivity. +1. The `term` query has zero flexibility. For example, if the `author.keyword` contains words `maria` or `maria rodriguez`, the query will have zero hits, due to case sensitivity. ::::{tip} @@ -472,7 +468,7 @@ Avoid using the `term` query for [`text` fields](elasticsearch://reference/elast ## Step 6: Combine multiple search criteria [full-text-filter-tutorial-complex-bool] -A [`bool`](elasticsearch://reference/query-languages/query-dsl/query-dsl-bool-query.md) query allows you to combine multiple query clauses to create sophisticated searches. In this tutorial scenario it’s useful for when users have complex requirements for finding recipes. +A [`bool`](elasticsearch://reference/query-languages/query-dsl/query-dsl-bool-query.md) query allows you to combine multiple query clauses to create sophisticated searches. In this tutorial, it’s useful when users have complex requirements for finding recipes. Let’s create a query that addresses the following user needs: @@ -533,7 +529,7 @@ GET /cooking_blog/_search } ``` -1. The `must_not` clause excludes documents that match the specified criteria. This is a powerful tool for filtering out unwanted results. +1. `must_not`: Excludes documents that match the specified criteria. This is a powerful tool for filtering out unwanted results. ::::{dropdown} Example response @@ -592,9 +588,10 @@ GET /cooking_blog/_search ## Learn more [full-text-filter-tutorial-learn-more] -This tutorial introduced the basics of full-text search and filtering in {{es}}. Building a real-world search experience requires understanding many more advanced concepts and techniques. Here are some resources once you’re ready to dive deeper: +This tutorial introduced the basics of full-text search and filtering in {{es}}. Building a real-world search experience requires understanding many more advanced concepts and techniques. Following resources will help you dive deeper: * [Full-text search](full-text.md): Learn about the core components of full-text search in {{es}}. * [Elasticsearch basics — Search and analyze data](../../explore-analyze/query-filter.md): Understand all your options for searching and analyzing data in {{es}}. * [Text analysis](full-text/text-analysis-during-search.md): Understand how text is processed for full-text search. -* [Search your data](../search.md): Learn about more advanced search techniques using the `_search` API, including semantic search. \ No newline at end of file +* [Search your data](../search.md): Learn about more advanced search techniques using the `_search` API, including semantic search. +* [Sear] \ No newline at end of file