Skip to content

Commit ef7bd69

Browse files
committed
DOCSP-44849: modify results
1 parent 5328c20 commit ef7bd69

File tree

4 files changed

+321
-4
lines changed

4 files changed

+321
-4
lines changed

snooty.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ quickstart-sinatra-app-name = "my-sinatra-app"
2222
quickstart-rails-app-name = "my-rails-app"
2323
feedback-widget-title = "Feedback"
2424
server-manual = "Server manual"
25+
api = "https://www.mongodb.com/docs/mongoid/master/api"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# start-only
2+
Band.where(members: 4).only(:name)
3+
# end-only
4+
5+
# start-only-embed
6+
bands = Band.only(:name, 'tours.year')
7+
# end-only-embed
8+
9+
# start-only-embed-association
10+
# Returns null
11+
Band.where(name: 'Astral Projection').only(:name).first.managers
12+
13+
# Returns the first Manager object
14+
Band.where(name: 'Astral Projection').only(:name, :manager_ids).first.managers
15+
# end-only-embed-association
16+
17+
# start-without
18+
Band.where(members: 4).without(:year)
19+
# end-without
20+
21+
# start-limit
22+
Band.limit(5)
23+
# end-limit
24+
25+
# start-skip
26+
Band.skip(3)
27+
28+
# Equivalent
29+
Band.offset(3)
30+
# end-skip
31+
32+
# start-batch
33+
Band.batch_size(500)
34+
# end-batch

source/interact-data.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ Interact with Data
1111
.. meta::
1212
:keywords: ruby framework, odm, crud, query
1313

14-
.. TODO
15-
.. toctree::
16-
:caption: Interact with Data
17-
/interact-data/specify-query
14+
.. toctree::
15+
:caption: Interact with Data
16+
17+
/interact-data/modify-results
1818

1919
In this section, you can learn how to use {+odm+} to interact with your
2020
MongoDB data.
2121

22+
- :ref:`mongoid-data-modify-results`: Learn how to modify the way that
23+
{+odm+} returns results from queries.
24+
2225
.. - :ref:`mongoid-data-specify-query`: Learn how to construct
2326
.. queries to match specific documents in a MongoDB collection.
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
.. _mongoid-data-modify-results:
2+
3+
====================
4+
Modify Query Results
5+
====================
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: ruby framework, odm, crud, print results
13+
14+
.. contents:: On this page
15+
:local:
16+
:backlinks: none
17+
:depth: 2
18+
:class: singlecol
19+
20+
Overview
21+
--------
22+
23+
In this guide, you can learn how to customize the way that {+odm+}
24+
returns results to you from queries. MongoDB allows you to perform the
25+
following actions to modify the way that results appear:
26+
27+
- :ref:`mongoid-data-projection`
28+
29+
- :ref:`mongoid-data-sort`
30+
31+
- :ref:`mongoid-data-skip-limit`
32+
33+
Sample Data
34+
~~~~~~~~~~~
35+
36+
The examples in this guide use the ``Band`` model, which represents a
37+
band or musical group. The definition of the ``Band`` model might be
38+
different for each section to demonstrate different query
39+
functionalities.
40+
41+
.. _mongoid-data-projection:
42+
43+
Return Specified Fields
44+
-----------------------
45+
46+
In MongoDB, the process of specifying fields to include or exclude from
47+
results is called *projection*. {+odm+} provides the following operators
48+
to project fields:
49+
50+
- ``only()``: Specifies fields to include
51+
- ``without()``: Specifies fields to exclude
52+
53+
Include Fields
54+
~~~~~~~~~~~~~~
55+
56+
The ``only()`` method retrieves only the specified fields from the
57+
database.
58+
59+
The following code returns only the ``name`` field from documents in
60+
which the value of the ``members`` field is ``4``:
61+
62+
.. literalinclude:: /includes/interact-data/modify-results.rb
63+
:start-after: start-only
64+
:end-before: end-only
65+
:language: ruby
66+
:dedent:
67+
68+
.. note:: _id Field
69+
70+
In MongoDB, the ``_id`` field is included in results even if you do
71+
not explicitly include it.
72+
73+
If you attempt to reference attributes that have not been loaded,
74+
{+odm+} raises a ``Mongoid::Errors::AttributeNotLoaded`` error.
75+
76+
You can also use the ``only()`` method to include fields from embedded
77+
documents.
78+
79+
Consider that the ``Band`` model embeds multiple ``Tour`` objects. You can
80+
project fields from the ``Tour`` model such as ``year``, as shown in the
81+
following code:
82+
83+
.. literalinclude:: /includes/interact-data/modify-results.rb
84+
:start-after: start-only-embed
85+
:end-before: end-only-embed
86+
:language: ruby
87+
:dedent:
88+
89+
Then, you can access the embedded fields from the returned documents:
90+
91+
.. code-block:: ruby
92+
93+
# Returns the first Tour object from
94+
# the first Band in the results
95+
bands.first.tours.first
96+
97+
You can pass fields of referenced associations to the ``only()`` method,
98+
but the projection is ignored when loading the embedded objects. {+odm+}
99+
loads all fields of the referenced associations.
100+
101+
.. note::
102+
103+
If you are connected to a deployment running MongoDB 4.4 or higher,
104+
you cannot specify an association and its fields in a projection in
105+
the same query.
106+
107+
If a document has ``has_one`` or ``has_and_belongs_to_many``
108+
associations, you must include the fields with foreign keys in the list
109+
of attributes loaded when using ``only()`` for those associations to be
110+
loaded.
111+
112+
In the following example, the ``Band`` and ``Manager`` models have a
113+
``has_and_belongs_to_many`` association:
114+
115+
.. code-block:: ruby
116+
117+
class Band
118+
include Mongoid::Document
119+
field :name, type: String
120+
has_and_belongs_to_many :managers
121+
end
122+
123+
class Manager
124+
include Mongoid::Document
125+
has_and_belongs_to_many :bands
126+
end
127+
128+
The following code demonstrates how {+odm+} can load the associated
129+
``Manager`` objects if you include the ``manager_ids`` field:
130+
131+
.. literalinclude:: /includes/interact-data/modify-results.rb
132+
:start-after: start-only-embed-association
133+
:end-before: end-only-embed-association
134+
:language: ruby
135+
:dedent:
136+
137+
Exclude Fields
138+
~~~~~~~~~~~~~~
139+
140+
You can explicitly exclude fields from results by using the
141+
``without()`` method.
142+
143+
The following code excludes the ``year`` field from returned ``Band``
144+
objects:
145+
146+
.. literalinclude:: /includes/interact-data/modify-results.rb
147+
:start-after: start-without
148+
:end-before: end-without
149+
:language: ruby
150+
:dedent:
151+
152+
.. important:: _id Field
153+
154+
{+odm+} requires the ``_id`` field for various operations, so you
155+
*cannot* exclude the ``_id`` field or the ``id`` alias from results.
156+
If you pass ``_id`` or ``id`` to the ``without()`` method, {+odm+}
157+
ignores it.
158+
159+
.. _mongoid-data-sort:
160+
161+
Sort Results
162+
------------
163+
164+
You can sort the order that {+odm+} returns documents by using the
165+
``order()`` and ``order_by()`` methods.
166+
167+
These methods accept a hash that indicates which fields to order the
168+
documents by, and whether to use an ascending or descending order for
169+
each field.
170+
171+
You can specify the sort direction in the following ways:
172+
173+
- Integers ``1`` (ascending) and ``-1`` (descending)
174+
- Example: ``Band.order(name: 1, year: -1)``
175+
176+
- Symbols ``:asc`` and ``:desc``
177+
- Example: ``Band.order(name: :asc)``
178+
179+
- Strings ``"asc"`` and ``"desc"``
180+
- Example: ``Band.order_by(name: "asc", year: "desc")``
181+
182+
The ``order()`` method also accepts the following sort specifications:
183+
184+
- Array of two-element arrays:
185+
186+
- Strings
187+
- Example: ``Band.order([['name', 'asc'], ['year', 'desc']])``
188+
189+
- Symbols
190+
- Example: ``Band.order([[:name, :asc]])``
191+
192+
- ``asc`` and ``desc`` methods on symbols
193+
- Example: ``Band.order(:name.asc, :year.desc)``
194+
195+
- SQL syntax
196+
- Example: ``Band.order('name desc')``
197+
198+
You can also use the ``asc()`` and ``desc()`` methods instead of using
199+
``order()``:
200+
201+
.. code-block:: ruby
202+
203+
Band.asc('name').desc('year')
204+
205+
If you chain sort specifications, the first call defines the most
206+
significant criteria and the newest call defines the least significant
207+
one.
208+
209+
.. TODO update link in the following note for scope
210+
211+
.. note:: Sorting in Scopes
212+
213+
If you define a scope on your model that includes a sort specification,
214+
the scope sort takes precedence over the sort specified in a query, as the
215+
default scope is evaluated first.
216+
217+
.. _mongoid-data-skip-limit:
218+
219+
Paginate Results
220+
----------------
221+
222+
{+odm+} provides the ``limit()``, ``skip()``, and ``batch_size()``
223+
pagination operators that you can use on ``Criteria`` objects. The
224+
following sections describe how to use these operators.
225+
226+
Limit Number of Results
227+
~~~~~~~~~~~~~~~~~~~~~~~
228+
229+
You can limit the number of results that {+odm+} returns by using the
230+
``limit()`` method.
231+
232+
The following code retrieves a maximum of ``5`` documents:
233+
234+
.. literalinclude:: /includes/interact-data/modify-results.rb
235+
:start-after: start-limit
236+
:end-before: end-limit
237+
:language: ruby
238+
:dedent:
239+
240+
Skip Results
241+
~~~~~~~~~~~~
242+
243+
You can skip a specified number of results by using the ``skip()``
244+
method, or its alias ``offset()``. If you chain a ``limit()`` call, it
245+
is applied after documents are skipped.
246+
247+
.. tip::
248+
249+
When performing pagination, you should use ``skip()`` on :ref:`sorted results <mongoid-data-sort>` to ensure consistent results.
250+
251+
The following code skips the first ``3`` documents when returning results:
252+
253+
.. literalinclude:: /includes/interact-data/modify-results.rb
254+
:start-after: start-skip
255+
:end-before: end-skip
256+
:language: ruby
257+
:dedent:
258+
259+
Generate Batches of Results
260+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
261+
262+
When executing large queries and when iterating over query results by using
263+
an enumerator method such as ``Criteria#each()``, {+odm+} automatically
264+
uses the MongoDB :manual:`getMore </reference/command/getMore/>` command
265+
to load results in batches. The default batch size is ``1000``, but
266+
you can set a different value by using the ``batch_size()`` method.
267+
268+
The following code sets the batch size to ``500``:
269+
270+
.. literalinclude:: /includes/interact-data/modify-results.rb
271+
:start-after: start-batch
272+
:end-before: end-batch
273+
:language: ruby
274+
:dedent:
275+
276+
Additional Information
277+
----------------------
278+
279+
.. TODO: add links to the bottom of this page

0 commit comments

Comments
 (0)