diff --git a/source/interact-data/query-async.txt b/source/interact-data/query-async.txt new file mode 100644 index 00000000..166b24b4 --- /dev/null +++ b/source/interact-data/query-async.txt @@ -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: + +- If {+odm+} completes the scheduled asynchronous task, it returns + the results. + +- If {+odm+} starts but does not complete the task, the caller's + thread blocks until {+odm+} finishes the task. + +- If {+odm+} has not started a task yet, it is removed from the + execution queue, and {+odm+} runs the query synchronously on the + caller's thread. + +.. 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. + +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 \ No newline at end of file diff --git a/source/interact-data/query-cache.txt b/source/interact-data/query-cache.txt new file mode 100644 index 00000000..2b477dee --- /dev/null +++ b/source/interact-data/query-cache.txt @@ -0,0 +1,111 @@ +.. _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 +` 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. To view +instructions on automatically enabling the query cache, see the +:ref:`Query Cache Rack 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 +------------------------------------ + +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 + +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. diff --git a/source/interact-data/query-persistence.txt b/source/interact-data/query-persistence.txt new file mode 100644 index 00000000..c6a42f77 --- /dev/null +++ b/source/interact-data/query-persistence.txt @@ -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 + + - 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 + + - Example: ``Band.where(name: 'Sundown').update(label: 'ABC Records')`` + +- ``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`` + +- ``destroy``: Deletes all matching documents while + running callbacks. This method loads all documents into memory. + + - Example: ``Band.where(label: 'ABC Records').destroy`` + +Additional Information +---------------------- + +To learn how to customize your persistence target, see the +:ref:`mongoid-persistence` guide. diff --git a/source/interact-data/specify-query.txt b/source/interact-data/specify-query.txt index 6c706674..6e70e805 100644 --- a/source/interact-data/specify-query.txt +++ b/source/interact-data/specify-query.txt @@ -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: @@ -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`.