From ef7bd6997a53aadd885020b8f10c01a75f4dfd27 Mon Sep 17 00:00:00 2001 From: rustagir Date: Wed, 30 Oct 2024 13:44:55 -0400 Subject: [PATCH 1/5] DOCSP-44849: modify results --- snooty.toml | 1 + .../includes/interact-data/modify-results.rb | 34 +++ source/interact-data.txt | 11 +- source/interact-data/modify-results.txt | 279 ++++++++++++++++++ 4 files changed, 321 insertions(+), 4 deletions(-) create mode 100644 source/includes/interact-data/modify-results.rb create mode 100644 source/interact-data/modify-results.txt diff --git a/snooty.toml b/snooty.toml index 17839cec..fd8e10ea 100644 --- a/snooty.toml +++ b/snooty.toml @@ -22,3 +22,4 @@ quickstart-sinatra-app-name = "my-sinatra-app" quickstart-rails-app-name = "my-rails-app" feedback-widget-title = "Feedback" server-manual = "Server manual" +api = "https://www.mongodb.com/docs/mongoid/master/api" \ No newline at end of file diff --git a/source/includes/interact-data/modify-results.rb b/source/includes/interact-data/modify-results.rb new file mode 100644 index 00000000..fb45192c --- /dev/null +++ b/source/includes/interact-data/modify-results.rb @@ -0,0 +1,34 @@ +# start-only +Band.where(members: 4).only(:name) +# end-only + +# start-only-embed +bands = Band.only(:name, 'tours.year') +# end-only-embed + +# start-only-embed-association +# Returns null +Band.where(name: 'Astral Projection').only(:name).first.managers + +# Returns the first Manager object +Band.where(name: 'Astral Projection').only(:name, :manager_ids).first.managers +# end-only-embed-association + +# start-without +Band.where(members: 4).without(:year) +# end-without + +# start-limit +Band.limit(5) +# end-limit + +# start-skip +Band.skip(3) + +# Equivalent +Band.offset(3) +# end-skip + +# start-batch +Band.batch_size(500) +# end-batch diff --git a/source/interact-data.txt b/source/interact-data.txt index 424edf96..224183ce 100644 --- a/source/interact-data.txt +++ b/source/interact-data.txt @@ -11,13 +11,16 @@ Interact with Data .. meta:: :keywords: ruby framework, odm, crud, query -.. TODO - .. toctree:: - :caption: Interact with Data - /interact-data/specify-query +.. toctree:: + :caption: Interact with Data + + /interact-data/modify-results In this section, you can learn how to use {+odm+} to interact with your MongoDB data. +- :ref:`mongoid-data-modify-results`: Learn how to modify the way that + {+odm+} returns results from queries. + .. - :ref:`mongoid-data-specify-query`: Learn how to construct .. queries to match specific documents in a MongoDB collection. diff --git a/source/interact-data/modify-results.txt b/source/interact-data/modify-results.txt new file mode 100644 index 00000000..51554ac4 --- /dev/null +++ b/source/interact-data/modify-results.txt @@ -0,0 +1,279 @@ +.. _mongoid-data-modify-results: + +==================== +Modify Query Results +==================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ruby framework, odm, crud, print results + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to customize the way that {+odm+} +returns results to you from queries. MongoDB allows you to perform the +following actions to modify the way that results appear: + +- :ref:`mongoid-data-projection` + +- :ref:`mongoid-data-sort` + +- :ref:`mongoid-data-skip-limit` + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``Band`` model, which represents a +band or musical group. The definition of the ``Band`` model might be +different for each section to demonstrate different query +functionalities. + +.. _mongoid-data-projection: + +Return Specified Fields +----------------------- + +In MongoDB, the process of specifying fields to include or exclude from +results is called *projection*. {+odm+} provides the following operators +to project fields: + +- ``only()``: Specifies fields to include +- ``without()``: Specifies fields to exclude + +Include Fields +~~~~~~~~~~~~~~ + +The ``only()`` method retrieves only the specified fields from the +database. + +The following code returns only the ``name`` field from documents in +which the value of the ``members`` field is ``4``: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-only + :end-before: end-only + :language: ruby + :dedent: + +.. note:: _id Field + + In MongoDB, the ``_id`` field is included in results even if you do + not explicitly include it. + +If you attempt to reference attributes that have not been loaded, +{+odm+} raises a ``Mongoid::Errors::AttributeNotLoaded`` error. + +You can also use the ``only()`` method to include fields from embedded +documents. + +Consider that the ``Band`` model embeds multiple ``Tour`` objects. You can +project fields from the ``Tour`` model such as ``year``, as shown in the +following code: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-only-embed + :end-before: end-only-embed + :language: ruby + :dedent: + +Then, you can access the embedded fields from the returned documents: + +.. code-block:: ruby + + # Returns the first Tour object from + # the first Band in the results + bands.first.tours.first + +You can pass fields of referenced associations to the ``only()`` method, +but the projection is ignored when loading the embedded objects. {+odm+} +loads all fields of the referenced associations. + +.. note:: + + If you are connected to a deployment running MongoDB 4.4 or higher, + you cannot specify an association and its fields in a projection in + the same query. + +If a document has ``has_one`` or ``has_and_belongs_to_many`` +associations, you must include the fields with foreign keys in the list +of attributes loaded when using ``only()`` for those associations to be +loaded. + +In the following example, the ``Band`` and ``Manager`` models have a +``has_and_belongs_to_many`` association: + +.. code-block:: ruby + + class Band + include Mongoid::Document + field :name, type: String + has_and_belongs_to_many :managers + end + + class Manager + include Mongoid::Document + has_and_belongs_to_many :bands + end + +The following code demonstrates how {+odm+} can load the associated +``Manager`` objects if you include the ``manager_ids`` field: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-only-embed-association + :end-before: end-only-embed-association + :language: ruby + :dedent: + +Exclude Fields +~~~~~~~~~~~~~~ + +You can explicitly exclude fields from results by using the +``without()`` method. + +The following code excludes the ``year`` field from returned ``Band`` +objects: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-without + :end-before: end-without + :language: ruby + :dedent: + +.. important:: _id Field + + {+odm+} requires the ``_id`` field for various operations, so you + *cannot* exclude the ``_id`` field or the ``id`` alias from results. + If you pass ``_id`` or ``id`` to the ``without()`` method, {+odm+} + ignores it. + +.. _mongoid-data-sort: + +Sort Results +------------ + +You can sort the order that {+odm+} returns documents by using the +``order()`` and ``order_by()`` methods. + +These methods accept a hash that indicates which fields to order the +documents by, and whether to use an ascending or descending order for +each field. + +You can specify the sort direction in the following ways: + +- Integers ``1`` (ascending) and ``-1`` (descending) + - Example: ``Band.order(name: 1, year: -1)`` + +- Symbols ``:asc`` and ``:desc`` + - Example: ``Band.order(name: :asc)`` + +- Strings ``"asc"`` and ``"desc"`` + - Example: ``Band.order_by(name: "asc", year: "desc")`` + +The ``order()`` method also accepts the following sort specifications: + +- Array of two-element arrays: + + - Strings + - Example: ``Band.order([['name', 'asc'], ['year', 'desc']])`` + + - Symbols + - Example: ``Band.order([[:name, :asc]])`` + +- ``asc`` and ``desc`` methods on symbols + - Example: ``Band.order(:name.asc, :year.desc)`` + +- SQL syntax + - Example: ``Band.order('name desc')`` + +You can also use the ``asc()`` and ``desc()`` methods instead of using +``order()``: + +.. code-block:: ruby + + Band.asc('name').desc('year') + +If you chain sort specifications, the first call defines the most +significant criteria and the newest call defines the least significant +one. + +.. TODO update link in the following note for scope + +.. note:: Sorting in Scopes + + If you define a scope on your model that includes a sort specification, + the scope sort takes precedence over the sort specified in a query, as the + default scope is evaluated first. + +.. _mongoid-data-skip-limit: + +Paginate Results +---------------- + +{+odm+} provides the ``limit()``, ``skip()``, and ``batch_size()`` +pagination operators that you can use on ``Criteria`` objects. The +following sections describe how to use these operators. + +Limit Number of Results +~~~~~~~~~~~~~~~~~~~~~~~ + +You can limit the number of results that {+odm+} returns by using the +``limit()`` method. + +The following code retrieves a maximum of ``5`` documents: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-limit + :end-before: end-limit + :language: ruby + :dedent: + +Skip Results +~~~~~~~~~~~~ + +You can skip a specified number of results by using the ``skip()`` +method, or its alias ``offset()``. If you chain a ``limit()`` call, it +is applied after documents are skipped. + +.. tip:: + + When performing pagination, you should use ``skip()`` on :ref:`sorted results ` to ensure consistent results. + +The following code skips the first ``3`` documents when returning results: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-skip + :end-before: end-skip + :language: ruby + :dedent: + +Generate Batches of Results +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When executing large queries and when iterating over query results by using +an enumerator method such as ``Criteria#each()``, {+odm+} automatically +uses the MongoDB :manual:`getMore ` command +to load results in batches. The default batch size is ``1000``, but +you can set a different value by using the ``batch_size()`` method. + +The following code sets the batch size to ``500``: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-batch + :end-before: end-batch + :language: ruby + :dedent: + +Additional Information +---------------------- + +.. TODO: add links to the bottom of this page From 1f16e11dda08cf3626012e8fc31022b1b95c79dd Mon Sep 17 00:00:00 2001 From: rustagir Date: Wed, 30 Oct 2024 13:46:41 -0400 Subject: [PATCH 2/5] vale --- source/interact-data/modify-results.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/interact-data/modify-results.txt b/source/interact-data/modify-results.txt index 51554ac4..72d1cbfe 100644 --- a/source/interact-data/modify-results.txt +++ b/source/interact-data/modify-results.txt @@ -100,7 +100,7 @@ loads all fields of the referenced associations. .. note:: - If you are connected to a deployment running MongoDB 4.4 or higher, + If you are connected to a deployment running MongoDB 4.4 or later, you cannot specify an association and its fields in a projection in the same query. @@ -246,7 +246,7 @@ is applied after documents are skipped. .. tip:: - When performing pagination, you should use ``skip()`` on :ref:`sorted results ` to ensure consistent results. + When performing pagination, use ``skip()`` on :ref:`sorted results ` to ensure consistent results. The following code skips the first ``3`` documents when returning results: From 5c1c6ee08d3a232add31c98869a1b08ff85ce1ae Mon Sep 17 00:00:00 2001 From: rustagir Date: Wed, 30 Oct 2024 14:06:42 -0400 Subject: [PATCH 3/5] fix --- source/interact-data/modify-results.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/interact-data/modify-results.txt b/source/interact-data/modify-results.txt index 72d1cbfe..9533dd77 100644 --- a/source/interact-data/modify-results.txt +++ b/source/interact-data/modify-results.txt @@ -9,7 +9,7 @@ Modify Query Results :values: reference .. meta:: - :keywords: ruby framework, odm, crud, print results + :keywords: ruby framework, odm, crud, print results, code example .. contents:: On this page :local: @@ -36,7 +36,9 @@ Sample Data The examples in this guide use the ``Band`` model, which represents a band or musical group. The definition of the ``Band`` model might be different for each section to demonstrate different query -functionalities. +functionalities. Some sections might also use the ``Manager`` model, +which represents a person who manages a given band, or a ``Tour`` model, which +represents live performances by a certain band or musical group. .. _mongoid-data-projection: From e647538f40fb4a45bf8581f52f93a01695e1c043 Mon Sep 17 00:00:00 2001 From: rustagir Date: Wed, 30 Oct 2024 17:29:22 -0400 Subject: [PATCH 4/5] list fixes --- source/interact-data/modify-results.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/interact-data/modify-results.txt b/source/interact-data/modify-results.txt index 9533dd77..45fabed2 100644 --- a/source/interact-data/modify-results.txt +++ b/source/interact-data/modify-results.txt @@ -173,12 +173,15 @@ each field. You can specify the sort direction in the following ways: - Integers ``1`` (ascending) and ``-1`` (descending) + - Example: ``Band.order(name: 1, year: -1)`` - Symbols ``:asc`` and ``:desc`` + - Example: ``Band.order(name: :asc)`` - Strings ``"asc"`` and ``"desc"`` + - Example: ``Band.order_by(name: "asc", year: "desc")`` The ``order()`` method also accepts the following sort specifications: @@ -186,15 +189,19 @@ The ``order()`` method also accepts the following sort specifications: - Array of two-element arrays: - Strings + - Example: ``Band.order([['name', 'asc'], ['year', 'desc']])`` - Symbols + - Example: ``Band.order([[:name, :asc]])`` - ``asc`` and ``desc`` methods on symbols + - Example: ``Band.order(:name.asc, :year.desc)`` - SQL syntax + - Example: ``Band.order('name desc')`` You can also use the ``asc()`` and ``desc()`` methods instead of using From f786188d24594194f934557ede1bdc76a4270afb Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 1 Nov 2024 10:18:49 -0400 Subject: [PATCH 5/5] MW PR fixes 1 --- .../includes/interact-data/modify-results.rb | 6 ++ source/interact-data/modify-results.txt | 78 +++++++++++-------- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/source/includes/interact-data/modify-results.rb b/source/includes/interact-data/modify-results.rb index fb45192c..f2da3cfe 100644 --- a/source/includes/interact-data/modify-results.rb +++ b/source/includes/interact-data/modify-results.rb @@ -22,6 +22,12 @@ Band.limit(5) # end-limit +# start-skip-limit +Band.skip(2).limit(5) +# Skips the first two results and returns +# the following five results +# end-skip-limit + # start-skip Band.skip(3) diff --git a/source/interact-data/modify-results.txt b/source/interact-data/modify-results.txt index 45fabed2..cc87951c 100644 --- a/source/interact-data/modify-results.txt +++ b/source/interact-data/modify-results.txt @@ -21,7 +21,7 @@ Overview -------- In this guide, you can learn how to customize the way that {+odm+} -returns results to you from queries. MongoDB allows you to perform the +returns results from queries. MongoDB allows you to perform the following actions to modify the way that results appear: - :ref:`mongoid-data-projection` @@ -36,17 +36,17 @@ Sample Data The examples in this guide use the ``Band`` model, which represents a band or musical group. The definition of the ``Band`` model might be different for each section to demonstrate different query -functionalities. Some sections might also use the ``Manager`` model, -which represents a person who manages a given band, or a ``Tour`` model, which -represents live performances by a certain band or musical group. +functionalities. Some sections also use the ``Manager`` model, +which represents a person who manages a given band, or the ``Tour`` +model, which represents live performances by a given band. .. _mongoid-data-projection: Return Specified Fields ----------------------- -In MongoDB, the process of specifying fields to include or exclude from -results is called *projection*. {+odm+} provides the following operators +In MongoDB, *projection* is the process of specifying fields to include +or exclude from results. {+odm+} provides the following operators to project fields: - ``only()``: Specifies fields to include @@ -98,7 +98,9 @@ Then, you can access the embedded fields from the returned documents: You can pass fields of referenced associations to the ``only()`` method, but the projection is ignored when loading the embedded objects. {+odm+} -loads all fields of the referenced associations. +loads all fields of the referenced associations. For example, when you +access the embedded ``Tour`` object as shown in the preceding code, +{+odm+} returns the complete object, not just the ``year`` field. .. note:: @@ -106,10 +108,10 @@ loads all fields of the referenced associations. you cannot specify an association and its fields in a projection in the same query. -If a document has ``has_one`` or ``has_and_belongs_to_many`` -associations, you must include the fields with foreign keys in the list -of attributes loaded when using ``only()`` for those associations to be -loaded. +If a document contains ``has_one`` or ``has_and_belongs_to_many`` +associations, and you want {+odm+} to load those associations when +you call the ``only()`` method, you must include the fields with foreign +keys in the list of attributes. In the following example, the ``Band`` and ``Manager`` models have a ``has_and_belongs_to_many`` association: @@ -163,14 +165,17 @@ objects: Sort Results ------------ -You can sort the order that {+odm+} returns documents by using the +You can specify the order in which {+odm+} returns documents by using the ``order()`` and ``order_by()`` methods. These methods accept a hash that indicates which fields to order the documents by, and whether to use an ascending or descending order for each field. -You can specify the sort direction in the following ways: +You can specify the sort direction by using integers, symbols, or +strings. We recommend using the same sorting syntax throughout your +application for consistency. The following list provides each syntax and +shows how to sort on the ``name`` and ``year`` fields: - Integers ``1`` (ascending) and ``-1`` (descending) @@ -178,7 +183,7 @@ You can specify the sort direction in the following ways: - Symbols ``:asc`` and ``:desc`` - - Example: ``Band.order(name: :asc)`` + - Example: ``Band.order(name: :asc, year: :desc)`` - Strings ``"asc"`` and ``"desc"`` @@ -194,7 +199,7 @@ The ``order()`` method also accepts the following sort specifications: - Symbols - - Example: ``Band.order([[:name, :asc]])`` + - Example: ``Band.order([[:name, :asc], [:year, :desc]])`` - ``asc`` and ``desc`` methods on symbols @@ -202,26 +207,28 @@ The ``order()`` method also accepts the following sort specifications: - SQL syntax - - Example: ``Band.order('name desc')`` + - Example: ``Band.order('name asc', 'year desc')`` -You can also use the ``asc()`` and ``desc()`` methods instead of using -``order()``: +.. tip:: -.. code-block:: ruby + Instead of using ``order()`` or ``order_by()``, you can also use the + ``asc()`` and ``desc()`` methods to specify sort orders: - Band.asc('name').desc('year') + .. code-block:: ruby + + Band.asc('name').desc('year') -If you chain sort specifications, the first call defines the most -significant criteria and the newest call defines the least significant -one. +When you chain sort specifications, the first call defines the first +sorting order and the newest call defines the last sorting order after +the previous sorts have been applied. .. TODO update link in the following note for scope .. note:: Sorting in Scopes If you define a scope on your model that includes a sort specification, - the scope sort takes precedence over the sort specified in a query, as the - default scope is evaluated first. + the scope sort takes precedence over the sort specified in a query, + because the default scope is evaluated first. .. _mongoid-data-skip-limit: @@ -229,14 +236,14 @@ Paginate Results ---------------- {+odm+} provides the ``limit()``, ``skip()``, and ``batch_size()`` -pagination operators that you can use on ``Criteria`` objects. The +pagination methods that you can use on ``Criteria`` objects. The following sections describe how to use these operators. Limit Number of Results ~~~~~~~~~~~~~~~~~~~~~~~ -You can limit the number of results that {+odm+} returns by using the -``limit()`` method. +You can use the ``limit()`` method to limit the number of results that +{+odm+} returns. The following code retrieves a maximum of ``5`` documents: @@ -250,12 +257,21 @@ Skip Results ~~~~~~~~~~~~ You can skip a specified number of results by using the ``skip()`` -method, or its alias ``offset()``. If you chain a ``limit()`` call, it -is applied after documents are skipped. +method, or its alias ``offset()``. + +If you chain a ``limit()`` call to ``skip()``, the limit is applied +after documents are skipped, as demonstrated in the following example: + +.. literalinclude:: /includes/interact-data/modify-results.rb + :start-after: start-skip-limit + :end-before: end-skip-limit + :language: ruby + :dedent: .. tip:: - When performing pagination, use ``skip()`` on :ref:`sorted results ` to ensure consistent results. + When performing pagination, use ``skip()`` on :ref:`sorted results ` + to ensure consistent results. The following code skips the first ``3`` documents when returning results: