Skip to content

Commit 25fd4bd

Browse files
authored
DOCSP-45362: text search (#72)
* DOCSP-45362: text search * wip * vale * MM PR fixes 1
1 parent 895424a commit 25fd4bd

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# start-text-index-model
2+
class Dish
3+
include Mongoid::Document
4+
5+
field :name, type: String
6+
field :description, type: String
7+
8+
index description: 'text'
9+
end
10+
# end-text-index-model
11+
12+
# start-term
13+
Dish.where('$text' => {'$search' => 'herb'})
14+
# end-term
15+
16+
# start-phrase
17+
Dish.where('$text' => {'$search' => "\"serves 2\""})
18+
# end-phrase
19+
20+
# start-exclude
21+
Dish.where('$text' => {'$search' => 'vegan -tofu'})
22+
# end-exclude

source/interact-data.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Interact with Data
1616

1717
Specify a Query </interact-data/specify-query>
1818
Modify Query Results </interact-data/modify-results>
19+
Search Text </interact-data/text-search>
1920
Transactions and Sessions </interact-data/transaction>
2021

2122
In this section, you can learn how to use {+odm+} to interact with your
@@ -27,5 +28,8 @@ MongoDB data.
2728
- :ref:`mongoid-data-modify-results`: Learn how to modify the way that
2829
{+odm+} returns results from queries.
2930

31+
- :ref:`mongoid-data-text-search`: Learn how to perform efficient
32+
searches on text fields.
33+
3034
- :ref:`mongoid-data-txn`: Learn how to perform multi-document
3135
transactions to make atomic data changes.
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
.. _mongoid-data-text-search:
2+
3+
===========
4+
Search Text
5+
===========
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: ruby framework, odm, crud, filter, code example
13+
14+
.. contents:: On this page
15+
:local:
16+
:backlinks: none
17+
:depth: 2
18+
:class: singlecol
19+
20+
Overview
21+
--------
22+
23+
In this guide, you can learn how to use {+odm+} to run a **text
24+
search**. A text search allows you to efficiently query fields that have
25+
string values.
26+
27+
MongoDB provides text indexes to support text search queries on
28+
fields that have string values or values that are arrays of string
29+
elements. To learn more about text indexes, see :manual:`Text Indexes on
30+
Self-Managed Deployments </core/indexes/index-types/index-text/>` in the
31+
{+server-manual+}.
32+
33+
.. note:: Atlas Search
34+
35+
This guide focuses on text search. If your database is hosted on
36+
MongoDB Atlas, you can use the Atlas Search feature
37+
to perform more powerful and flexible text searches. To learn more
38+
about Atlas Search, see the :atlas:`Atlas Search Overview
39+
</atlas-search/atlas-search-overview/>` in the Atlas documentation.
40+
41+
You can run a text search by performing the following steps:
42+
43+
1. Define a text index on a model.
44+
#. Create the text index on the target collection.
45+
#. Perform a text search query.
46+
47+
The following sections describe how to perform each of these actions.
48+
49+
Define a Text Index on Your Model
50+
---------------------------------
51+
52+
.. TODO link to indexes page
53+
54+
Use the ``index`` macro to specify the text index in your model
55+
definition. The following code creates a ``Dish`` model class that
56+
includes a text index on the ``description`` field:
57+
58+
.. literalinclude:: /includes/interact-data/text-search.rb
59+
:start-after: start-text-index-model
60+
:end-before: end-text-index-model
61+
:language: ruby
62+
:emphasize-lines: 7
63+
:dedent:
64+
65+
.. note::
66+
67+
You must specify the index type as a string, as shown by ``'text'``
68+
in the preceding code.
69+
70+
Create the Text Index
71+
---------------------
72+
73+
Next, you must create the text index in your collection. You can
74+
create the index by using an interface such as the :atlas:`Atlas UI
75+
</atlas-ui/indexes>` or :compass:`Compass </indexes>`. If you are using
76+
the Rails framework to develop your application, you can run the following
77+
Rake task to create the index based on your model specification:
78+
79+
.. code-block:: bash
80+
81+
bundle exec rake db:mongoid:create_indexes
82+
83+
Perform Text Searches
84+
---------------------
85+
86+
To perform a text search, use the ``$text`` evaluation query operator,
87+
followed by the ``$search`` field in your query filter. The ``$text`` operator
88+
performs a text search on the text indexed fields. The ``$search`` field
89+
specifies the text to search in the text indexed fields. To learn more
90+
about this operator, see the :manual:`$text reference
91+
</reference/operator/query/text>` in the {+server-manual+}.
92+
93+
.. _mongoid-term-search:
94+
95+
Search by a Term
96+
~~~~~~~~~~~~~~~~
97+
98+
To search for a term, specify the term as a string in your query filter.
99+
To search for multiple terms, separate each term with spaces in the string.
100+
101+
.. note:: Searching for Multiple Terms
102+
103+
When searching for multiple terms, {+odm+} returns
104+
documents with at least one of the terms in text indexed fields.
105+
106+
Suppose you search by using the string ``'cake coffee cream'``. The
107+
following list describes values that match this text query:
108+
109+
- ``'Has strong coffee notes.'``
110+
- ``'Good for creamy coffee fans.'``
111+
- ``'A rich but light cake.'``
112+
- ``'A creamy coffee cake with cranberries.'``
113+
114+
The following example runs a text search for ``description`` values that contain
115+
the term ``'herb'``:
116+
117+
.. io-code-block::
118+
:copyable: true
119+
120+
.. input:: /includes/interact-data/text-search.rb
121+
:start-after: start-term
122+
:end-before: end-term
123+
:language: rust
124+
:dedent:
125+
126+
.. output::
127+
:language: none
128+
:visible: false
129+
130+
# Sample output
131+
{"_id":"...","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans.","name":"Kale Tabbouleh"}
132+
{"_id":"...","description":"Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4.","name":"Herbed Whole Branzino"}
133+
134+
.. tip::
135+
136+
Although the search term was ``'herb'``, the method also matches
137+
descriptions containing ``'herbs'`` because a MongoDB text index uses *suffix
138+
stemming* to match similar words. To learn more about how
139+
MongoDB matches terms, see :manual:`Text Index Properties
140+
</core/indexes/index-types/index-text/text-index-properties/>` in the
141+
{+server-manual}.
142+
143+
Search by a Phrase
144+
~~~~~~~~~~~~~~~~~~
145+
146+
To search for a phrase, specify the phrase with escaped quotes as a
147+
string in your query filter. If you don't add escaped quotes around the
148+
phrase, {+odm+} runs a :ref:`term search <mongoid-term-search>`.
149+
150+
.. tip::
151+
152+
Escaped quotes are a backslash character (``\``) followed by a double
153+
quote character (``"``).
154+
155+
The following example runs a text search for ``description`` values that
156+
contain the phrase ``"serves 2"``:
157+
158+
.. io-code-block::
159+
:copyable: true
160+
161+
.. input:: /includes/interact-data/text-search.rb
162+
:start-after: start-phrase
163+
:end-before: end-phrase
164+
:language: rust
165+
:dedent:
166+
167+
.. output::
168+
:language: none
169+
:visible: false
170+
171+
# Sample output
172+
{"_id":"...","description":"A vegetarian take on the classic dish that uses lentils as a base. Serves 2.","name":"Shepherd’s Pie"}
173+
{"_id":"...","description":"Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2.","name":"Garlic Butter Trout"}
174+
175+
Search with Excluded Terms
176+
~~~~~~~~~~~~~~~~~~~~~~~~~~
177+
178+
For each term or phrase to exclude from your text search,
179+
specify the term or phrase prefixed with a minus sign (``-``) as a string in
180+
your query filter.
181+
182+
.. important::
183+
184+
You must search for at least one term to exclude
185+
terms from your search. If you don't search for any terms, {+odm+}
186+
doesn't return any documents.
187+
188+
The following example runs a text search for ``description`` values that
189+
contain the term ``'vegan'``, but do not contain the term ``'tofu'``:
190+
191+
.. io-code-block::
192+
:copyable: true
193+
194+
.. input:: /includes/interact-data/text-search.rb
195+
:start-after: start-exclude
196+
:end-before: end-exclude
197+
:language: rust
198+
:dedent:
199+
200+
.. output::
201+
:language: none
202+
:visible: false
203+
204+
# Sample output
205+
{"_id":"...","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans.","name":"Kale Tabbouleh"}
206+
207+
Additional Information
208+
----------------------
209+
210+
To learn more about constructing query filters, see
211+
:ref:`mongoid-data-specify-query`.
212+
213+
.. TODO link to CRUD guide

0 commit comments

Comments
 (0)