From 88dcf6e8e4d40f429c1bfa51d57dfc075b32b434 Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 22 Nov 2024 11:43:15 -0500 Subject: [PATCH 1/4] DOCSP-45362: text search --- source/includes/interact-data/text-search.rb | 10 + source/interact-data.txt | 4 + source/interact-data/text-search.txt | 200 +++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 source/includes/interact-data/text-search.rb create mode 100644 source/interact-data/text-search.txt diff --git a/source/includes/interact-data/text-search.rb b/source/includes/interact-data/text-search.rb new file mode 100644 index 00000000..4c2ec182 --- /dev/null +++ b/source/includes/interact-data/text-search.rb @@ -0,0 +1,10 @@ +# start-text-index-model +class Dish + include Mongoid::Document + + field :name, type: String + field :description, type: String + + index description: 'text' +end +# end-text-index-model \ No newline at end of file diff --git a/source/interact-data.txt b/source/interact-data.txt index ec2ad6b3..b11a2b05 100644 --- a/source/interact-data.txt +++ b/source/interact-data.txt @@ -16,6 +16,7 @@ Interact with Data Specify a Query Modify Query Results + Search Text Transactions and Sessions In this section, you can learn how to use {+odm+} to interact with your @@ -27,5 +28,8 @@ MongoDB data. - :ref:`mongoid-data-modify-results`: Learn how to modify the way that {+odm+} returns results from queries. +- :ref:`mongoid-data-text-search`: Learn how to perform efficient + searches on text fields. + - :ref:`mongoid-data-txn`: Learn how to perform multi-document transactions to make atomic data changes. \ No newline at end of file diff --git a/source/interact-data/text-search.txt b/source/interact-data/text-search.txt new file mode 100644 index 00000000..df7d47b2 --- /dev/null +++ b/source/interact-data/text-search.txt @@ -0,0 +1,200 @@ +.. _mongoid-data-text-search: + +=========== +Search Text +=========== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ruby framework, odm, crud, filter, code example + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use {+odm+} to run a **text +search**. A text search allows you to efficiently query fields that have +string values. + +MongoDB provides text indexes to support text search queries on +fields that have string values or values that are arrays of string +elements. To learn more about text indexes, see :manual:`Text Indexes on +Self-Managed Deployments ` in the +{+server-manual+}. + +.. note:: Atlas Search + + This guide focuses on text search. If your database is hosted on + MongoDB Atlas, you can use the Atlas Search feature + to perform more powerful and flexible text searches. To learn more + about Atlas Search, see the :atlas:`Atlas Search Overview + ` in the Atlas documentation. + +You can run a text search by performing the following steps: + +1. Define a text index on a model. +#. Create the text index on the target collection. +#. Perform a text search query. + +The following sections describe how to perform each of these actions. + +Define a Text Index on Your Model +--------------------------------- + +.. TODO link to indexes page + +Use the ``index`` macro to specify the text index in your model +definition. The following code creates a ``Dish`` model class that +includes a text index on the ``description`` field: + +.. literalinclude:: /includes/interact-data/text-search.rb + :start-after: start-text-index-model + :end-before: end-text-index-model + :language: ruby + :emphasize-lines: 7 + :dedent: + +.. note:: + + You must specify the index type as a string, as shown by ``'text'`` + in the preceding code. + +Create the Text Index +--------------------- + +Next, you must create the text index in your collection. You can +create the index by using an interface such as the :atlas:`Atlas UI +` or :compass:`Compass `. If you are +developing your application by using Rails, you can run the following +Rake task to create the index based on your model specification: + +.. code-block:: bash + + bundle exec rake db:mongoid:create_indexes + +Perform Text Searches +--------------------- + +To perform a text search, use the ``$text`` evaluation query operator, +followed by the ``$search`` field in your query filter. The ``$text`` operator +performs a text search on the text indexed fields. The ``$search`` field +specifies the text to search in the text indexed fields. To learn more +about this operator, see the :manual:`$text reference +` in the {+server-manual+}. + +.. _mongoid-term-search: + +Search by a Term +~~~~~~~~~~~~~~~~ + +To search for a term, specify the term as a string in your query filter. +To search for multiple terms, separate each term with spaces in the string. + +.. note:: + + When searching for multiple terms, {+odm+} returns + documents with at least one of the terms in text indexed fields. + +The following example runs a text search for ``description`` values that contain +the term ``'herb'``: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: ruby + + Dish.where('$text' => {'$search' => 'herb'}) + + .. output:: + :language: none + :visible: false + + # Sample output + {"_id":"...","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans.","name":"Kale Tabbouleh"} + {"_id":"...","description":"Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4.","name":"Herbed Whole Branzino"} + +.. tip:: + + Although the search term was ``'herb'``, the method also matches + descriptions containing ``'herbs'`` because a MongoDB text index uses *suffix + stemming* to match similar words. To learn more about how + MongoDB matches terms, see :manual:`Index Entries + `. + +Search by a Phrase +~~~~~~~~~~~~~~~~~~ + +To search for a phrase, specify the phrase with escaped quotes as a +string in your query filter. If you don't add escaped quotes around the +phrase, {+odm+} runs a :ref:`term search `. + +.. tip:: + + Escaped quotes are a backslash character followed by a double quote + character. + +The following example runs a text search for ``description`` values that +contain the phrase ``"serves 2"``: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: ruby + + Dish.where('$text' => {'$search' => "\"serves 2\""}) + + .. output:: + :language: none + :visible: false + + # Sample output + {"_id":"...","description":"A vegetarian take on the classic dish that uses lentils as a base. Serves 2.","name":"Shepherd’s Pie"} + {"_id":"...","description":"Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2.","name":"Garlic Butter Trout"} + +Search with Excluded Terms +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For each term or phrase you want to exclude from your text search, +specify the term or phrase prefixed with a minus sign (``-``) as a string in +your query filter. + +.. important:: + + You must search for at least one term if you want to exclude + terms from your search. If you don't search for any terms, {+odm+} + doesn't return any documents. + +The following example runs a text search for ``description`` values that +contain the term ``'vegan'``, but do not contain the term ``'tofu'``: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: ruby + + Dish.where('$text' => {'$search' => 'vegan -tofu'}) + + .. output:: + :language: none + :visible: false + + # Sample output + {"_id":"...","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans.","name":"Kale Tabbouleh"} + +Additional Information +---------------------- + +To learn more about querying, see :ref:`mongoid-data-specify-query`. + +.. TODO link to CRUD guide From 4ffdfac699ec6f21556cda78de6793a42cff811a Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 22 Nov 2024 11:53:44 -0500 Subject: [PATCH 2/4] wip --- source/includes/interact-data/text-search.rb | 14 ++++++- source/interact-data/text-search.txt | 40 +++++++++++++------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/source/includes/interact-data/text-search.rb b/source/includes/interact-data/text-search.rb index 4c2ec182..1d431ceb 100644 --- a/source/includes/interact-data/text-search.rb +++ b/source/includes/interact-data/text-search.rb @@ -7,4 +7,16 @@ class Dish index description: 'text' end -# end-text-index-model \ No newline at end of file +# end-text-index-model + +# start-term +Dish.where('$text' => {'$search' => 'herb'}) +# end-term + +# start-phrase +Dish.where('$text' => {'$search' => "\"serves 2\""}) +# end-phrase + +# start-exclude +Dish.where('$text' => {'$search' => 'vegan -tofu'}) +# end-exclude \ No newline at end of file diff --git a/source/interact-data/text-search.txt b/source/interact-data/text-search.txt index df7d47b2..03826010 100644 --- a/source/interact-data/text-search.txt +++ b/source/interact-data/text-search.txt @@ -98,21 +98,30 @@ Search by a Term To search for a term, specify the term as a string in your query filter. To search for multiple terms, separate each term with spaces in the string. -.. note:: +.. note:: Searching for Multiple Terms When searching for multiple terms, {+odm+} returns documents with at least one of the terms in text indexed fields. + Suppose you search by using the string ``'cake coffee cream'``. The + following list describes values that match this text query: + + - ``'Has strong coffee notes.'`` + - ``'Good for creamy coffee fans.'`` + - ``'A rich but light cake.'`` + - ``'A creamy coffee cake with cranberries.'`` + The following example runs a text search for ``description`` values that contain the term ``'herb'``: .. io-code-block:: :copyable: true - .. input:: - :language: ruby - - Dish.where('$text' => {'$search' => 'herb'}) + .. input:: /includes/interact-data/text-search.rb + :start-after: start-term + :end-before: end-term + :language: rust + :dedent: .. output:: :language: none @@ -148,10 +157,11 @@ contain the phrase ``"serves 2"``: .. io-code-block:: :copyable: true - .. input:: - :language: ruby - - Dish.where('$text' => {'$search' => "\"serves 2\""}) + .. input:: /includes/interact-data/text-search.rb + :start-after: start-phrase + :end-before: end-phrase + :language: rust + :dedent: .. output:: :language: none @@ -180,10 +190,11 @@ contain the term ``'vegan'``, but do not contain the term ``'tofu'``: .. io-code-block:: :copyable: true - .. input:: - :language: ruby - - Dish.where('$text' => {'$search' => 'vegan -tofu'}) + .. input:: /includes/interact-data/text-search.rb + :start-after: start-exclude + :end-before: end-exclude + :language: rust + :dedent: .. output:: :language: none @@ -195,6 +206,7 @@ contain the term ``'vegan'``, but do not contain the term ``'tofu'``: Additional Information ---------------------- -To learn more about querying, see :ref:`mongoid-data-specify-query`. +To learn more about constructing query filters, see +:ref:`mongoid-data-specify-query`. .. TODO link to CRUD guide From f12f8fef8fef7e30b8f33c5965dc50a4714bee64 Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 22 Nov 2024 11:56:14 -0500 Subject: [PATCH 3/4] vale --- source/interact-data/text-search.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/interact-data/text-search.txt b/source/interact-data/text-search.txt index 03826010..dcc784d2 100644 --- a/source/interact-data/text-search.txt +++ b/source/interact-data/text-search.txt @@ -174,13 +174,13 @@ contain the phrase ``"serves 2"``: Search with Excluded Terms ~~~~~~~~~~~~~~~~~~~~~~~~~~ -For each term or phrase you want to exclude from your text search, +For each term or phrase to exclude from your text search, specify the term or phrase prefixed with a minus sign (``-``) as a string in your query filter. .. important:: - You must search for at least one term if you want to exclude + You must search for at least one term to exclude terms from your search. If you don't search for any terms, {+odm+} doesn't return any documents. From fcb192b7fa96a3082ece9441547056a55c0cd43b Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 22 Nov 2024 14:10:32 -0500 Subject: [PATCH 4/4] MM PR fixes 1 --- source/interact-data/text-search.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/interact-data/text-search.txt b/source/interact-data/text-search.txt index dcc784d2..a777bf0d 100644 --- a/source/interact-data/text-search.txt +++ b/source/interact-data/text-search.txt @@ -72,8 +72,8 @@ Create the Text Index Next, you must create the text index in your collection. You can create the index by using an interface such as the :atlas:`Atlas UI -` or :compass:`Compass `. If you are -developing your application by using Rails, you can run the following +` or :compass:`Compass `. If you are using +the Rails framework to develop your application, you can run the following Rake task to create the index based on your model specification: .. code-block:: bash @@ -136,8 +136,9 @@ the term ``'herb'``: Although the search term was ``'herb'``, the method also matches descriptions containing ``'herbs'`` because a MongoDB text index uses *suffix stemming* to match similar words. To learn more about how - MongoDB matches terms, see :manual:`Index Entries - `. + MongoDB matches terms, see :manual:`Text Index Properties + ` in the + {+server-manual}. Search by a Phrase ~~~~~~~~~~~~~~~~~~ @@ -148,8 +149,8 @@ phrase, {+odm+} runs a :ref:`term search `. .. tip:: - Escaped quotes are a backslash character followed by a double quote - character. + Escaped quotes are a backslash character (``\``) followed by a double + quote character (``"``). The following example runs a text search for ``description`` values that contain the phrase ``"serves 2"``: