diff --git a/source/connect/connection-targets.txt b/source/connect/connection-targets.txt index e4f2ead4d..20e3d09e2 100644 --- a/source/connect/connection-targets.txt +++ b/source/connect/connection-targets.txt @@ -16,6 +16,8 @@ Choose a Connection Target :backlinks: none :depth: 2 :class: singlecol + +.. _node-other-ways-to-connect: Overview -------- diff --git a/source/crud/query/specify-documents-to-return.txt b/source/crud/query/specify-documents-to-return.txt index 508f266ea..b1f225c15 100644 --- a/source/crud/query/specify-documents-to-return.txt +++ b/source/crud/query/specify-documents-to-return.txt @@ -23,6 +23,311 @@ Overview In this guide, you can learn how to specify which documents to return from a read operation by using the following methods: -- ``limit``: Specifies the maximum number of documents to return from a query. -- ``sort``: Specifies the sort order for the returned documents. -- ``skip``: Specifies the number of documents to skip before returning query results. \ No newline at end of file +- ``sort()``: Specifies the sort order for the returned documents. +- ``limit()``: Specifies the maximum number of documents to return from a query. +- ``skip()``: Specifies the number of documents to skip before returning query results. + +You can use these methods either by chaining them to your read operation or by specifying them in an +``options`` object in your call to your read operation. + +.. note:: + + If you chain ``sort()``, ``limit()``, or ``skip()`` to a read operation, you must + specify all methods before iterating the cursor. If you specify a method after + iterating the cursor, the method you specified does not apply to the operation. + +Sample Data for Examples +~~~~~~~~~~~~~~~~~~~~~~~~ + +To run the examples in this guide, use the following code snippet to insert documents +that describe books into the ``myDB.books`` collection: + +.. code-block:: javascript + + const myDB = client.db("myDB"); + const myColl = myDB.collection("books"); + + await myColl.insertMany([ + { "_id": 1, "name": "The Brothers Karamazov", "author": "Dostoyevsky", "length": 824 }, + { "_id": 2, "name": "Les Misérables", "author": "Hugo", "length": 1462 }, + { "_id": 3, "name": "Atlas Shrugged", "author": "Rand", "length": 1088 }, + { "_id": 4, "name": "Infinite Jest", "author": "Wallace", "length": 1104 }, + { "_id": 5, "name": "Cryptonomicon", "author": "Stephenson", "length": 918 }, + { "_id": 6, "name": "A Dance With Dragons", "author": "Martin", "length": 1104 }, + ]); + +.. include:: /includes/access-cursor-note.rst + +.. _node-fundamentals-sort: + +Sort +---- + +Use the ``sort()`` method to change the order in which read operations return +documents. This method tells MongoDB to order returned documents by the +values of one or more fields in a certain direction. To sort returned +documents by a field in ascending (lowest first) order, use a value of +``1``. To sort in descending (greatest first) order instead, use ``-1``. +If you do not specify a sort, MongoDB does not guarantee the order of +query results. + +The following example passes the sort document to a read operation to ensure that the +operation returns books with longer lengths before books with shorter +lengths: + +.. code-block:: javascript + :emphasize-lines: 4 + + // define an empty query document + const query = {}; + // sort in descending (-1) order by length + const sort = { length: -1 }; + const cursor = myColl.find(query).sort(sort); + for await (const doc of cursor) { + console.dir(doc); + } + +In this case, the number ``-1`` tells the read operation to sort the +books in descending order by length. ``find()`` returns the following +documents when this sort is used with an empty query: + +.. code-block:: json + :copyable: false + + { "_id": 2, "title": "Les Misérables", "author": "Hugo", "length": 1462 } + { "_id": 4, "title": "Infinite Jest", "author": "Wallace", "length": 1104 } + { "_id": 6, "title": "A Dance with Dragons", "author": "Martin", "length": 1104 } + { "_id": 3, "title": "Atlas Shrugged", "author": "Rand", "length": 1088 } + { "_id": 5, "title": "Cryptonomicon", "author": "Stephenson", "length": 918 } + { "_id": 1, "title": "The Brothers Karamazov", "author": "Dostoyevsky", "length": 824 } + +Sometimes, the order of two or more documents is ambiguous using a specified sort. In the +preceding example, the documents that have ``title`` values of ``"A Dance with Dragons"`` and +``"Infinite Jest"`` both have a ``length`` of ``1104``, so the order in which they are +returned is not guaranteed. To resolve ties in your sorted results in a repeatable way, +add more fields to the sort document: + +.. code-block:: javascript + :emphasize-lines: 4 + + // define an empty query document + const query = {}; + // sort in ascending (1) order by length + const sort = { length: 1, author: 1 }; + const cursor = myColl.find(query).sort(sort); + for await (const doc of cursor) { + console.dir(doc); + } + +With the addition of the ``author`` field to the sort document, the read operation sorts +matching documents first by ``length`` then, if there is a tie, by ``author``. Matched +document fields are compared in the same order as fields are specified in the sort +document. ``find()`` returns the following ordering of documents when this sort is used on +the documents matching the query: + +.. code-block:: json + :copyable: false + + { "_id": 1, "title": "The Brothers Karamazov", "author": "Dostoyevsky", "length": 824 } + { "_id": 5, "title": "Cryptonomicon", "author": "Stephenson", "length": 918 } + { "_id": 3, "title": "Atlas Shrugged", "author": "Rand", "length": 1088 } + { "_id": 6, "title": "A Dance with Dragons", "author": "Martin", "length": 1104 } + { "_id": 4, "title": "Infinite Jest", "author": "Wallace", "length": 1104 } + { "_id": 2, "title": "Les Misérables", "author": "Hugo", "length": 1462 } + +.. _node-fundamentals-limit: + +Limit +----- + +Use the ``limit()`` method to cap the number of documents that can be returned from a read +operation. This method specifies the maximum number of documents that the operation can +return, but the operation can return a smaller number of documents if there are not enough +documents present to reach the limit. If ``limit()`` is used with the :ref:`skip() +` method, the skip applies first and the limit only applies to the +documents left over after the skip. + +This example performs the following actions: + +- Uses an empty query filter to match all documents in the collection +- Calls the ``sort()`` method to apply a descending sort on the ``length`` field to the results +- Calls the ``limit()`` method to return only the first ``3`` results + +.. code-block:: javascript + :emphasize-lines: 5 + + // define an empty query document + const query = {}; + // sort in descending (-1) order by length + const sort = { length: -1 }; + const limit = 3; + const cursor = myColl.find(query).sort(sort).limit(limit); + for await (const doc of cursor) { + console.dir(doc); + } + +The code example above outputs the following three documents, sorted by +length: + +.. code-block:: json + :copyable: false + + { "_id": 2, "title": "Les Misérables", "author": "Hugo", "length": 1462 } + { "_id": 6, "title": "A Dance With Dragons", "author": "Martin", "length": 1104 } + { "_id": 4, "title": "Infinite Jest", "author": "Wallace", "length": 1104 } + +.. note:: + + The order in which you call ``limit()`` and ``sort()`` does not matter because the + driver reorders the calls to apply the sort first. The following two calls are + equivalent: + + .. code-block:: javascript + + myColl.find(query).sort({ length: -1 }).limit(3); + myColl.find(query).limit(3).sort({ length: -1 }); + +You can also apply ``sort()`` and ``limit()`` by specifying them in an +``options`` object in your call to the ``find()`` method. The following two +calls are equivalent: + +.. code-block:: javascript + + myColl.find(query).sort({ length: -1 }).limit(3); + myColl.find(query, { sort: { length: -1 }, limit: 3 }); + +For more information on the ``options`` settings for the ``find()`` +method, see the +`API documentation on find() <{+api+}/classes/Collection.html#find>`__. + +.. _node-fundamentals-skip: + +Skip +---- + +Use the ``skip()`` method to omit documents from the beginning of the read operation +results. You can combine ``skip()`` with +:ref:`sort() ` to omit the top +(for descending order) or bottom (for ascending order) results for a +given query. Since the :manual:`order of documents returned +` is not guaranteed in +the absence of a sort, using ``skip()`` without using ``sort()`` omits +arbitrary documents. + +If the value of ``skip()`` exceeds the number of matched documents for +a query, then that query returns no documents. + +This example queries the collection for the books with the fifth and sixth highest lengths +by performing the following actions: + +- Uses an empty query filter to match all documents in the collection +- Calls the ``sort()`` method to apply a descending sort to the ``length`` field, which returns longer books before shorter books +- Calls the ``skip()`` method to omit the first four matching documents from the result + +.. code-block:: javascript + + // define an empty query document + const query = {}; + const sort = { length: -1 }; + const skip = 4; + const cursor = myColl.find(query).sort(sort).skip(skip); + for await (const doc of cursor) { + console.dir(doc); + } + +Since the query skips the first four matching documents, the preceding code snippet prints +the fifth and sixth highest length documents: + +.. code-block:: json + :copyable: false + + { "_id": 5, "title": "Cryptonomicon", "author": "Stephenson", "length": 918 } + { "_id": 1, "title": "The Brothers Karamazov", "author": "Dostoyevsky", "length": 824 } + +You can also apply ``skip()`` and ``sort()`` by specifying them in an +``options`` object in your call to the ``find()`` method. The following two +calls are equivalent: + +.. code-block:: javascript + + myColl.find(query).sort({ length: -1 }).skip(4); + myColl.find(query, { sort: { length: -1 }, skip: 4}); + +For more information on the ``options`` settings for the ``find()`` +method, see the +`API documentation on find() <{+api+}/classes/Collection.html#find>`__. + +.. _node-fundamentals-combine-lim-sort-skip: + +Combine Limit, Sort, and Skip +----------------------------- + +You can combine the ``limit``, ``sort``, and ``skip`` options in a single +operation. This allows you to set a maximum number of sorted documents to +return, skipping a specified number of documents before returning. + +The following example returns documents with the ``length`` value of +``"1104"``. The results are sorted in alphabetical order, skipping the first +document and includes only the first result: + +.. code-block:: javascript + + // define a query to look for length value of 1104 + const query = {length: "1104"}; + const options = { + // sort in alphabetical (1) order by title + sort : { title: 1 }, + // omit the first document + skip : 1, + // returns only the first result + limit: 1, + } + const cursor = myColl.find(query, options); + for await (const doc of cursor) { + console.dir(doc); + } + +.. code-block:: json + :copyable: false + + { "_id": 4, "title": "Infinite Jest", "author": "Wallace", "length": 1104 } + +.. note:: + + The order in which you call these methods doesn't change the documents + that are returned. The driver automatically reorders the calls to perform the + sort and skip operations first, and the limit operation afterward. + +You can also limit, sort, and skip results by chaining each method to the ``find`` method. +The following example specifies the same query as the preceding example: + +.. io-code-block:: + + .. input:: + :language: javascript + + myColl.find(query).sort({ title: 1 }).skip(1).limit(1); + + .. output:: + :language: json + :visible: false + + { "_id": 4, "title": "Infinite Jest", "author": "Wallace", "length": 1104 } + +Additional Information +---------------------- + +For more information about specifying a query, see :ref:`node-query`. + +For more information about retrieving documents, see :ref:`node-fundamentals-retrieve-data`. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods discussed in this +guide, see the following API documentation: + +- `find() <{+api+}/classes/Collection.html#find>`__ +- `limit() <{+api+}/classes/FindCursor.html#limit>`__ +- `sort() <{+api+}/classes/FindCursor.html#sort>`__ +- `skip() <{+api+}/classes/FindCursor.html#skip>`__ \ No newline at end of file diff --git a/source/includes/access-cursor-note.rst b/source/includes/access-cursor-note.rst index c3ad63f56..c72bac066 100644 --- a/source/includes/access-cursor-note.rst +++ b/source/includes/access-cursor-note.rst @@ -3,4 +3,4 @@ Your query operation may return a reference to a cursor that contains matching documents. To learn how to examine data stored in the cursor, see the - :doc:`Cursor Fundamentals page `. \ No newline at end of file + :ref:`Access Data From a Cursor page `.