From dc8884caa86a3f28020e052ef508f59a8a43eff6 Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 20 Dec 2024 11:36:50 -0500 Subject: [PATCH 1/5] DOCSP-45110: queries misc sections --- source/interact-data/query-persistence.txt | 142 +++++++++++++++++++++ source/interact-data/specify-query.txt | 1 + 2 files changed, 143 insertions(+) create mode 100644 source/interact-data/query-persistence.txt diff --git a/source/interact-data/query-persistence.txt b/source/interact-data/query-persistence.txt new file mode 100644 index 00000000..392362a5 --- /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`` + +- ``update_all``: 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..c161865f 100644 --- a/source/interact-data/specify-query.txt +++ b/source/interact-data/specify-query.txt @@ -15,6 +15,7 @@ Specify a Query :caption: Queries /interact-data/scoping + /interact-data/query-persistence .. contents:: On this page :local: From 795524b426524aab29c6dc9af9919dfd555679ab Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 20 Dec 2024 13:06:06 -0500 Subject: [PATCH 2/5] wip: --- source/interact-data/query-async.txt | 93 ++++++++++++++++++++++ source/interact-data/query-cache.txt | 105 +++++++++++++++++++++++++ source/interact-data/specify-query.txt | 10 +++ 3 files changed, 208 insertions(+) create mode 100644 source/interact-data/query-async.txt create mode 100644 source/interact-data/query-cache.txt diff --git a/source/interact-data/query-async.txt b/source/interact-data/query-async.txt new file mode 100644 index 00000000..52d50413 --- /dev/null +++ b/source/interact-data/query-async.txt @@ -0,0 +1,93 @@ +.. _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 would for synchronous queries. + +Even if a query is scheduled for asynchronous execution, it might be +executed synchronously on the caller's thread. The following list +describes possible scenarios that this might occur depending on when the +query results are being accessed: + +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. + +.. 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..c584186f --- /dev/null +++ b/source/interact-data/query-cache.txt @@ -0,0 +1,105 @@ +.. _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. See the +:ref:`Query Cache Rack Middleware ` section of +the Configuration guide for instructions. + +.. 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 of the sort that {+odm+} +applies 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 + +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/specify-query.txt b/source/interact-data/specify-query.txt index c161865f..6e70e805 100644 --- a/source/interact-data/specify-query.txt +++ b/source/interact-data/specify-query.txt @@ -16,6 +16,8 @@ Specify a Query /interact-data/scoping /interact-data/query-persistence + /interact-data/query-cache + /interact-data/query-async .. contents:: On this page :local: @@ -905,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`. From f0de4e827ef3d7cb5f38c0d3f6b29e4d4e88c265 Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 20 Dec 2024 13:08:53 -0500 Subject: [PATCH 3/5] vale --- source/interact-data/query-async.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/interact-data/query-async.txt b/source/interact-data/query-async.txt index 52d50413..6332a4d0 100644 --- a/source/interact-data/query-async.txt +++ b/source/interact-data/query-async.txt @@ -38,7 +38,7 @@ a ``Criteria`` instance, as shown in the following code: The preceding code schedules the queries for asynchronous execution. You can then access the results of the queries in your view as you -normally would for synchronous queries. +normally do for synchronous queries. Even if a query is scheduled for asynchronous execution, it might be executed synchronously on the caller's thread. The following list From 86c5d29c25109ceeb19139c92ec16d6ad4cdaa9a Mon Sep 17 00:00:00 2001 From: rustagir Date: Wed, 8 Jan 2025 13:45:19 -0500 Subject: [PATCH 4/5] MR PR fixes 1 --- source/interact-data/query-async.txt | 5 ++--- source/interact-data/query-cache.txt | 11 ++++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/source/interact-data/query-async.txt b/source/interact-data/query-async.txt index 6332a4d0..37396437 100644 --- a/source/interact-data/query-async.txt +++ b/source/interact-data/query-async.txt @@ -40,10 +40,9 @@ 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 a query is scheduled for asynchronous execution, it might be +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 that this might occur depending on when the -query results are being accessed: +describes possible scenarios in which this situation might occur: 1. If the scheduled asynchronous task has been executed, the results are returned. diff --git a/source/interact-data/query-cache.txt b/source/interact-data/query-cache.txt index c584186f..2c6b98cb 100644 --- a/source/interact-data/query-cache.txt +++ b/source/interact-data/query-cache.txt @@ -83,9 +83,9 @@ 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 of the sort that {+odm+} -applies to the second call, both methods query the database and -separately cache results. +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 @@ -95,6 +95,11 @@ code: 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 ---------------------- From 1c68896c984ca75ea6208221a1c647d4bcb2ccd4 Mon Sep 17 00:00:00 2001 From: rustagir Date: Thu, 9 Jan 2025 13:41:07 -0500 Subject: [PATCH 5/5] GM PR fixes 1 --- source/interact-data/query-async.txt | 14 ++++----- source/interact-data/query-cache.txt | 5 ++-- source/interact-data/query-persistence.txt | 34 +++++++++++----------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/source/interact-data/query-async.txt b/source/interact-data/query-async.txt index 37396437..166b24b4 100644 --- a/source/interact-data/query-async.txt +++ b/source/interact-data/query-async.txt @@ -44,15 +44,15 @@ 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 {+odm+} completes the scheduled asynchronous task, it returns + the results. -#. If the task has been started, but hasn't completed, the caller's - thread blocks until the task is finished. +- If {+odm+} starts but does not complete the task, the caller's + thread blocks until {+odm+} finishes the task. -#. 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. +- 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:: diff --git a/source/interact-data/query-cache.txt b/source/interact-data/query-cache.txt index 2c6b98cb..2b477dee 100644 --- a/source/interact-data/query-cache.txt +++ b/source/interact-data/query-cache.txt @@ -40,9 +40,10 @@ Automatic ~~~~~~~~~ The {+ruby-driver+} provides middleware to automatically enable the -query cache for Rack web requests and Active Job job runs. See 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 for instructions. +the configuration guide. .. note:: diff --git a/source/interact-data/query-persistence.txt b/source/interact-data/query-persistence.txt index 392362a5..c6a42f77 100644 --- a/source/interact-data/query-persistence.txt +++ b/source/interact-data/query-persistence.txt @@ -47,15 +47,15 @@ query criteria: - Example: ``Band.where(name: 'Daft Punk').create`` - ``create!``: Saves a model instance to MongoDB or raises an exception - if a validation error occurs. + if a validation error occurs - Example: ``Band.where(name: 'Daft Punk').create!`` -- ``build``: Creates an unsaved model instance. +- ``build``: Creates an unsaved model instance - Example: ``Band.where(name: 'Daft Punk').build`` -- ``new``: Creates an unsaved model instance. +- ``new``: Creates an unsaved model instance - Example: ``Band.where(name: 'Daft Punk').new`` @@ -65,58 +65,58 @@ Update Documents You can use the following methods to update documents based on your query criteria: -- ``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')`` -- ``update_all``: Updates attributes of all matching documents. +- ``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. +- ``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. +- ``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. +- ``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. +- ``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. + 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. +- ``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. +- ``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. + 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. +- ``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. + documents - Example: ``Band.where(name: 'Sun Down').set(likes: 10000)`` -- ``unset``: Deletes a particular field in all matching documents. +- ``unset``: Deletes a particular field in all matching documents - Example: ``Band.where(name: 'Sun Down').unset(:likes)`` @@ -130,7 +130,7 @@ query criteria: - Example: ``Band.where(label: 'ABC Records').delete`` -- ``update_all``: Deletes all matching documents while +- ``destroy``: Deletes all matching documents while running callbacks. This method loads all documents into memory. - Example: ``Band.where(label: 'ABC Records').destroy``