From a07b9fcbfc49b8f59d466e2fc7f51aedae26b13f Mon Sep 17 00:00:00 2001 From: danielle9897 Date: Wed, 25 Sep 2024 10:56:37 +0300 Subject: [PATCH 1/6] RDoc-3052 small text fixes --- .../indexes/querying/searching.dotnet.markdown | 2 +- .../indexes/querying/searching.js.markdown | 2 +- .../indexes/querying/suggestions.dotnet.markdown | 2 +- .../indexes/querying/suggestions.js.markdown | 2 +- .../ClientApi/Session/Querying/TextSearch/FullTextSearch.cs | 6 +++--- .../indexes/querying/highlighting.dotnet.markdown | 5 ++--- .../indexes/querying/highlighting.js.markdown | 5 ++--- .../indexes/querying/highlighting.python.markdown | 5 ++--- .../indexes/querying/projections.python.markdown | 3 +-- .../indexes/querying/query-index.dotnet.markdown | 3 +-- .../indexes/querying/query-index.js.markdown | 5 ++--- .../indexes/querying/query-index.python.markdown | 5 ++--- .../indexes/querying/searching.dotnet.markdown | 4 +--- .../indexes/querying/searching.js.markdown | 5 ++--- .../indexes/querying/searching.python.markdown | 5 ++--- .../indexes/querying/suggestions.dotnet.markdown | 5 ++--- .../indexes/querying/suggestions.js.markdown | 5 ++--- .../indexes/querying/suggestions.python.markdown | 5 ++--- .../ClientApi/Session/Querying/TextSearch/FullTextSearch.cs | 6 +++--- .../indexes/querying/projections.dotnet.markdown | 3 +-- .../indexes/querying/projections.js.markdown | 3 +-- 21 files changed, 35 insertions(+), 51 deletions(-) diff --git a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown index fecfd0e564..b70903e162 100644 --- a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown +++ b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown @@ -3,7 +3,7 @@ {NOTE: } -* __Prior to this article__, please refer to article [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) +* __Prior to this article__, please refer to [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) to learn about the `Search` method. * __All capabilities__ provided by `Search` with a dynamic query can also be used when querying a static-index. diff --git a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.js.markdown b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.js.markdown index 04e278af1f..e3a54d6d3e 100644 --- a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.js.markdown +++ b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/searching.js.markdown @@ -3,7 +3,7 @@ {NOTE: } -* __Prior to this article__, please refer to article [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) +* __Prior to this article__, please refer to [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) to learn about the `search` method. * __All capabilities__ provided by `search` with a dynamic query can also be used when querying a static-index. diff --git a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown index bf2d7620cc..054df3709f 100644 --- a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown +++ b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown @@ -4,7 +4,7 @@ {NOTE: } -* Prior to this article, please refer to article [Query for Suggestions](../../client-api/session/querying/how-to-work-with-suggestions) +* Prior to this article, please refer to [Query for Suggestions](../../client-api/session/querying/how-to-work-with-suggestions) for general knowledge about Suggestions, and for dynamic-queries examples. * In addition to getting suggested terms when making a dynamic-query, diff --git a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown index 23de769efc..b36a084f59 100644 --- a/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown +++ b/Documentation/5.2/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown @@ -4,7 +4,7 @@ {NOTE: } -* Prior to this article, please refer to article [Query for Suggestions](../../client-api/session/querying/how-to-work-with-suggestions) +* Prior to this article, please refer to [Query for Suggestions](../../client-api/session/querying/how-to-work-with-suggestions) for general knowledge about Suggestions, and for dynamic-queries examples. * In addition to getting suggested terms when making a dynamic-query, diff --git a/Documentation/5.2/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs b/Documentation/5.2/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs index e93899553e..428026faf9 100644 --- a/Documentation/5.2/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs +++ b/Documentation/5.2/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs @@ -598,7 +598,7 @@ public async Task Examples() #region fts_33 List employees = session .Query() - // Use '*' to replace one ore more characters + // Use '*' to replace one or more characters .Search(x => x.Notes, "art*") .Search(x => x.Notes, "*logy") .Search(x => x.Notes, "*mark*") @@ -618,7 +618,7 @@ public async Task Examples() #region fts_34 List employees = await asyncSession .Query() - // Use '*' to replace one ore more characters + // Use '*' to replace one or more characters .Search(x => x.Notes, "art*") .Search(x => x.Notes, "*logy") .Search(x => x.Notes, "*mark*") @@ -638,7 +638,7 @@ public async Task Examples() #region fts_35 List employees = session.Advanced .DocumentQuery() - // Use '*' to replace one ore more characters + // Use '*' to replace one or more characters .Search(x => x.Notes, "art*") .Search(x => x.Notes, "*logy") .Search(x => x.Notes, "*mark*") diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.dotnet.markdown index 3d9fee8aa3..709b3960e3 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.dotnet.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.dotnet.markdown @@ -8,9 +8,8 @@ also request to get a list of text fragments that highlight the searched terms. * This article provides examples of highlighting search results when querying a static-index. - Prior to reading this article, it is recommended to take a look at the - [Highlight search results](../../client-api/session/querying/text-search/highlight-query-results) - article for general knowledge about Highlighting and for dynamic-queries examples. + Prior to reading this article, please refer to [Highlight search results](../../client-api/session/querying/text-search/highlight-query-results) + for general knowledge about Highlighting and for dynamic-queries examples. * To search and get fragments with highlighted terms when querying a static-index, the index field on which you search must be configured for highlighting. See examples below. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.js.markdown index 16a1452cd1..9e0cf9148e 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.js.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.js.markdown @@ -8,9 +8,8 @@ also request to get a list of text fragments that highlight the searched terms. * This article provides examples of highlighting search results when querying a static-index. - Prior to reading this article, it is recommended to take a look at the - [Highlight search results](../../client-api/session/querying/text-search/highlight-query-results) - article for general knowledge about Highlighting and for dynamic-queries examples. + Prior to reading this article, please refer to [Highlight search results](../../client-api/session/querying/text-search/highlight-query-results) + for general knowledge about Highlighting and for dynamic-queries examples. * To search and get fragments with highlighted terms when querying a static-index, the index field on which you search must be configured for highlighting. See examples below. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.python.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.python.markdown index bac226098c..fe206193dd 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.python.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/highlighting.python.markdown @@ -8,9 +8,8 @@ also request to get a list of text fragments that highlight the searched terms. * This article provides examples of highlighting search results when querying a static-index. - Prior to reading this article, it is recommended to take a look at the - [Highlight search results](../../client-api/session/querying/text-search/highlight-query-results) - article for general knowledge about Highlighting and for dynamic-queries examples. + Prior to reading this article, please refer to [Highlight search results](../../client-api/session/querying/text-search/highlight-query-results) + for general knowledge about Highlighting and for dynamic-queries examples. * To search and get fragments with highlighted terms when querying a static-index, the index field on which you search must be configured for highlighting. See examples below. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/projections.python.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/projections.python.markdown index fbc3ff2877..3f7362c4d1 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/projections.python.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/projections.python.markdown @@ -5,8 +5,7 @@ * This article provides examples of projecting query results when querying a **static-index**. -* Prior to reading this article, it is recommended to take a look at the - [query results projection Overview](../../client-api/session/querying/how-to-project-query-results) +* Prior to reading this article, please refer to [query results projection overview](../../client-api/session/querying/how-to-project-query-results) for general knowledge about Projections and for dynamic-queries examples. * Projections can be applied using the `select_fields` and `select_fields_query_data` methods. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.dotnet.markdown index 8c02866cd6..73d3fb4d50 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.dotnet.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.dotnet.markdown @@ -4,8 +4,7 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Query Overview](../../client-api/session/querying/how-to-query). +* Prior to this article, it is recommended that you first read this [Query Overview](../../client-api/session/querying/how-to-query). * For a basic indexes overview, see the [Indexes Overview](../../studio/database/indexes/indexes-overview). diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.js.markdown index 5a8cb02a29..aff21c18ab 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.js.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.js.markdown @@ -4,9 +4,8 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Query Overview](../../client-api/session/querying/how-to-query). - +* Prior to this article, it is recommended that you first read this [Query Overview](../../client-api/session/querying/how-to-query). + * For a basic indexes overview, see the [Indexes Overview](../../studio/database/indexes/indexes-overview). --- diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.python.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.python.markdown index c17490029d..03fd6d08af 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.python.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/query-index.python.markdown @@ -4,9 +4,8 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Query Overview](../../client-api/session/querying/how-to-query). - +* Prior to this article, it is recommended that you first read this [Query Overview](../../client-api/session/querying/how-to-query). + * For a basic indexes overview, see the [Indexes Overview](../../studio/database/indexes/indexes-overview). --- diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown index 748c1670d9..89bac02e5f 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown @@ -3,9 +3,7 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) - article to learn about the `Search` method. +* Prior to this article, please refer to [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) to learn about the `Search` method. * **All capabilities** provided by `Search` with a dynamic query can also be used when querying a static-index. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.js.markdown index e1a46a7995..0dfc359c81 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.js.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.js.markdown @@ -3,9 +3,8 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) - article to learn about the `search` method. +* Prior to reading this article, please refer to [full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) + to learn about the `search` method. * **All capabilities** provided by `search` with a dynamic query can also be used when querying a static-index. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.python.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.python.markdown index cfc4acc13a..01beaec7d8 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.python.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/searching.python.markdown @@ -3,9 +3,8 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) - article to learn about the `search` method. +* Prior to reading this article, please refer to [full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) + to learn about the `search` method. * **All capabilities** provided by `search` with a dynamic query can also be used when querying a static-index. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown index 2b72414e3c..59deabdc35 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.dotnet.markdown @@ -4,9 +4,8 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Query for Suggestions](../../client-api/session/querying/how-to-work-with-suggestions) - article for general knowledge about Suggestions and for dynamic-queries examples. +* Prior to reading this article, please refer to [query for suggestions](../../client-api/session/querying/how-to-work-with-suggestions) + for general knowledge about Suggestions and for dynamic-queries examples. * In addition to getting suggested terms when making a dynamic-query, you can query for similar terms when querying an index. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown index 883e04a8ce..56151556e8 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.js.markdown @@ -4,9 +4,8 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Query for Suggestions](../../client-api/session/querying/how-to-work-with-suggestions) - article for general knowledge about Suggestions and for dynamic-queries examples. +* Prior to reading this article, please refer to [query for suggestions](../../client-api/session/querying/how-to-work-with-suggestions) + for general knowledge about Suggestions and for dynamic-queries examples. * In addition to getting suggested terms when making a dynamic-query, you can query for similar terms when querying an index. diff --git a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.python.markdown b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.python.markdown index f27c37d319..1014002496 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.python.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/indexes/querying/suggestions.python.markdown @@ -4,9 +4,8 @@ {NOTE: } -* Prior to reading this article, it is recommended to take a look at the - [Query for Suggestions](../../client-api/session/querying/how-to-work-with-suggestions) - article for general knowledge about Suggestions and for dynamic-queries examples. +* Prior to reading this article, please refer to [query for suggestions](../../client-api/session/querying/how-to-work-with-suggestions) + for general knowledge about Suggestions and for dynamic-queries examples. * In addition to getting suggested terms when making a dynamic-query, you can query for similar terms when querying an index. diff --git a/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs b/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs index e93899553e..428026faf9 100644 --- a/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs +++ b/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/ClientApi/Session/Querying/TextSearch/FullTextSearch.cs @@ -598,7 +598,7 @@ public async Task Examples() #region fts_33 List employees = session .Query() - // Use '*' to replace one ore more characters + // Use '*' to replace one or more characters .Search(x => x.Notes, "art*") .Search(x => x.Notes, "*logy") .Search(x => x.Notes, "*mark*") @@ -618,7 +618,7 @@ public async Task Examples() #region fts_34 List employees = await asyncSession .Query() - // Use '*' to replace one ore more characters + // Use '*' to replace one or more characters .Search(x => x.Notes, "art*") .Search(x => x.Notes, "*logy") .Search(x => x.Notes, "*mark*") @@ -638,7 +638,7 @@ public async Task Examples() #region fts_35 List employees = session.Advanced .DocumentQuery() - // Use '*' to replace one ore more characters + // Use '*' to replace one or more characters .Search(x => x.Notes, "art*") .Search(x => x.Notes, "*logy") .Search(x => x.Notes, "*mark*") diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.dotnet.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.dotnet.markdown index 2f5a602cee..0f264f77c9 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.dotnet.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.dotnet.markdown @@ -5,8 +5,7 @@ * This article provides examples of projecting query results when querying a **static-index**. -* Prior to reading this article, it is recommended to take a look at the - [query results projection Overview](../../client-api/session/querying/how-to-project-query-results) +* Prior to reading this article, please refer to [query results projection overview](../../client-api/session/querying/how-to-project-query-results) for general knowledge about Projections and for dynamic-queries examples. * In this page: diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.js.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.js.markdown index 58e25e536f..7fad35330f 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.js.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/projections.js.markdown @@ -5,8 +5,7 @@ * This article provides examples of projecting query results when querying a **static-index**. -* Prior to reading this article, it is recommended to take a look at the - [query results projection Overview](../../client-api/session/querying/how-to-project-query-results) +* Prior to reading this article, please refer to [query results projection overview](../../client-api/session/querying/how-to-project-query-results) for general knowledge about Projections and for dynamic-queries examples. * In this page: From 435e03a2cbc7235df4e82574019d84bff0d52838 Mon Sep 17 00:00:00 2001 From: danielle9897 Date: Wed, 25 Sep 2024 18:03:10 +0300 Subject: [PATCH 2/6] RDoc-3052 The breaking changes page for 6.0 --- .../server/server-breaking-changes.markdown | 149 +++++++++++++++--- 1 file changed, 127 insertions(+), 22 deletions(-) diff --git a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown index b193a5eb41..1421ae35cd 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown @@ -1,24 +1,129 @@ # Migration: Server Breaking Changes +--- -The following features, that were available in former RavenDB versions, -are unavailable under RavenDB `6.x` or incompatible with their previous versions. - -* **License Keys** - License keys for versions lower than `6.0` are **not supported** by RavenDB `6.0`. - If you own a valid license key for RavenDB `5.x` or lower, please upgrade it using - the quick online interface [described here](../../start/licensing/replace-license#upgrade-a-license-key-for-ravendb-6.x). -* **RavenDB for Docker** - RavenDB now applies an improved security model, and uses a **dedicated user** rather than `root`. - Read more about this change [here](../../migration/server/docker). -* **Unsupported sharding features** - RavenDB 6.0 introduces [sharding](../../sharding/overview). Server and Client features - that are currently unavailable under a sharded database (but remain available in regular - databases) are listed [here](../../sharding/unsupported). -* [Graph Queries](https://ravendb.net/docs/article-page/5.4/csharp/indexes/querying/graph/graph-queries-overview) - Graph queries support, available in RavenDB versions `4.2` to `5.x`, is removed from - RavenDB `6.x` server and client API. -* **ETL** - SQL ETL no longer tolerates errors on `Load`: load errors are thrown immediately, to distinguish - partial load errors that are used in SQL ETL from, for example, commit errors that may happen - during load. (Prior to this change ETL would just advance instead of retrying.) -* `DateOnly` and `TimeOnly` are now supported for every new auto index. +{NOTE: } + +* The following features and behaviors that were available in previous versions of RavenDB + are either unavailable in RavenDB `6.x` or incompatible with those earlier versions. + +* In this page: + * [License keys](../../migration/server/server-breaking-changes#license-keys) + * [RavenDB for Docker](../../migration/server/server-breaking-changes#ravendb-for-docker) + * [Unsupported sharding features](../../migration/server/server-breaking-changes#unsupported-sharding-features) + * [Graph queries](../../migration/server/server-breaking-changes#graph-queries) + * [SQL ETL](../../migration/server/server-breaking-changes#sql-etl) + * [DateOnly & TimeOnly](../../migration/server/server-breaking-changes#dateonly-&-timeonly) + * [Full-text search with wildcards](../../migration/server/server-breaking-changes#full-text-search-with-wildcards) + +{NOTE/} + +--- + +{PANEL: License keys} + +License keys for versions lower than `6.0` are **not supported** by RavenDB `6.0`. +If you own a valid license key for RavenDB `5.x` or lower, please upgrade it using +the quick online interface described [here](../../start/licensing/replace-license#upgrade-a-license-key-for-ravendb-6.x). + +{PANEL/} + +{PANEL: RavenDB for Docker} + +RavenDB now applies an improved security model, and uses a **dedicated user** rather than `root`. +Read more about this change [here](../../migration/server/docker). + +{PANEL/} + +{PANEL: Unsupported sharding features} + +RavenDB `6.0` introduces [sharding](../../sharding/overview). +Server and client features that are currently unavailable in a sharded database (but remain available in regular databases) are listed [here](../../sharding/unsupported). + +{PANEL/} + +{PANEL: Graph queries} + +[Graph Queries](https://ravendb.net/docs/article-page/5.4/csharp/indexes/querying/graph/graph-queries-overview) support, +available in RavenDB versions `4.2` to `5.x`, has been removed from the RavenDB `6.x` server and client API. + +{PANEL/} + +{PANEL: SQL ETL} + +SQL ETL no longer tolerates errors on `Load`, load errors are thrown immediately. +This is done to distinguish partial load errors that are used in SQL ETL from, for example, commit errors that may happen during load. +(Prior to this change, the ETL would just advance instead of retrying.) + +{PANEL/} + +{PANEL: DateOnly & TimeOnly} + +[DateOnly and TimeOnly](../../client-api/how-to/using-timeonly-and-dateonly) types are now supported for every new auto index. + +{PANEL/} + +{PANEL: Full-text search with wildcards} + +Starting with `6.0` we have changed how the [Search method](../../indexes/querying/searching) handles wildcards when they are included in search terms: + +##### Behavior for versions lower than `6.0`: + +After the analyzer stripped wildcards from the search term, +RavenDB would attempt to restore the `*` to their original positions before sending the term to the search engine (Lucene or Corax). + +##### Behavior for `6.0` and up: + +Once wildcards are stripped by the analyzer, we no longer add them back before sending the term to the search engine. +The search terms sent to the search engine are solely based on the transformations applied by the analyzer used. + +Note the different behavior in the following cases: + +{NOTE: } + +**When using `StandardAnalyzer` or `NGramAnalyzer`**: + +--- + +Usually, the same analyzer used to tokenize field content at **indexing time** is also used to process the terms provided in the **full-text search query** +before they are sent to the search engine to retrieve matching documents. + +However, in the following cases: + +* When making a [dynamic search query](../../client-api/session/querying/text-search/full-text-search) +* or when querying a static index that uses the default `StandardAnalyzer` +* or when querying a static index that uses the `NGramAnalyzer` + +the queried terms in the `Search` method are processed with the **`LowerCaseKeywordAnalyzer`** analyzer before being sent to the search engine. + +This analyzer does Not remove the `*`, so the terms are sent with `*` as provided in the search terms. + +{NOTE/} +{NOTE: } + +**When using a Custom Analyzer**: + +--- + +When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, +then when querying the index, the search terms in the query will be processed according to the custom analyzer's logic. + +The `*` will remain in the terms if the custom analyzer allows it. +It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. + +{NOTE/} +{NOTE: } + +**When using the Exact Analyzer:** + +--- + +When using `KeywordAnalyzer`(the default Exact analyzer) in your index, +then when querying the index, the wildcards in your query terms remain untouched, the terms are sent to the search engine exactly as prepared by the analyzer. + +{NOTE/} + +--- + +See behavior example in [here](../../todo..). + +{PANEL/} From 60f972cef2f6f876e161e92d1b4c4a2ed0c53e79 Mon Sep 17 00:00:00 2001 From: danielle9897 Date: Sun, 6 Oct 2024 21:19:27 +0300 Subject: [PATCH 3/6] RDoc-3052 Add text & examples to the Full-Text Search page (C#) --- .../querying/searching.dotnet.markdown | 203 +++++++ .../indexes/querying/searching.js.markdown | 98 +++ .../querying/searching.python.markdown | 98 +++ .../server/server-breaking-changes.markdown | 57 +- .../Indexes/Querying/Searching.cs | 571 ++++++++++++++++++ .../nodejs/indexes/querying/searching.js | 98 +++ .../python/Indexes/Querying/Searching.py | 110 ++++ 7 files changed, 1187 insertions(+), 48 deletions(-) create mode 100644 Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown create mode 100644 Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown create mode 100644 Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.python.markdown create mode 100644 Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs create mode 100644 Documentation/6.0/Samples/nodejs/indexes/querying/searching.js create mode 100644 Documentation/6.0/Samples/python/Indexes/Querying/Searching.py diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown new file mode 100644 index 0000000000..3f1676344a --- /dev/null +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown @@ -0,0 +1,203 @@ +# Full-Text Search with Index +--- + +{NOTE: } + +* Prior to this article, please refer to [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) to learn about the `Search` method. + +* **All capabilities** provided by `Search` with a dynamic query can also be used when querying a static-index. + +* However, as opposed to making a dynamic search query where an auto-index is created for you, + when using a **static-index**: + + * You must configure the index-field in which you want to search. + See examples below. + + * You can configure which analyzer will be used to tokenize this field. + See [selecting an analyzer](../../indexes/using-analyzers#selecting-an-analyzer-for-a-field). + +--- + +* In this page: + * [Indexing single field for FTS](../../indexes/querying/searching#indexing-single-field-for-fts) + * [Indexing multiple fields for FTS](../../indexes/querying/searching#indexing-multiple-fields-for-fts) + * [Boosting search results](../../indexes/querying/searching#boosting-search-results) + * [Searching with wildcards](../../indexes/querying/searching#searching-with-wildcards) + * [When using StandardAnalyzer or NGramAnalyzer](../../indexes/querying/searching#when-usingor) + * [When using a custom analyzer](../../indexes/querying/searching#when-using-a-custom-analyzer) + * [When using the Exact analyzer](../../indexes/querying/searching#when-using-the-exact-analyzer) + +{NOTE/} + +--- + +{PANEL: Indexing single field for FTS} + +#### The index: + +{CODE:csharp index_1@Indexes\Querying\Searching.cs/} + +--- + +#### Query with Search: + +* Use `Search` to make a full-text search when querying the index. + +* Refer to [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) for all available **Search options**, + such as using wildcards, searching for multiple terms, etc. + +{CODE-TABS} +{CODE-TAB:csharp:Query search_1@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query_async search_2@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:DocumentQuery search_3@Indexes\Querying\Searching.cs /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes" +where search(EmployeeNotes, "French") +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{PANEL/} + +{PANEL: Indexing multiple fields for FTS} + +#### The index: + +{CODE:csharp index_2@Indexes\Querying\Searching.cs/} + +--- + +#### Sample query: + +{CODE-TABS} +{CODE-TAB:csharp:Query search_4@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query_async search_5@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:DocumentQuery search_6@Indexes\Querying\Searching.cs /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByEmployeeData" +where (search(EmployeeData, "Manager") or search(EmployeeData, "French Spanish", and)) +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{PANEL/} + +{PANEL: Boosting search results} + +* In order to prioritize results, you can provide a boost value to the searched terms. + This can be applied by either of the following: + + * Add a boost value to the relevant index-field **inside the index definition**. + Refer to article [indexes - boosting](../../indexes/boosting). + + * Add a boost value to the queried terms **at query time**. + Refer to article [Boost search results](../../client-api/session/querying/text-search/boost-search-results). + +{PANEL/} + +{PANEL: Searching with wildcards} + +* When making a full-text search with wildcards in the search terms, + the presence of wildcards (`*`) in the terms sent to the search engine is determined by the transformations applied by the + [analyzer](../../indexes/using-analyzers) used in the index. + +* Note the different behavior in the following cases: + * [When using StandardAnalyzer or NGramAnalyzer](../../indexes/querying/searching#when-usingor) + * [When using a custom analyzer](../../indexes/querying/searching#when-using-a-custom-analyzer) + * [When using the Exact analyzer](../../indexes/querying/searching#when-using-the-exact-analyzer) + +--- + +{NOTE: } + +##### When using `StandardAnalyzer` or `NGramAnalyzer`: +--- + +Usually, the same analyzer used to tokenize field content at **indexing time** is also used to process the terms provided in the **full-text search query** +before they are sent to the search engine to retrieve matching documents. + +**However, in the following cases**: + +* When making a [dynamic search query](../../client-api/session/querying/text-search/full-text-search) +* or when querying a static index that uses the default `StandardAnalyzer` +* or when querying a static index that uses the `NGramAnalyzer` + +the queried terms in the _Search_ method are processed with the **`LowerCaseKeywordAnalyzer`** before being sent to the search engine. + +This analyzer does Not remove the `*`, so the terms are sent with `*` as provided in the search terms. +For example: + +{CODE-TABS} +{CODE-TAB:csharp:Index index_3@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query search_7@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query_async search_8@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:DocumentQuery search_9@Indexes\Querying\Searching.cs /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes/usingDefaultAnalyzer" +where search(EmployeeNotes, "*rench") +include explanations() +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{NOTE/} +{NOTE: } + +##### When using a custom analyzer: +--- + +When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, +then when querying the index, the search terms in the query will be processed according to the custom analyzer's logic. + +The `*` will remain in the terms if the custom analyzer allows it. +It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. + +For example: + +{CODE-TABS} +{CODE-TAB:csharp:Index index_4@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Custom_analyzer analyzer_1@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query search_10@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query_async search_11@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:DocumentQuery search_12@Indexes\Querying\Searching.cs /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes/UsingCustomAnalyzer" +where search(EmployeeNotes, "*French*") +include explanations() +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{NOTE/} +{NOTE: } + +##### When using the Exact analyzer: +--- + +When using the default Exact analyzer in your index (which is `KeywordAnalyzer`), +then when querying the index, the wildcards in your search terms remain untouched. +The terms are sent to the search engine exactly as produced by the analyzer. + +For example: + +{CODE-TABS} +{CODE-TAB:csharp:Index index_5@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query search_13@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:Query_async search_14@Indexes\Querying\Searching.cs /} +{CODE-TAB:csharp:DocumentQuery search_15@Indexes\Querying\Searching.cs /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes/usingExactAnalyzer" +where search(FirstName, "Mich*") +include explanations() +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{NOTE/} +{PANEL/} + +## Related Articles + +### Client API + +- [Full-Text search](../../client-api/session/querying/text-search/full-text-search) + +### Indexes + +- [Analyzers](../../indexes/using-analyzers) +- [Boosting](../../indexes/boosting) diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown new file mode 100644 index 0000000000..0dfc359c81 --- /dev/null +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown @@ -0,0 +1,98 @@ +# Full-Text Search with Index +--- + +{NOTE: } + +* Prior to reading this article, please refer to [full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) + to learn about the `search` method. + +* **All capabilities** provided by `search` with a dynamic query can also be used when querying a static-index. + +* However, as opposed to making a dynamic search query where an auto-index is created for you, + when using a **static-index**: + + * You must configure the index-field in which you want to search. + See examples below. + + * You can configure which analyzer will be used to tokenize this field. + See [selecting an analyzer](../../indexes/using-analyzers#selecting-an-analyzer-for-a-field). + +--- + +* In this page: + * [Indexing single field for FTS](../../indexes/querying/searching#indexing-single-field-for-fts) + * [Indexing multiple fields for FTS](../../indexes/querying/searching#indexing-multiple-fields-for-fts) + * [Boosting search results](../../indexes/querying/searching#boosting-search-results) + +{NOTE/} + +--- + +{PANEL: Indexing single field for FTS} + +#### The index: + +{CODE:nodejs index_1@Indexes\Querying\searching.js/} + +--- + +#### Query with Search: + +* Using the `search` method has the advantage of using any of its functionalities, + such as using wildcards, searching for multiple terms, etc. + +* Refer to [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) for all available **Search options**. + +{CODE-TABS} +{CODE-TAB:nodejs:Query search_1@Indexes\Querying\searching.js /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes" +where search(employeeNotes, "French") +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{PANEL/} + +{PANEL: Indexing multiple fields for FTS} + +#### The index: + +{CODE:nodejs index_2@Indexes\Querying\searching.js/} + +--- + +#### Sample query: + +{CODE-TABS} +{CODE-TAB:nodejs:Query search_2@Indexes\Querying\searching.js /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByEmployeeData" +where (search(employeeData, "Manager") or search(employeeData, "French Spanish", and)) +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{PANEL/} + +{PANEL: Boosting search results} + +* In order to prioritize results, you can provide a boost value to the searched terms. + This can be applied by either of the following: + + * Add a boost value to the relevant index-field **inside the index definition**. + Refer to article [indexes - boosting](../../indexes/boosting). + + * Add a boost value to the queried terms **at query time**. + Refer to article [Boost search results](../../client-api/session/querying/text-search/boost-search-results). + +{PANEL/} + +## Related Articles + +### Client API + +- [Full-Text search](../../client-api/session/querying/text-search/full-text-search) + +### Indexes + +- [Analyzers](../../indexes/using-analyzers) +- [Boosting](../../indexes/boosting) diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.python.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.python.markdown new file mode 100644 index 0000000000..01beaec7d8 --- /dev/null +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.python.markdown @@ -0,0 +1,98 @@ +# Full-Text Search with Index +--- + +{NOTE: } + +* Prior to reading this article, please refer to [full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) + to learn about the `search` method. + +* **All capabilities** provided by `search` with a dynamic query can also be used when querying a static-index. + +* However, as opposed to making a dynamic search query where an auto-index is created for you, + when using a **static-index**: + + * You must configure the index-field in which you want to search. + See examples below. + + * You can configure which analyzer will be used to tokenize this field. + See [selecting an analyzer](../../indexes/using-analyzers#selecting-an-analyzer-for-a-field). + +--- + +* In this page: + * [Indexing single field for FTS](../../indexes/querying/searching#indexing-single-field-for-fts) + * [Indexing multiple fields for FTS](../../indexes/querying/searching#indexing-multiple-fields-for-fts) + * [Boosting search results](../../indexes/querying/searching#boosting-search-results) + +{NOTE/} + +--- + +{PANEL: Indexing single field for FTS} + +#### The index: + +{CODE:python index_1@Indexes\Querying\Searching.py/} + +--- + +#### Query with Search: + +* Use `Search` to make a full-text search when querying the index. + +* Refer to [Full-Text search with dynamic queries](../../client-api/session/querying/text-search/full-text-search) for all available **Search options**, + such as using wildcards, searching for multiple terms, etc. + +{CODE-TABS} +{CODE-TAB:python:Query search_1@Indexes\Querying\Searching.py /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes" +where search(EmployeeNotes, "French") +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{PANEL/} + +{PANEL: Indexing multiple fields for FTS} + +#### The index: + +{CODE:python index_2@Indexes\Querying\Searching.py/} + +--- + +#### Sample query: + +{CODE-TABS} +{CODE-TAB:python:Query search_4@Indexes\Querying\Searching.py /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByEmployeeData" +where (search(EmployeeData, "Manager") or search(EmployeeData, "French Spanish", and)) +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{PANEL/} + +{PANEL: Boosting search results} + +* In order to prioritize results, you can provide a boost value to the searched terms. + This can be applied by either of the following: + + * Add a boost value to the relevant index-field **inside the index definition**. + Refer to article [indexes - boosting](../../indexes/boosting). + + * Add a boost value to the queried terms **at query time**. + Refer to article [Boost search results](../../client-api/session/querying/text-search/boost-search-results). + +{PANEL/} + +## Related Articles + +### Client API + +- [Full-Text search](../../client-api/session/querying/text-search/full-text-search) + +### Indexes + +- [Analyzers](../../indexes/using-analyzers) +- [Boosting](../../indexes/boosting) diff --git a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown index 1421ae35cd..08dc5aa6ef 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown @@ -74,56 +74,17 @@ RavenDB would attempt to restore the `*` to their original positions before send ##### Behavior for `6.0` and up: Once wildcards are stripped by the analyzer, we no longer add them back before sending the term to the search engine. -The search terms sent to the search engine are solely based on the transformations applied by the analyzer used. +The search terms sent to the search engine are solely based on the transformations applied by the analyzer used in the index. -Note the different behavior in the following cases: +Note the different behavior in the following cases: -{NOTE: } - -**When using `StandardAnalyzer` or `NGramAnalyzer`**: - ---- - -Usually, the same analyzer used to tokenize field content at **indexing time** is also used to process the terms provided in the **full-text search query** -before they are sent to the search engine to retrieve matching documents. - -However, in the following cases: - -* When making a [dynamic search query](../../client-api/session/querying/text-search/full-text-search) -* or when querying a static index that uses the default `StandardAnalyzer` -* or when querying a static index that uses the `NGramAnalyzer` - -the queried terms in the `Search` method are processed with the **`LowerCaseKeywordAnalyzer`** analyzer before being sent to the search engine. - -This analyzer does Not remove the `*`, so the terms are sent with `*` as provided in the search terms. - -{NOTE/} -{NOTE: } - -**When using a Custom Analyzer**: - ---- - -When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, -then when querying the index, the search terms in the query will be processed according to the custom analyzer's logic. - -The `*` will remain in the terms if the custom analyzer allows it. -It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. - -{NOTE/} -{NOTE: } - -**When using the Exact Analyzer:** - ---- - -When using `KeywordAnalyzer`(the default Exact analyzer) in your index, -then when querying the index, the wildcards in your query terms remain untouched, the terms are sent to the search engine exactly as prepared by the analyzer. - -{NOTE/} - ---- +* **When using `StandardAnalyzer` or `NGramAnalyzer`**: + The queried terms in the Search method are processed with the `LowerCaseKeywordAnalyzer` before being sent to the search engine. +* **When using a custom analyzer**: + The queried terms in the Search method are processed according to the custom analyzer's logic. +* **When using the Exact analyzer**: + The queried terms in the Search method remain untouched as produced by the exact analyzer. -See behavior example in [here](../../todo..). +See detailed examples in: [Searching with wildcards](../../indexes/querying/searching#searching-with-wildcards). {PANEL/} diff --git a/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs b/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs new file mode 100644 index 0000000000..35b8f01eb8 --- /dev/null +++ b/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs @@ -0,0 +1,571 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Raven.Client.Documents; +using Raven.Client.Documents.Indexes; +using Raven.Client.Documents.Queries; +using Raven.Documentation.Samples.Orders; +using Xunit; + +namespace Raven.Documentation.Samples.Indexes.Querying +{ + public class Searching + { + #region index_1 + public class Employees_ByNotes : + AbstractIndexCreationTask + { + // The IndexEntry class defines the index-fields + public class IndexEntry + { + public string EmployeeNotes { get; set; } + } + + public Employees_ByNotes() + { + // The 'Map' function defines the content of the index-fields + Map = employees => from employee in employees + select new IndexEntry() + { + EmployeeNotes = employee.Notes[0] + }; + + // Configure the index-field for FTS: + // Set 'FieldIndexing.Search' on index-field 'EmployeeNotes' + Index(x => x.EmployeeNotes, FieldIndexing.Search); + + // Optionally: Set your choice of analyzer for the index-field. + // Here the text from index-field 'EmployeeNotes' will be tokenized by 'WhitespaceAnalyzer'. + Analyze(x => x.EmployeeNotes, "WhitespaceAnalyzer"); + + // Note: + // If no analyzer is set then the default 'RavenStandardAnalyzer' is used. + } + } + #endregion + + #region index_2 + public class Employees_ByEmployeeData : + AbstractIndexCreationTask + { + public class IndexEntry + { + public object[] EmployeeData { get; set; } + } + + public Employees_ByEmployeeData() + { + Map = employees => from employee in employees + select new IndexEntry() + { + EmployeeData = new object[] + { + // Multiple document-fields can be indexed + // into the single index-field 'EmployeeData' + employee.FirstName, + employee.LastName, + employee.Title, + employee.Notes + } + }; + + // Configure the index-field for FTS: + // Set 'FieldIndexing.Search' on index-field 'EmployeeData' + Index(x => x.EmployeeData, FieldIndexing.Search); + + // Note: + // Since no analyzer is set then the default 'RavenStandardAnalyzer' is used. + } + } + #endregion + + #region index_3 + public class Employees_ByNotes_usingDefaultAnalyzer : + AbstractIndexCreationTask + { + public class IndexEntry + { + public string EmployeeNotes { get; set; } + } + + public Employees_ByNotes_usingDefaultAnalyzer() + { + Map = employees => from employee in employees + select new IndexEntry() + { + EmployeeNotes = employee.Notes[0] + }; + + // Configure the index-field for FTS: + Index(x => x.EmployeeNotes, FieldIndexing.Search); + + // Since no analyzer is explicitly set + // then the default 'RavenStandardAnalyzer' will be used at indexing time. + + // However, when making a search query with wildcards, + // the 'LowerCaseKeywordAnalyzer' will be used to process the search terms + // prior to sending them to the search engine. + } + } + #endregion + + #region index_4 + public class Employees_ByNotes_usingCustomAnalyzer : + AbstractIndexCreationTask + { + public class IndexEntry + { + public string EmployeeNotes { get; set; } + } + + public Employees_ByNotes_usingCustomAnalyzer() + { + Map = employees => from employee in employees + select new IndexEntry() + { + EmployeeNotes = employee.Notes[0] + }; + + // Configure the index-field for FTS: + Index(x => x.EmployeeNotes, FieldIndexing.Search); + + // Set a custom analyzer for the index-field: + Analyze(x => x.EmployeeNotes, "CustomAnalyzers.RemoveWildcardsAnalyzer"); + } + } + #endregion + + #region index_5 + public class Employees_ByNotes_usingExactAnalyzer : + AbstractIndexCreationTask + { + public class IndexEntry + { + public string FirstName { get; set; } + } + + public Employees_ByNotes_usingExactAnalyzer() + { + Map = employees => from employee in employees + select new IndexEntry() + { + FirstName = employee.FirstName + }; + + // Set the Exact analyzer for the index-field: + // (The field will not be tokenized) + Indexes.Add(x => x.FirstName, FieldIndexing.Exact); + } + } + #endregion + + public async Task Examples() + { + using (var store = new DocumentStore()) + { + using (var session = store.OpenSession()) + { + #region search_1 + List employees = session + // Query the index + .Query() + // Call 'Search': + // pass the index field that was configured for FTS and the term to search for. + .Search(x => x.EmployeeNotes, "French") + .OfType() + .ToList(); + + // * Results will contain all Employee documents that have 'French' in their 'Notes' field. + // + // * Search is case-sensitive since field was indexed using the 'WhitespaceAnalyzer' + // which preserves casing. + #endregion + } + + using (var asyncSession = store.OpenAsyncSession()) + { + #region search_2 + List employees = await asyncSession + // Query the index + .Query() + // Call 'Search': + // pass the index field that was configured for FTS and the term to search for. + .Search(x => x.EmployeeNotes, "French") + .OfType() + .ToListAsync(); + + // * Results will contain all Employee documents that have 'French' in their 'Notes' field. + // + // * Search is case-sensitive since field was indexed using the 'WhitespaceAnalyzer' + // which preserves casing. + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_3 + List employees = session.Advanced + // Query the index + .DocumentQuery() + // Call 'Search': + // pass the index field that was configured for FTS and the term to search for. + .Search(x => x.EmployeeNotes, "French") + .OfType() + .ToList(); + + // * Results will contain all Employee documents that have 'French' in their 'Notes' field. + // + // * Search is case-sensitive since field was indexed using the 'WhitespaceAnalyzer' + // which preserves casing. + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_4 + List employees = session + // Query the static-index + .Query() + // A logical OR is applied between the following two Search calls: + .Search(x => x.EmployeeData, "Manager") + // A logical AND is applied between the following two terms: + .Search(x => x.EmployeeData, "French Spanish", @operator: SearchOperator.And) + .OfType() + .ToList(); + + // * Results will contain all Employee documents that have: + // ('Manager' in any of the 4 document-fields that were indexed) + // OR + // ('French' AND 'Spanish' in any of the 4 document-fields that were indexed) + // + // * Search is case-insensitive since the default analyzer is used + #endregion + } + + using (var asyncSession = store.OpenAsyncSession()) + { + #region search_5 + List employees = await asyncSession + // Query the static-index + .Query() + // A logical OR is applied between the following two Search calls: + .Search(x => x.EmployeeData, "Manager") + // A logical AND is applied between the following two terms: + .Search(x => x.EmployeeData, "French Spanish", @operator: SearchOperator.And) + .OfType() + .ToListAsync(); + + // * Results will contain all Employee documents that have: + // ('Manager' in any of the 4 document-fields that were indexed) + // OR + // ('French' AND 'Spanish' in any of the 4 document-fields that were indexed) + // + // * Search is case-insensitive since the default analyzer is used + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_6 + List employees = session.Advanced + // Query the static-index + .DocumentQuery() + .OpenSubclause() + // A logical OR is applied between the following two Search calls: + .Search(x => x.EmployeeData, "Manager") + // A logical AND is applied between the following two terms: + .Search(x => x.EmployeeData, "French Spanish", @operator: SearchOperator.And) + .CloseSubclause() + .OfType() + .ToList(); + + // * Results will contain all Employee documents that have: + // ('Manager' in any of the 4 document-fields that were indexed) + // OR + // ('French' AND 'Spanish' in any of the 4 document-fields that were indexed) + // + // * Search is case-insensitive since the default analyzer is used + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_7 + List employees = session + .Query() + + // If you request to include explanations, + // you can see the exact term that was sent to the search engine. + .ToDocumentQuery() + .IncludeExplanations(out var explanations) + .ToQueryable() + + // Provide a term with a wildcard to the Search method: + .Search(x => x.EmployeeNotes, "*rench") + .OfType() + .ToList(); + + // Results will contain all Employee documents that have terms that end with 'rench' + // (e.g. French). + + // Checking the explanations, you can see that the search term 'rench' + // was sent to the search engine WITH the leading wildcard, i.e. '*rench' + // since the 'LowerCaseKeywordAnalyzer' is used in this case. + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"EmployeeNotes:*rench", explanation); + #endregion + } + + using (var asyncSession = store.OpenAsyncSession()) + { + #region search_8 + List employees = await asyncSession + .Query() + + // If you request to include explanations, + // you can see the exact term that was sent to the search engine. + .ToDocumentQuery() + .IncludeExplanations(out var explanations) + .ToQueryable() + + // Provide a term with a wildcard to the Search method: + .Search(x => x.EmployeeNotes, "*rench") + .OfType() + .ToListAsync(); + + // Results will contain all Employee documents that have terms that end with 'rench' + // (e.g. French). + + // Checking the explanations, you can see that the search term 'rench' + // was sent to the search engine WITH the leading wildcard, i.e. '*rench' + // since the 'LowerCaseKeywordAnalyzer' is used in this case. + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"EmployeeNotes:*rench", explanation); + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_9 + List employees = session.Advanced + .DocumentQuery() + + // If you request to include explanations, + // you can see the exact term that was sent to the search engine. + .IncludeExplanations(out var explanations) + + // Provide a term with a wildcard to the Search method: + .Search(x => x.EmployeeNotes, "*rench") + .OfType() + .ToList(); + + // Results will contain all Employee documents that have terms that end with 'rench' + // (e.g. French). + + // Checking the explanations, you can see that the search term 'rench' + // was sent to the search engine WITH the leading wildcard, i.e. '*rench' + // since the 'LowerCaseKeywordAnalyzer' is used in this case. + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"EmployeeNotes:*rench", explanation); + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_10 + List employees = session + .Query() + + .ToDocumentQuery() + .IncludeExplanations(out var explanations) + .ToQueryable() + + // Provide a term with wildcards to the Search method: + .Search(x => x.EmployeeNotes, "*French*") + .OfType() + .ToList(); + + // Even though a wildcard was provided, + // the results will contain all Employee documents that contain the exact term 'French'. + + // The search term was sent to the search engine WITHOUT the wildcard, + // as the custom analyzer's logic strips them out. + + // This can be verified by checking the explanations: + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"EmployeeNotes:french", explanation); + Assert.DoesNotContain($"EmployeeNotes:*french", explanation); + #endregion + } + + using (var asyncSession = store.OpenAsyncSession()) + { + #region search_11 + List employees = await asyncSession + .Query() + + .ToDocumentQuery() + .IncludeExplanations(out var explanations) + .ToQueryable() + + // Provide a term with wildcards to the Search method: + .Search(x => x.EmployeeNotes, "*French*") + .OfType() + .ToListAsync(); + + // Even though a wildcard was provided, + // the results will contain all Employee documents that contain the exact term 'French'. + + // The search term was sent to the search engine WITHOUT the wildcard, + // as the custom analyzer's logic strips them out. + + // This can be verified by checking the explanations: + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"EmployeeNotes:french", explanation); + Assert.DoesNotContain($"EmployeeNotes:*french", explanation); + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_12 + List employees = session.Advanced + .DocumentQuery() + .IncludeExplanations(out var explanations) + // Provide a term with wildcards to the Search method: + .Search(x => x.EmployeeNotes, "*French*") + .OfType() + .ToList(); + + // Even though a wildcard was provided, + // the results will contain all Employee documents that contain the exact term 'French'. + + // The search term was sent to the search engine WITHOUT the wildcard, + // as the custom analyzer's logic strips them out. + + // This can be verified by checking the explanations: + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"EmployeeNotes:french", explanation); + Assert.DoesNotContain($"EmployeeNotes:*french", explanation); + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_13 + List employees = session + .Query() + + .ToDocumentQuery() + .IncludeExplanations(out var explanations) + .ToQueryable() + + // Provide a term with a wildcard to the Search method: + .Search(x => x.FirstName, "Mich*") + .OfType() + .ToList(); + + // Results will contain all Employee documents with FirstName that starts with 'Mich' + // (e.g. Michael). + + // The search term, 'Mich*', is sent to the search engine + // exactly as was provided to the Search method, WITH the wildcard. + + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"FirstName:Mich*", explanation); + #endregion + } + + using (var asyncSession = store.OpenAsyncSession()) + { + #region search_14 + List employees = await asyncSession + .Query() + + .ToDocumentQuery() + .IncludeExplanations(out var explanations) + .ToQueryable() + + // Provide a term with a wildcard to the Search method: + .Search(x => x.FirstName, "Mich*") + .OfType() + .ToListAsync(); + + // Results will contain all Employee documents with FirstName that starts with 'Mich' + // (e.g. Michael). + + // The search term, 'Mich*', is sent to the search engine + // exactly as was provided to the Search method, WITH the wildcard. + + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"FirstName:Mich*", explanation); + #endregion + } + + using (var session = store.OpenSession()) + { + #region search_15 + List employees = session.Advanced + .DocumentQuery() + .IncludeExplanations(out var explanations) + // Provide a term with a wildcard to the Search method: + .Search(x => x.FirstName, "Mich*") + .OfType() + .ToList(); + + // Results will contain all Employee documents with FirstName that starts with 'Mich' + // (e.g. Michael). + + // The search term, 'Mich*', is sent to the search engine + // exactly as was provided to the Search method, WITH the wildcard. + + var explanation = explanations.GetExplanations(employees[0].Id)[0]; + Assert.Contains($"FirstName:Mich*", explanation); + #endregion + } + } + } + + #region analyzer_1 + public const string RemoveWildcardsAnalyzer = + @" + using System.IO; + using Lucene.Net.Analysis; + using Lucene.Net.Analysis.Standard; + namespace CustomAnalyzers + { + public class RemoveWildcardsAnalyzer : StandardAnalyzer + { + public RemoveWildcardsAnalyzer() : base(Lucene.Net.Util.Version.LUCENE_30) + { + } + + public override TokenStream TokenStream(string fieldName, System.IO.TextReader reader) + { + // Read input stream and remove wildcards (*) + string text = reader.ReadToEnd(); + string processedText = RemoveWildcards(text); + StringReader newReader = new StringReader(processedText); + + return base.TokenStream(fieldName, newReader); + } + + private string RemoveWildcards(string input) + { + // Replace wildcard characters with an empty string + return input.Replace(""*"", """"); + } + } + }"; + #endregion + } +} diff --git a/Documentation/6.0/Samples/nodejs/indexes/querying/searching.js b/Documentation/6.0/Samples/nodejs/indexes/querying/searching.js new file mode 100644 index 0000000000..d72359d8b8 --- /dev/null +++ b/Documentation/6.0/Samples/nodejs/indexes/querying/searching.js @@ -0,0 +1,98 @@ +import { DocumentStore, AbstractIndexCreationTask } from "ravendb"; + +const store = new DocumentStore(); +const session = store.openSession(); + +class Employee { } + +//region index_1 +class Employees_ByNotes extends AbstractJavaScriptIndexCreationTask { + + constructor() { + super(); + + // Define the index-fields + this.map("Employees", e => ({ + employeeNotes : e.Notes + })); + + // Configure the index-field for FTS: + // Set 'Search' on index-field 'employeeNotes' + this.index("employeeNotes", "Search"); + + // Optionally: Set your choice of analyzer for the index-field. + // Here the text from index-field 'employeeNotes' will be tokenized by 'WhitespaceAnalyzer'. + this.analyze("employeeNotes", "WhitespaceAnalyzer"); + + // Note: + // If no analyzer is set then the default 'RavenStandardAnalyzer' is used. + } +} +//endregion + +//region index_2 +class Employees_ByEmployeeData extends AbstractJavaScriptIndexCreationTask { + + constructor() { + super(); + + // Define the index-fields + this.map("Employees", e => ({ + // Multiple document-fields can be indexed + // into the single index-field 'employeeData' + employeeData : [e.FirstName, e.LastName, e.Title, e.Notes] + })); + + // Configure the index-field for FTS: + // Set 'Search' on index-field 'employeeNotes' + this.index("employeeNotes", "Search"); + + // Note: + // Since no analyzer is set then the default 'RavenStandardAnalyzer' is used. + } +} +//endregion + +async function searching() { + const session = store.openSession(); + + { + //region search_1 + const employees = await session + // Query the index + .query({ indexName: "Employees/ByNotes" }) + // Call 'Search': + // pass the index field name that was configured for FTS and the term to search for. + .search("employeeNotes", "French") + .all(); + + // * Results will contain all Employee documents that have 'French' in their 'Notes' field. + // + // * Search is case-sensitive since field was indexed using the 'WhitespaceAnalyzer' + // which preserves casing. + //endregion + } + + { + //region search_2 + const employees = await session + // Query the static-index + .query({ indexName: "Employees/ByEmployeeData" }) + .openSubclause() + // A logical OR is applied between the following two Search calls: + .search("employeeData", "Manager") + // A logical AND is applied between the following two terms: + .search("employeeData", "French Spanish", "AND") + .closeSubclause() + .all(); + + // * Results will contain all Employee documents that have: + // ('Manager' in any of the 4 document-fields that were indexed) + // OR + // ('French' AND 'Spanish' in any of the 4 document-fields that were indexed) + // + // * Search is case-insensitive since the default analyzer is used + //endregion + } +} + diff --git a/Documentation/6.0/Samples/python/Indexes/Querying/Searching.py b/Documentation/6.0/Samples/python/Indexes/Querying/Searching.py new file mode 100644 index 0000000000..983e1e884f --- /dev/null +++ b/Documentation/6.0/Samples/python/Indexes/Querying/Searching.py @@ -0,0 +1,110 @@ +from typing import Any, Dict, List + +from ravendb import AbstractIndexCreationTask, SearchOperator +from ravendb.documents.indexes.definitions import FieldIndexing + +from examples_base import ExampleBase, Employee + + +# region index_1 +class Employees_ByNotes(AbstractIndexCreationTask): + # The IndexEntry class defines the index-fields + class IndexEntry: + def __init__(self, employee_notes: str = None): + self.employee_notes = employee_notes + + def __init__(self): + super().__init__() + # The 'Map' function defines the content of the index-fields + self.map = "from employee in docs.Employees " "select new " "{ " " employee_notes = employee.Notes[0]" "}" + + # Configure the index-field for FTS: + # Set 'FieldIndexing.Search' on index-field 'employee_notes' + self._index("employee_notes", FieldIndexing.SEARCH) + + # Optionally: Set your choice of analyzer for the index-field: + # Here the text from index-field 'EmployeeNotes' will be tokenized by 'WhitespaceAnalyzer'. + self._analyze("employee_notes", "WhitespaceAnalyzer") + + # Note: + # If no analyzer is set then the default 'RavenStandardAnalyzer' is used. + + +# endregion +# region index_2 +class Employees_ByEmployeeData(AbstractIndexCreationTask): + class IndexEntry: + def __init__(self, employee_data: List = None): + self.employee_data = employee_data + + def __init__(self): + super().__init__() + self.map = ( + "from employee in docs.Employees " + "select new {" + " employee_data = " + " {" + # Multiple document-fields can be indexed + # into the single index-field 'employee_data' + " employee.FirstName," + " employee.LastName," + " employee.Title," + " employee.Notes" + " }" + "}" + ) + # Configure the index-field for FTS: + # Set 'FieldIndexing.SEARCH' on index-field 'employee_data' + self._index("employee_data", FieldIndexing.SEARCH) + + # Note: + # Since no analyzer is set then the default 'RavenStandardAnalyzer' is used. + + +# endregion + + +class Searching(ExampleBase): + def setUp(self): + super().setUp() + + def test_searching(self): + with self.embedded_server.get_document_store() as store: + with store.open_session() as session: + # region search_1 + employees = list( + session + # Query the index + .query_index_type(Employees_ByNotes, Employees_ByNotes.IndexEntry) + # Call 'search': + # pass the index field that was configured for FTS and the term to search for. + .search("employee_notes", "French").of_type(Employee) + ) + # * Results will contain all Employee documents that have 'French' in their 'Notes' field. + + # * Search is case-sensitive since field was indexed using the 'WhitespaceAnalyzer' + # which preserves casing. + # endregion + + # region search_4 + employees = list( + session + # Query the static-index + .query_index_type(Employees_ByEmployeeData, Employees_ByEmployeeData.IndexEntry) + .open_subclause() + # A logical OR is applied between the following two search calls + .search("employee_data", "Manager") + # A logical AND is applied between the following two terms + .search("employee_data", "French Spanish", operator=SearchOperator.AND) + .close_subclause() + .of_type(Employee) + ) + + # * Results will contain all Employee documents that have: + # ('Manager' in any of the 4 document-fields that were indexed) + # OR + # ('French' AND 'Spanish' in any of the 4 document-fields that were indexed) + + # * Search is case-insensitive since the default analyzer is used + + # endregion From 3b210898e4267e1d29eff48fe9b1715fa15e1003 Mon Sep 17 00:00:00 2001 From: danielle9897 Date: Mon, 7 Oct 2024 11:00:24 +0300 Subject: [PATCH 4/6] RDoc-3052 Add text & examples to the Full-Text Search page (Node.js) --- .../querying/searching.dotnet.markdown | 4 +- .../indexes/querying/searching.js.markdown | 98 ++++++++- .../Indexes/Querying/Searching.cs | 108 +++++----- .../nodejs/indexes/querying/searching.js | 196 +++++++++++++++++- 4 files changed, 353 insertions(+), 53 deletions(-) diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown index 3f1676344a..ce00829b9e 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown @@ -122,7 +122,7 @@ before they are sent to the search engine to retrieve matching documents. the queried terms in the _Search_ method are processed with the **`LowerCaseKeywordAnalyzer`** before being sent to the search engine. -This analyzer does Not remove the `*`, so the terms are sent with `*` as provided in the search terms. +This analyzer does Not remove the `*`, so the terms are sent with `*`, as provided in the search terms. For example: {CODE-TABS} @@ -182,7 +182,7 @@ For example: {CODE-TAB:csharp:Query_async search_14@Indexes\Querying\Searching.cs /} {CODE-TAB:csharp:DocumentQuery search_15@Indexes\Querying\Searching.cs /} {CODE-TAB-BLOCK:sql:RQL} -from index "Employees/ByNotes/usingExactAnalyzer" +from index "Employees/ByFirstName/usingExactAnalyzer" where search(FirstName, "Mich*") include explanations() {CODE-TAB-BLOCK/} diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown index 0dfc359c81..381d3c5ccb 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown @@ -15,7 +15,7 @@ See examples below. * You can configure which analyzer will be used to tokenize this field. - See [selecting an analyzer](../../indexes/using-analyzers#selecting-an-analyzer-for-a-field). + See [selecting an analyzer](../../indexes/using-analyzers#selecting-an-analyzer-for-a-field). --- @@ -23,6 +23,10 @@ * [Indexing single field for FTS](../../indexes/querying/searching#indexing-single-field-for-fts) * [Indexing multiple fields for FTS](../../indexes/querying/searching#indexing-multiple-fields-for-fts) * [Boosting search results](../../indexes/querying/searching#boosting-search-results) + * [Searching with wildcards](../../indexes/querying/searching#searching-with-wildcards) + * [When using StandardAnalyzer or NGramAnalyzer](../../indexes/querying/searching#when-usingor) + * [When using a custom analyzer](../../indexes/querying/searching#when-using-a-custom-analyzer) + * [When using the Exact analyzer](../../indexes/querying/searching#when-using-the-exact-analyzer) {NOTE/} @@ -86,6 +90,98 @@ where (search(employeeData, "Manager") or search(employeeData, "French Spanish", {PANEL/} +{PANEL: Searching with wildcards} + +* When making a full-text search with wildcards in the search terms, + the presence of wildcards (`*`) in the terms sent to the search engine is determined by the transformations applied by the + [analyzer](../../indexes/using-analyzers) used in the index. + +* Note the different behavior in the following cases: + * [When using StandardAnalyzer or NGramAnalyzer](../../indexes/querying/searching#when-usingor) + * [When using a custom analyzer](../../indexes/querying/searching#when-using-a-custom-analyzer) + * [When using the Exact analyzer](../../indexes/querying/searching#when-using-the-exact-analyzer) + +--- + +{NOTE: } + +##### When using `StandardAnalyzer` or `NGramAnalyzer`: +--- + +Usually, the same analyzer used to tokenize field content at **indexing time** is also used to process the terms provided in the **full-text search query** +before they are sent to the search engine to retrieve matching documents. + +**However, in the following cases**: + +* When making a [dynamic search query](../../client-api/session/querying/text-search/full-text-search) +* or when querying a static index that uses the default `StandardAnalyzer` +* or when querying a static index that uses the `NGramAnalyzer` + +the queried terms in the _search_ method are processed with the **`LowerCaseKeywordAnalyzer`** before being sent to the search engine. + +This analyzer does Not remove the `*`, so the terms are sent with `*`, as provided in the search terms. +For example: + +{CODE-TABS} +{CODE-TAB:nodejs:Index index_3@Indexes\Querying\searching.js /} +{CODE-TAB:nodejs:Query search_3@Indexes\Querying\searching.js /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes/usingDefaultAnalyzer" +where search(EmployeeNotes, "*rench") +include explanations() +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{NOTE/} +{NOTE: } + +##### When using a custom analyzer: +--- + +When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, +then when querying the index, the search terms in the query will be processed according to the custom analyzer's logic. + +The `*` will remain in the terms if the custom analyzer allows it. +It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. + +For example: + +{CODE-TABS} +{CODE-TAB:nodejs:Index index_4@Indexes\Querying\searching.js /} +{CODE-TAB:nodejs:Custom_analyzer analyzer_1@Indexes\Querying\searching.js /} +{CODE-TAB:nodejs:Query search_4@Indexes\Querying\searching.js /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByNotes/UsingCustomAnalyzer" +where search(EmployeeNotes, "*French*") +include explanations() +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{NOTE/} +{NOTE: } + +##### When using the Exact analyzer: +--- + +When using the default Exact analyzer in your index (which is `KeywordAnalyzer`), +then when querying the index, the wildcards in your search terms remain untouched. +The terms are sent to the search engine exactly as produced by the analyzer. + +For example: + +{CODE-TABS} +{CODE-TAB:nodejs:Index index_5@Indexes\Querying\searching.js /} +{CODE-TAB:nodejs:Query search_5@Indexes\Querying\searching.js /} +{CODE-TAB-BLOCK:sql:RQL} +from index "Employees/ByFirstName/usingExactAnalyzer" +where search(FirstName, "Mich*") +include explanations() +{CODE-TAB-BLOCK/} +{CODE-TABS/} + +{NOTE/} +{PANEL/} + ## Related Articles ### Client API diff --git a/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs b/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs index 35b8f01eb8..516274acd6 100644 --- a/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs +++ b/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/Indexes/Querying/Searching.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using Raven.Client.Documents; using Raven.Client.Documents.Indexes; +using Raven.Client.Documents.Indexes.Analysis; +using Raven.Client.Documents.Operations.Analyzers; using Raven.Client.Documents.Queries; using Raven.Documentation.Samples.Orders; using Xunit; @@ -136,15 +138,15 @@ public Employees_ByNotes_usingCustomAnalyzer() #endregion #region index_5 - public class Employees_ByNotes_usingExactAnalyzer : - AbstractIndexCreationTask + public class Employees_ByFirstName_usingExactAnalyzer : + AbstractIndexCreationTask { public class IndexEntry { public string FirstName { get; set; } } - public Employees_ByNotes_usingExactAnalyzer() + public Employees_ByFirstName_usingExactAnalyzer() { Map = employees => from employee in employees select new IndexEntry() @@ -292,7 +294,7 @@ public async Task Examples() { #region search_7 List employees = session - .Query() // If you request to include explanations, @@ -321,7 +323,7 @@ public async Task Examples() { #region search_8 List employees = await asyncSession - .Query() // If you request to include explanations, @@ -390,7 +392,7 @@ public async Task Examples() .ToList(); // Even though a wildcard was provided, - // the results will contain all Employee documents that contain the exact term 'French'. + // the results will contain only Employee documents that contain the exact term 'French'. // The search term was sent to the search engine WITHOUT the wildcard, // as the custom analyzer's logic strips them out. @@ -419,7 +421,7 @@ public async Task Examples() .ToListAsync(); // Even though a wildcard was provided, - // the results will contain all Employee documents that contain the exact term 'French'. + // the results will contain only Employee documents that contain the exact term 'French'. // The search term was sent to the search engine WITHOUT the wildcard, // as the custom analyzer's logic strips them out. @@ -444,7 +446,7 @@ public async Task Examples() .ToList(); // Even though a wildcard was provided, - // the results will contain all Employee documents that contain the exact term 'French'. + // the results will contain only Employee documents that contain the exact term 'French'. // The search term was sent to the search engine WITHOUT the wildcard, // as the custom analyzer's logic strips them out. @@ -460,8 +462,8 @@ public async Task Examples() { #region search_13 List employees = session - .Query() + .Query() .ToDocumentQuery() .IncludeExplanations(out var explanations) @@ -487,8 +489,8 @@ public async Task Examples() { #region search_14 List employees = await asyncSession - .Query() + .Query() .ToDocumentQuery() .IncludeExplanations(out var explanations) @@ -514,8 +516,8 @@ public async Task Examples() { #region search_15 List employees = session.Advanced - .DocumentQuery() + .DocumentQuery() .IncludeExplanations(out var explanations) // Provide a term with a wildcard to the Search method: .Search(x => x.FirstName, "Mich*") @@ -532,40 +534,52 @@ public async Task Examples() Assert.Contains($"FirstName:Mich*", explanation); #endregion } - } - } - - #region analyzer_1 - public const string RemoveWildcardsAnalyzer = - @" - using System.IO; - using Lucene.Net.Analysis; - using Lucene.Net.Analysis.Standard; - namespace CustomAnalyzers - { - public class RemoveWildcardsAnalyzer : StandardAnalyzer - { - public RemoveWildcardsAnalyzer() : base(Lucene.Net.Util.Version.LUCENE_30) - { - } - public override TokenStream TokenStream(string fieldName, System.IO.TextReader reader) - { - // Read input stream and remove wildcards (*) - string text = reader.ReadToEnd(); - string processedText = RemoveWildcards(text); - StringReader newReader = new StringReader(processedText); - - return base.TokenStream(fieldName, newReader); - } + #region analyzer_1 + // The custom analyzer: + // ==================== + + const string RemoveWildcardsAnalyzer = + @" + using System.IO; + using Lucene.Net.Analysis; + using Lucene.Net.Analysis.Standard; + namespace CustomAnalyzers + { + public class RemoveWildcardsAnalyzer : StandardAnalyzer + { + public RemoveWildcardsAnalyzer() : base(Lucene.Net.Util.Version.LUCENE_30) + { + } - private string RemoveWildcards(string input) - { - // Replace wildcard characters with an empty string - return input.Replace(""*"", """"); - } - } - }"; - #endregion + public override TokenStream TokenStream(string fieldName, System.IO.TextReader reader) + { + // Read input stream and remove wildcards (*) + string text = reader.ReadToEnd(); + string processedText = RemoveWildcards(text); + StringReader newReader = new StringReader(processedText); + + return base.TokenStream(fieldName, newReader); + } + + private string RemoveWildcards(string input) + { + // Replace wildcard characters with an empty string + return input.Replace(""*"", """"); + } + } + }"; + + // Deploying the custom analyzer: + // ============================== + + store.Maintenance.Send(new PutAnalyzersOperation(new AnalyzerDefinition() + { + Name = "CustomAnalyzers.RemoveWildcardsAnalyzer", + Code = RemoveWildcardsAnalyzer, + })); + #endregion + } + } } } diff --git a/Documentation/6.0/Samples/nodejs/indexes/querying/searching.js b/Documentation/6.0/Samples/nodejs/indexes/querying/searching.js index d72359d8b8..5d2ab0c445 100644 --- a/Documentation/6.0/Samples/nodejs/indexes/querying/searching.js +++ b/Documentation/6.0/Samples/nodejs/indexes/querying/searching.js @@ -1,4 +1,5 @@ import { DocumentStore, AbstractIndexCreationTask } from "ravendb"; +import assert from "assert"; const store = new DocumentStore(); const session = store.openSession(); @@ -13,7 +14,7 @@ class Employees_ByNotes extends AbstractJavaScriptIndexCreationTask { // Define the index-fields this.map("Employees", e => ({ - employeeNotes : e.Notes + employeeNotes: e.Notes })); // Configure the index-field for FTS: @@ -40,7 +41,7 @@ class Employees_ByEmployeeData extends AbstractJavaScriptIndexCreationTask { this.map("Employees", e => ({ // Multiple document-fields can be indexed // into the single index-field 'employeeData' - employeeData : [e.FirstName, e.LastName, e.Title, e.Notes] + employeeData: [e.FirstName, e.LastName, e.Title, e.Notes] })); // Configure the index-field for FTS: @@ -53,6 +54,66 @@ class Employees_ByEmployeeData extends AbstractJavaScriptIndexCreationTask { } //endregion +//region index_3 +class Employees_ByNotes_usingDefaultAnalyzer extends AbstractJavaScriptIndexCreationTask { + + constructor() { + super(); + + // Define the index-fields + this.map("Employees", e => ({ + employeeNotes: e.Notes + })); + + // Configure the index-field for FTS: + this.index("employeeNotes", "Search"); + + // Since no analyzer is explicitly set + // then the default 'RavenStandardAnalyzer' will be used at indexing time. + + // However, when making a search query with wildcards, + // the 'LowerCaseKeywordAnalyzer' will be used to process the search terms + // prior to sending them to the search engine. + } +} +//endregion + +//region index_4 +class Employees_ByNotes_usingCustomAnalyzer extends AbstractJavaScriptIndexCreationTask { + + constructor() { + super(); + + this.map("Employees", e => ({ + employeeNotes: e.Notes + })); + + // Configure the index-field for FTS: + this.index("employeeNotes", "Search"); + + // Set a custom analyzer for the index-field: + this.analyze("employeeNotes", "RemoveWildcardsAnalyzer"); + } +} +//endregion + +//region index_5 +class Employees_ByFirstName_usingExactAnalyzer extends AbstractJavaScriptIndexCreationTask { + + constructor() { + super(); + + this.map("Employees", e => ({ + firstName: e.FirstName + })); + + // Set the Exact analyzer for the index-field: + // (The field will not be tokenized) + this.index("firstName", "Exact"); + } +} +//endregion + async function searching() { const session = store.openSession(); @@ -61,7 +122,7 @@ async function searching() { const employees = await session // Query the index .query({ indexName: "Employees/ByNotes" }) - // Call 'Search': + // Call 'search': // pass the index field name that was configured for FTS and the term to search for. .search("employeeNotes", "French") .all(); @@ -94,5 +155,134 @@ async function searching() { // * Search is case-insensitive since the default analyzer is used //endregion } + + { + //region search_3 + let explanations; + + const employees = await session + .query({ indexName: "Employees/ByNotes/usingDefaultAnalyzer" }) + // If you request to include explanations, + // you can see the exact term that was sent to the search engine. + .includeExplanations(e => explanations = e) + // Provide a term with a wildcard to the search method: + .search("employeeNotes", "*rench") + .all(); + + // Results will contain all Employee documents that have terms that end with 'rench' + // (e.g. French). + + // Checking the explanations, you can see that the search term 'rench' + // was sent to the search engine WITH the leading wildcard, i.e. '*rench' + // since the 'LowerCaseKeywordAnalyzer' is used in this case. + const explanation = explanations.explanations[employees[0].id][0]; + const expectedVal = "employeeNotes:*rench"; + + assert.ok(explanation.includes(expectedVal), + `'${explanation}' does not contain '${expectedVal}.'`); + //endregion + } + + { + //region search_4 + let explanations; + + const employees = await session + .query({ indexName: "Employees/ByNotes/usingCustomAnalyzer" }) + .includeExplanations(e => explanations = e) + // Provide a term with wildcards to the Search method: + .search("employeeNotes", "*French*") + .all(); + + // Even though a wildcard was provided, + // the results will contain only Employee documents that contain the exact term 'French'. + + // The search term was sent to the search engine WITHOUT the wildcard, + // as the custom analyzer's logic strips them out. + + // This can be verified by checking the explanations: + const explanation = explanations.explanations[employees[0].id][0]; + + const expectedVal = "employeeNotes:french"; + assert.ok(explanation.includes(expectedVal), + `'${explanation}' does not contain '${expectedVal}.'`); + + const notExpectedVal = "employeeNotes:*french"; + assert.ok(!explanation.includes(notExpectedVal), + `'${explanation}' does not contain '${notExpectedVal}.'`); + //endregion + } + + { + //region search_5 + let explanations; + + const employees = await session + .query({ indexName: "Employees/ByFirstName/usingExactAnalyzer" }) + .includeExplanations(e => explanations = e) + // Provide a term with a wildcard to the Search method: + .search("firstName", "Mich*") + .all(); + + // Results will contain all Employee documents with FirstName that starts with 'Mich' + // (e.g. Michael). + + // The search term, 'Mich*', is sent to the search engine + // exactly as was provided to the Search method, WITH the wildcard. + + const explanation = explanations.explanations[employees[0].id][0]; + const expectedVal = "firstName:Mich*"; + + assert.ok(explanation.includes(expectedVal), + `'${explanation}' does not contain '${expectedVal}.'`); + //endregion + } + + { + //region analyzer_1 + // The custom analyzer: + // ==================== + + const removeWildcardsanalyzer = ` + using System.IO; + using Lucene.Net.Analysis; + using Lucene.Net.Analysis.Standard; + namespace CustomAnalyzers + { + public class RemoveWildcardsAnalyzer : StandardAnalyzer + { + public RemoveWildcardsAnalyzer() : base(Lucene.Net.Util.Version.LUCENE_30) + { + } + + public override TokenStream TokenStream(string fieldName, System.IO.TextReader reader) + { + // Read input stream and remove wildcards (*) + string text = reader.ReadToEnd(); + string processedText = RemoveWildcards(text); + StringReader newReader = new StringReader(processedText); + + return base.TokenStream(fieldName, newReader); + } + + private string RemoveWildcards(string input) + { + // Replace wildcard characters with an empty string + return input.Replace("*", ""); + } + } + }`; + + // Deploying the custom analyzer: + // ============================== + + const analyzerDefinition = { + name: "RemoveWildcardsAnalyzer", + code: RemoveWildcardsAnalyzer + }; + + await documentStore.maintenance.send(new PutAnalyzersOperation(analyzerDefinition)); + //endregion + } } From fea3001e5fdc489e73475b02c0d1989166ddd1d9 Mon Sep 17 00:00:00 2001 From: danielle9897 Date: Mon, 7 Oct 2024 11:02:33 +0300 Subject: [PATCH 5/6] RDoc-3052 small fix --- .../migration/server/server-breaking-changes.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown index 08dc5aa6ef..200f5ae54f 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown @@ -79,11 +79,11 @@ The search terms sent to the search engine are solely based on the transformatio Note the different behavior in the following cases: * **When using `StandardAnalyzer` or `NGramAnalyzer`**: - The queried terms in the Search method are processed with the `LowerCaseKeywordAnalyzer` before being sent to the search engine. + The queried terms in the _Search_ method are processed with the `LowerCaseKeywordAnalyzer` before being sent to the search engine. * **When using a custom analyzer**: - The queried terms in the Search method are processed according to the custom analyzer's logic. + The queried terms in the _Search_ method are processed according to the custom analyzer's logic. * **When using the Exact analyzer**: - The queried terms in the Search method remain untouched as produced by the exact analyzer. + The queried terms in the _Search_ method remain untouched as produced by the exact analyzer. See detailed examples in: [Searching with wildcards](../../indexes/querying/searching#searching-with-wildcards). From 3616dca6837389e8caf29fcdfb02a64f5b594dc9 Mon Sep 17 00:00:00 2001 From: danielle9897 Date: Thu, 10 Oct 2024 16:31:26 +0300 Subject: [PATCH 6/6] RDoc-3052 fix review comments --- .../querying/searching.dotnet.markdown | 17 ++++++++++---- .../indexes/querying/searching.js.markdown | 23 ++++++++++++------- .../server/server-breaking-changes.markdown | 12 ++++++++++ 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown index ce00829b9e..28ee65d1ed 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.dotnet.markdown @@ -99,11 +99,14 @@ where (search(EmployeeData, "Manager") or search(EmployeeData, "French Spanish", the presence of wildcards (`*`) in the terms sent to the search engine is determined by the transformations applied by the [analyzer](../../indexes/using-analyzers) used in the index. -* Note the different behavior in the following cases: +* Note the different behavior in the following cases, as described below: * [When using StandardAnalyzer or NGramAnalyzer](../../indexes/querying/searching#when-usingor) * [When using a custom analyzer](../../indexes/querying/searching#when-using-a-custom-analyzer) * [When using the Exact analyzer](../../indexes/querying/searching#when-using-the-exact-analyzer) +* When using [Corax](../../indexes/search-engine/corax) as the search engine, + this behavior will only apply to indexes that are newly created or have been reset. + --- {NOTE: } @@ -143,11 +146,15 @@ include explanations() ##### When using a custom analyzer: --- -When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, -then when querying the index, the search terms in the query will be processed according to the custom analyzer's logic. +* When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, + then when querying the index, the search terms in the query will be processed according to the **custom analyzer's logic**. + +* The `*` will remain in the terms if the custom analyzer allows it. + It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. -The `*` will remain in the terms if the custom analyzer allows it. -It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. +* Note: + An exception to the above is when the wildcard is used as a suffix in the search term (e.g. `Fren*`). + In this case the wildcard will be included in the query regardless of the analyzer's logic. For example: diff --git a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown index 381d3c5ccb..0227ab11e2 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/indexes/querying/searching.js.markdown @@ -96,10 +96,13 @@ where (search(employeeData, "Manager") or search(employeeData, "French Spanish", the presence of wildcards (`*`) in the terms sent to the search engine is determined by the transformations applied by the [analyzer](../../indexes/using-analyzers) used in the index. -* Note the different behavior in the following cases: - * [When using StandardAnalyzer or NGramAnalyzer](../../indexes/querying/searching#when-usingor) - * [When using a custom analyzer](../../indexes/querying/searching#when-using-a-custom-analyzer) - * [When using the Exact analyzer](../../indexes/querying/searching#when-using-the-exact-analyzer) +* Note the different behavior in the following cases, as described below: + * [When using StandardAnalyzer or NGramAnalyzer](../../indexes/querying/searching#when-usingor) + * [When using a custom analyzer](../../indexes/querying/searching#when-using-a-custom-analyzer) + * [When using the Exact analyzer](../../indexes/querying/searching#when-using-the-exact-analyzer) + +* When using [Corax](../../indexes/search-engine/corax) as the search engine, + this behavior will only apply to indexes that are newly created or have been reset. --- @@ -138,11 +141,15 @@ include explanations() ##### When using a custom analyzer: --- -When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, -then when querying the index, the search terms in the query will be processed according to the custom analyzer's logic. +* When setting a [custom analyzer](../../indexes/using-analyzers#creating-custom-analyzers) in your index to tokenize field content, + then when querying the index, the search terms in the query will be processed according to the custom analyzer's logic. + +* The `*` will remain in the terms if the custom analyzer allows it. + It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. -The `*` will remain in the terms if the custom analyzer allows it. -It is the user’s responsibility to ensure that wildcards are not removed by the custom analyzer if they should be included in the query. +* Note: + An exception to the above is when the wildcard is used as a suffix in the search term (e.g. `Fren*`). + In this case the wildcard will be included in the query regardless of the analyzer's logic. For example: diff --git a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown index 200f5ae54f..8eefcfadff 100644 --- a/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown +++ b/Documentation/6.0/Raven.Documentation.Pages/migration/server/server-breaking-changes.markdown @@ -66,11 +66,17 @@ This is done to distinguish partial load errors that are used in SQL ETL from, f Starting with `6.0` we have changed how the [Search method](../../indexes/querying/searching) handles wildcards when they are included in search terms: +{NOTE: } + ##### Behavior for versions lower than `6.0`: After the analyzer stripped wildcards from the search term, RavenDB would attempt to restore the `*` to their original positions before sending the term to the search engine (Lucene or Corax). +{NOTE/} + +{NOTE: } + ##### Behavior for `6.0` and up: Once wildcards are stripped by the analyzer, we no longer add them back before sending the term to the search engine. @@ -85,6 +91,12 @@ Note the different behavior in the following cases: * **When using the Exact analyzer**: The queried terms in the _Search_ method remain untouched as produced by the exact analyzer. +{INFO: } +When using **Corax** as the search engine, +this behavior will only apply to indexes that are newly created or have been reset. +{INFO/} + See detailed examples in: [Searching with wildcards](../../indexes/querying/searching#searching-with-wildcards). +{NOTE/} {PANEL/}