Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions source/interact-data/query-async.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
.. _mongoid-query-async:

====================
Asynchronous Queries
====================

.. facet::
:name: genre
:values: reference

.. meta::
:keywords: ruby framework, odm, memory, background tasks, execution

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol

Overview
--------

In this guide, you can learn how to perform asynchronous queries in
{+odm+}. You can run database queries asynchronously in the background,
which can be beneficial if your application retrieves documents from
multiple collections.

Run Async Queries
-----------------

To schedule an asynchronous query, call the ``load_async`` method on
a ``Criteria`` instance, as shown in the following code:

.. code-block:: ruby

@active_bands = Band.where(active: true).load_async
@public_articles = Article.where(public: true).load_async

The preceding code schedules the queries for asynchronous execution.
You can then access the results of the queries in your view as you
normally do for synchronous queries.

Even if you schedule a query for asynchronous execution, it might be
executed synchronously on the caller's thread. The following list
describes possible scenarios in which this situation might occur:

1. If the scheduled asynchronous task has been executed, the
results are returned.

#. If the task has been started, but hasn't completed, the caller's
thread blocks until the task is finished.

#. If the task has not been started yet, it is removed from the
execution queue, and the query is executed synchronously on the
caller's thread.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: Can you convert some of these from passive to active voice?


.. note::

Even though the ``load_async`` method returns a ``Criteria`` object,
do not perform any operations on this object other than accessing query results.
{+odm+} schedules the query for execution immediately after calling
``load_async``, so later changes to the ``Criteria`` object might not
be applied.

Configure Query Performance
---------------------------

Asynchronous queries are disabled by default. When asynchronous queries
are disabled, the ``load_async`` method performs the query immediately
on the current thread, blocking as required. Therefore, calling
``load_async`` on a ``Criteria`` instance in this situation is similar
to calling the ``to_a`` method to force query execution.
Comment on lines +70 to +72
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: I'm not familiar with this method - how is this similar?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to_a performs a conversion to an array of documents, i believe that this forces query execution because it requires the query to return documents to convert those documents to an array

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, if you don't call to_a you're not actually sending the command to the server and just returning an instance of Mongoid::Criteria instead


To enable asynchronous query execution, you must set the following
configuration options:

.. code-block:: xml

development:
...
options:
# Execute asynchronous queries using a global thread pool.
async_query_executor: :global_thread_pool
# Number of threads in the pool. The default is 4.
# global_executor_concurrency: 4

Additional Information
----------------------

.. TODO link to config guide

.. TODO link to crud operations
110 changes: 110 additions & 0 deletions source/interact-data/query-cache.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
.. _mongoid-query-cache:

===========
Query Cache
===========

.. facet::
:name: genre
:values: reference

.. meta::
:keywords: ruby framework, odm, memory, storage, execution

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol

Overview
--------

In this guide, you can learn about **query caching**. The
query cache saves the results of previous find and aggregation queries
and reuses them in the future. This prevents {+odm+} from performing
the queries again, increasing application performance and reducing
the database load.

To learn more about this feature, see :ruby:`Query Cache
</reference/query-cache/>` in the {+ruby-driver+} documentation.

Enable Query Caching
--------------------

In this section, you can learn how to enable the query caching feature
in your application. You can enable the query cache by using the
driver's namespace or {+odm+}'s namespace.

Automatic
~~~~~~~~~

The {+ruby-driver+} provides middleware to automatically enable the
query cache for Rack web requests and Active Job job runs. See the
:ref:`Query Cache Rack Middleware <query-cache-middleware>` section of
the Configuration guide for instructions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s: Link text should begin with an explanation of the purpose of the link: https://www.mongodb.com/docs/meta/style-guide/style/links-and-cross-references/#make-link-text-clear

Suggested change
query cache for Rack web requests and Active Job job runs. See the
:ref:`Query Cache Rack Middleware <query-cache-middleware>` section of
the Configuration guide for instructions.
query cache for Rack web requests and Active Job job runs. For instructions
on automatically enabling the query cache, see the :ref:`Query Cache Rack Middleware <query-cache middleware>` section of the configuration guide.


.. note::

Query cache middleware does not apply to code run outside web
requests or jobs.

Manual
~~~~~~

To enable the query cache manually for a specific code segment, you can
run your code within the following block:

.. code-block:: ruby

Mongo::QueryCache.cache do
# Include code here ...
end

You can explicitly enable and disable the query cache, but we recommend
using the block form in the preceding code example. The following code
demonstrates how to enable and disable the query cache:

.. code-block:: ruby

begin
Mongo::QueryCache.enabled = true
# Include code here
ensure
Mongo::QueryCache.enabled = false
end

Cache the Result of the first Method
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Cache the Result of the first Method
Cache the Result of the ``first`` Method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoiding using monospace in titles per style guide

------------------------------------

Calling the ``first`` method on a model class uses an ascending sort on
the ``_id`` field when returning the result. This might produce unexpected
behavior if you enable query caching.

For example, if you call the ``all`` method on a model class before
calling ``first``, you might expect the ``first`` method to use the
cached results from ``all``. However, because {+odm+} applies a sort
to the second call, both methods query the database and separately cache
results.

To use the cached results when calling the ``first`` method, call
``all.to_a.first`` on the model class, as shown in the following example
code:

.. code-block::

Band.all.to_a.first
Comment on lines +91 to +97
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: might just be my unfamiliarity with to_a, but can you briefly explain what this code does?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to_a stores the documents in an array, so when first applies the sort, its just on the array in memory instead of executing a new query. I can add this info to the page.


In the preceding example, chaining the ``to_a`` method runs the query
and converts the results into an array in memory. Then, the ``first``
method simply returns the first array entry instead of triggering
another query and caching the results.

Additional Information
----------------------

To learn more about creating filter criteria, see the
:ref:`mongoid-data-specify-query` guide.

To learn how to customize your persistence target, see the
:ref:`mongoid-persistence` guide.
142 changes: 142 additions & 0 deletions source/interact-data/query-persistence.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
.. _mongoid-query-persistence:

=========================
Persist Data from Queries
=========================

.. 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 how to persist data off of your queries
in {+odm+}. {+odm+} supports persistence operations off of criteria in a
limited capacity, allowing you to to expressively perform multi-document
insert, update, and delete operations.

To learn more about creating filter criteria, see the
:ref:`mongoid-data-specify-query` guide.

.. TODO To learn more about performing CRUD operations, see the :ref:`` guide.

Persistence Methods
-------------------

This section describes methods that you can chain to your queries to
create, update, and delete data in your MongoDB collections.

Create a Document
~~~~~~~~~~~~~~~~~

You can use the following methods to create new documents from your
query criteria:

- ``create``: Saves a model instance to MongoDB

- Example: ``Band.where(name: 'Daft Punk').create``

- ``create!``: Saves a model instance to MongoDB or raises an exception
if a validation error occurs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s: remove this period as it is a sentence fragment. applies to all items in this list.

Suggested change
if a validation error occurs.
if a validation error occurs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed periods from all lists except delete section as one entry has two sentences.


- Example: ``Band.where(name: 'Daft Punk').create!``

- ``build``: Creates an unsaved model instance.

- Example: ``Band.where(name: 'Daft Punk').build``

- ``new``: Creates an unsaved model instance.

- Example: ``Band.where(name: 'Daft Punk').new``

Update Documents
~~~~~~~~~~~~~~~~

You can use the following methods to update documents based on your
query criteria:

- ``update``: Updates attributes of the first matching document.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s: same suggestion as above.

Suggested change
- ``update``: Updates attributes of the first matching document.
- ``update``: Updates attributes of the first matching document


- Example: ``Band.where(name: 'Sundown').update(label: 'ABC Records')``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: up to you, but was wondering why this is a long list instead of a table, given that each method has an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We prev got feedback that people think the code in tables is too small to read


- ``update_all``: Updates attributes of all matching documents.

- Example: ``Band.where(country: 'Canada').update_all(label: 'ABC Records')``

- ``add_to_set``: Adds a value to a specified array in all matching documents.

- Example: ``Band.where(name: 'Sun Down').add_to_set(label: 'ABC Records')``

- ``bit``: Performs a bitwise update of a field.

- Example: ``Band.where(name: 'Sun Down').bit(likes: { and: 14, or: 4 })``

- ``inc``: Increments the value of a field.

- Example: ``Band.where(name: 'Sun Down').inc(likes: 14)``

- ``pop``: Removes the first or last element of an array field.

- Example: ``Band.where(name: 'Sun Down').pop(members: -1)``

- ``pull``: Removes all instances of a value or values that match a
specified condition from an array field.

- Example: ``Band.where(name: 'Sun Down').pull(members: 'Jonah Larsen')``

- ``pull_all``: Removes all instances of the specified values from an array field.

- Example: ``Band.where(name: 'Sun Down').pull_all(:members, [ 'Jonah Larsen', 'Dan Jones' ])``

- ``push``: Appends a specified value to an array field.

- Example: ``Band.where(name: 'Sun Down').push(members: 'Jonah Larsen')``

- ``push_all``: Appends a specified value by using the ``$each``
operator in an array field.

- Example: ``Band.where(name: 'Sun Down').push_all(members: [ 'Jonah Larsen', 'Dan Jones' ])``

- ``rename``: Renames a field in all matching documents.

- Example: ``Band.where(name: 'Sun Down').rename(name: :title)``

- ``set``: Sets a new value for a specified field in all matching
documents.

- Example: ``Band.where(name: 'Sun Down').set(likes: 10000)``

- ``unset``: Deletes a particular field in all matching documents.

- Example: ``Band.where(name: 'Sun Down').unset(:likes)``

Delete Documents
~~~~~~~~~~~~~~~~

You can use the following methods to delete documents based on your
query criteria:

- ``delete``: Deletes all matching documents.

- Example: ``Band.where(label: 'ABC Records').delete``

- ``update_all``: Deletes all matching documents while
running callbacks. This method loads all documents into memory.

- Example: ``Band.where(label: 'ABC Records').destroy``

Check failure on line 136 in source/interact-data/query-persistence.txt

View workflow job for this annotation

GitHub Actions / TDBX Vale rules

[vale] reported by reviewdog 🐶 [MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'. Raw Output: {"message": "[MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'.", "location": {"path": "source/interact-data/query-persistence.txt", "range": {"start": {"line": 136, "column": 49}}}, "severity": "ERROR"}

Additional Information
----------------------

To learn how to customize your persistence target, see the
:ref:`mongoid-persistence` guide.
11 changes: 11 additions & 0 deletions source/interact-data/specify-query.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Specify a Query
:caption: Queries

/interact-data/scoping
/interact-data/query-persistence
/interact-data/query-cache
/interact-data/query-async

.. contents:: On this page
:local:
Expand Down Expand Up @@ -904,3 +907,11 @@ To learn how to modify the way that {+odm+} returns results to you, see

To learn more about defining scopes on your models, see
:ref:`mongoid-data-scoping`.

To learn about methods that you can chain to your queries to persist
data, see :ref:`mongoid-query-persistence`.

To learn about the query cache feature, see :ref:`mongoid-query-cache`.

To learn about performing asychronous queries, see
:ref:`mongoid-query-async`.
Loading