Skip to content

Commit 81ebaff

Browse files
author
Emily Giurleo
authored
RUBY-2376 Query cache documentation (#2101)
1 parent 68b5bb8 commit 81ebaff

File tree

4 files changed

+225
-42
lines changed

4 files changed

+225
-42
lines changed

source/index.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ For tutorials on Mongoid, see the `Mongoid Manual <https://docs.mongodb.com/mong
7878
/tutorials/ruby-driver-geospatial-search
7979
/tutorials/ruby-driver-gridfs
8080
/tutorials/client-side-encryption
81+
/tutorials/query-cache
8182
bson-tutorials
8283
API <http://api.mongodb.com/ruby/current/>
8384
/reference/driver-compatibility

source/ruby-driver-tutorials.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Tutorials
1111
The tutorials in this section provide examples of some frequently used
1212
operations. This section is not meant to be an exhaustive list of all
1313
operations available in the Ruby driver.
14-
14+
1515
.. toctree::
1616
:titlesonly:
1717

source/tutorials/query-cache.txt

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
***********
2+
Query Cache
3+
***********
4+
5+
.. default-domain:: mongodb
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 2
11+
:class: singlecol
12+
13+
.. _query-cache:
14+
15+
The MongoDB Ruby driver provides a built-in query cache. When enabled, the
16+
query cache saves the results of previously-executed find and aggregation
17+
queries. When those same queries are performed again, the driver returns
18+
the cached reuslts to prevent unnecessary roundtrips to the database.
19+
20+
Usage
21+
=====
22+
23+
The query cache is disabled by default. It cache can be enabled on the global
24+
scope as well as within the context of a specific block.
25+
26+
To enable the query cache globally:
27+
28+
.. code-block:: ruby
29+
30+
Mongo::QueryCache.enabled = true
31+
32+
Similarly, to disable it globally:
33+
34+
.. code-block:: ruby
35+
36+
Mongo::QueryCache.enabled = false
37+
38+
To enable the query cache within the context of a block:
39+
40+
.. code-block:: ruby
41+
42+
Mongo::QueryCache.cache do
43+
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
44+
client['artists'].find(name: 'Flying Lotus').first
45+
#=> Queries the database and caches the result
46+
47+
client['artists'].find(name: 'Flying Lotus').first
48+
#=> Returns the previously cached result
49+
end
50+
end
51+
52+
And to disable the query cache in the context of a block:
53+
54+
.. code-block:: ruby
55+
56+
Mongo::QueryCache.uncached do
57+
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
58+
client['artists'].find(name: 'Flying Lotus').first
59+
#=> Sends the query to the database; does NOT cache the result
60+
61+
client['artists'].find(name: 'Flying Lotus').first
62+
#=> Queries the database again
63+
end
64+
end
65+
66+
You may check whether the query cache is enabled at any time by calling
67+
``Mongo::QueryCache.enabled?``, which will return ``true`` or ``false``.
68+
69+
.. _query-cache-matching:
70+
71+
Query Matching
72+
==============
73+
74+
A query is eligible to use cached results if it matches the original query
75+
that produced the cached results. Two queries are considered matching if they
76+
are identical in the following values:
77+
78+
* Namespace (the database and collection on which the query was performed)
79+
* Selector (for aggregations, the aggregation pipeline stages)
80+
* Skip
81+
* Sort
82+
* Projection
83+
* Collation
84+
* Read Concern
85+
* Read Preference
86+
87+
For example, if you perform one query, and then perform a mostly identical query
88+
with a different sort order, those queries will not be considered matching,
89+
and the second query will not use the cached results of the first.
90+
91+
Limits
92+
======
93+
94+
When performing a query with a limit, the query cache will reuse an existing
95+
cached query with a larger limit if one exists. For example:
96+
97+
.. code-block:: ruby
98+
99+
Mongo::QueryCache.cache do
100+
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
101+
client['artists'].find(genre: 'Rock', limit: 10)
102+
#=> Queries the database and caches the result
103+
104+
client['artists'].find(genre: 'Rock', limit: 5)
105+
#=> Returns the first 5 results from the cached query
106+
107+
client['artists'].find(genre: 'Rock', limit: 20)
108+
#=> Queries the database again and replaces the previously cached query results
109+
end
110+
end
111+
112+
Cache Invalidation
113+
==================
114+
115+
The query cache is cleared in part or in full on every write operation. Most
116+
write operations will clear the results of any queries were performed on the same
117+
collection that is being written to. Some operations will clear the entire
118+
query cache.
119+
120+
The following operations will clear cached query results on the same database and
121+
collection (including during bulk writes):
122+
123+
* ``insert_one``
124+
* ``update_one``
125+
* ``replace_one``
126+
* ``update_many``
127+
* ``delete_one``
128+
* ``delete_many``
129+
* ``find_one_and_delete``
130+
* ``find_one_and_update``
131+
* ``find_one_and_replace``
132+
133+
The following operations will clear the entire query cache:
134+
135+
* aggregation with ``$merge`` or ``$out`` pipeline stages
136+
* ``commit_transaction``
137+
* ``abort_transaction``
138+
139+
Manual Cache Invalidation
140+
=========================
141+
142+
You may clear the query cache at any time with the following method:
143+
144+
.. code-block:: ruby
145+
146+
Mongo::QueryCache.clear
147+
148+
This will remove all cached query results.
149+
150+
Transactions
151+
============
152+
153+
Queries are cached within the context of a transaction, but the entire
154+
cache will be cleared when the transaction is committed or aborted.
155+
156+
.. code-block:: ruby
157+
158+
Mongo::QueryCache.cache do
159+
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
160+
session = client.start_session
161+
162+
session.with_transaction do
163+
client['artists'].insert_one({ name: 'Fleet Foxes' }, session: session)
164+
165+
client['artists'].find({}, session: session).first
166+
#=> { name: 'Fleet Foxes' }
167+
#=> Queries the database and caches the result
168+
169+
client['artists'].find({}, session: session).first
170+
#=> { name: 'Fleet Foxes' }
171+
#=> Returns the previously cached result
172+
173+
session.abort_transaction
174+
end
175+
176+
client['artists'].find.first
177+
#=> nil
178+
# The query cache was cleared on abort_transaction
179+
end
180+
end
181+
182+
.. note::
183+
184+
Transactions are often performed with a "snapshot" read concern level. Keep
185+
in mind that a query with a "snapshot" read concern cannot return cached
186+
results from a query without the "snapshot" read concern, so it is possible
187+
that a transaction may not use previously cached queries.
188+
189+
To understand when a query will use a cached result, see the
190+
:ref:`Query Matching <query-cache-matching>` section.
191+
192+
Aggregations
193+
============
194+
195+
The query cache also caches the results of aggregation pipelines. For example:
196+
197+
.. code-block:: ruby
198+
199+
Mongo::QueryCache.cache do
200+
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
201+
client['artists'].aggregate([ { '$match' => { name: 'Fleet Foxes' } } ]).first
202+
#=> Queries the database and caches the result
203+
204+
client['artists'].aggregate([ { '$match' => { name: 'Fleet Foxes' } } ]).first
205+
#=> Returns the previously cached result
206+
end
207+
end
208+
209+
.. note::
210+
211+
Aggregation results are cleared from the cache during every write operation,
212+
with no exceptions.
213+

source/tutorials/ruby-driver-crud-operations.txt

Lines changed: 10 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -130,46 +130,15 @@ object, or with ``Decimal128.from_string()``.
130130
price = BSON::Decimal128.from_string("428.79")
131131
# => BSON::Decimal128('428.79')
132132

133-
134-
.. _query-cache:
135-
136133
Query Cache
137134
===========
138135

139-
If the Ruby driver's query cache is enabled, it will cache find queries on
140-
the currently executed thread and avoid sending requests to the database for
141-
identical queries. The QueryCache class stores CachingCursor objects which attempt
142-
to load documents from memory before retrieving them from the database. Performing
143-
any write operations such as insert, update, or delete clears the query cache. Note that
144-
if the number of results is too large to be returned in a single batch,
145-
the query cache will not be used, even if ``Mongo::QueryCache.enabled`` is true, and
146-
an error will be returned.
147-
148-
Similar to Mongoid's query cache, the driver's query cache implementation
149-
does not support using CachingCursors for queries with different limit sizes if
150-
the original query has a specified limit. For example, if a query with a limit of
151-
100 were executed, followed by a query with a limit of 10, the second query
152-
would still run against the database and a new CachingCursor object would be stored,
153-
rather than using the existing one. However, if a query does not specify a limit
154-
initially, then any query that is run after it with a specified limit will use
155-
the original CachingCursor rather than going back to the database, and will return
156-
the correct number of documents accordingly.
157-
158-
To enable the query cache on a global scope:
159-
160-
.. code-block:: ruby
161-
162-
Mongo::QueryCache.enabled = true
163-
164-
The following code shows how to enable the query cache within the context of a
165-
specific block:
166-
167-
.. code-block:: ruby
168-
169-
Mongo::QueryCache.cache do
170-
# all queries within this block are cached
171-
end
136+
The Ruby driver provides a query cache. When enabled, the query cache will
137+
save the results of find and aggregation queries and return those saved results
138+
when the same queries are performed again.
172139

140+
To read more about the query cache, visit the
141+
:ref:`query cache tutorial <query-cache>`.
173142

174143
Reading
175144
=======
@@ -293,7 +262,7 @@ Additional Query Operations
293262

294263
``estimated_document_count``
295264
Get an approximate number of documents in the collection.
296-
265+
297266
Note that unlike ``count_documents``, ``estimated_document_count`` does not
298267
accept a filter.
299268

@@ -306,7 +275,7 @@ Additional Query Operations
306275
``count``
307276
Get an approximate number of documents matching a filter, or an approximate
308277
number of documents in the collection.
309-
278+
310279
*Deprecated:* The ``count`` method is deprecated and does not work in
311280
transactions. Please use ``count_documents`` to obtain an exact count of
312281
documents potentially matching a filter or ``estimated_document_count``
@@ -366,11 +335,11 @@ or on the collection:
366335

367336
client = Mongo::Client.new(['localhost:14420'], database: 'music',
368337
read_concern: {level: :local})
369-
338+
370339
client['collection'].find.to_a
371340

372341
collection = client['collection', read_concern: {level: :majority}]
373-
342+
374343
collection.find.to_a
375344

376345
The driver does not currently support setting read concern on an individual
@@ -387,7 +356,7 @@ part of the command:
387356
.. code-block:: ruby
388357

389358
client.database.command(collstats: 'test', readConcern: {level: :majority})
390-
359+
391360

392361
.. _ruby-driver-read-preference:
393362

0 commit comments

Comments
 (0)