Skip to content

DOCSP-48381 make specify docs page #1037

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
298 changes: 297 additions & 1 deletion source/crud/query/specify-documents-to-return.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,300 @@ 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.
- ``skip``: Specifies the number of documents to skip before returning query results.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: can't comment on lines 26-27 but since these are method names, I'd add () to the end of each

Suggested change
- ``skip``: Specifies the number of documents to skip before returning query results.
- ``skip()``: Specifies the number of documents to skip before returning query results.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applies to all mentions of the skip(), sort(), limit() methods


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the best place to mention this or honestly if it is even worth mentioning - but if you use the chaining API you must specify all options before starting to iterate the cursor.

const cursor = find();
await cursor.next();
cursor.limit(5); // does not work

Should we mention this limitation of the builder API somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good information for users to have, thanks for informing me! I added a note about it in the overview section, let me know if the wording is technically correct! Do you know where the API documentation about this would be/if there is any? I was looking in https://mongodb.github.io/node-mongodb-native/6.15/ but couldn't find anything specifically about the chaining API.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't document this, although it might be nice to add to our doc comments. I looked at the code though and we actually throw an error in this scenario. For example, here's the source code for limit:

/**
   * Set the limit for the cursor.
   *
   * @param value - The limit for the cursor query.
   */
  limit(value: number): this {
    this.throwIfInitialized();  // <-- here we throw
    if (this.findOptions.tailable) {
      throw new MongoTailableCursorError('Tailable cursor does not support limit');
    }

    if (typeof value !== 'number') {
      throw new MongoInvalidArgumentError('Operation "limit" requires an integer');
    }

    this.findOptions.limit = value;
    return this;
  }

So I guess, anybody who tries to set these values after the cursor is initialized would see errors. Given that, do you think its worth documenting explicitly here as well? We could also just add a note to the API docs that specify that they will throw if the cursor is initialized.

Also, its worth mentioning that this applies to all our cursor chaining APIs, not just skip/limit/sort. So if we document it, it would be nice to document this behavior more generally than just for these three options, I think? This error is thrown for any option that affects the actual cursor command the driver sends (ex: project, allowDiskUse, comment, etc).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can still leave this note in these docs for now, and based on our discussion in slack about standardization, we also made another ticket about adding a note about this cursor chaining behavior.

Sample Data for Examples
~~~~~~~~~~~~~~~~~~~~~~~~

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: [nit] to avoid repeating follow/following

Suggested change
To follow the examples in this guide, use the following code snippet to insert documents
To run the examples in this guide, use the following code snippet to insert documents

To follow 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-limit:

Limit
-----

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
Use ``limit`` to cap the number of documents that can be returned from a read operation.
Use the ``limit()`` method to cap the number of documents that can be returned from a read operation.

Use ``limit`` to cap the number of documents that can be returned from a read operation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: a little more concise

Suggested change
``limit`` functions as a cap on the maximum number of
``limit`` specifies the maximum number of

``limit`` functions as a cap on 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 <node-fundamentals-skip>` method, the skip applies
first and the limit only applies to the documents left over after
the skip.

The following example queries the collection to return the top three
longest books. It matches all documents because the query filter is
empty. Then, it applies a descending ``sort`` on the ``length`` field to
return longer books before shorter books and a ``limit`` to
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: this might be outside the scope of this PR so optional, but I'd turn this code description into a bulleted list

return only the ``3`` first results:

.. code-block:: javascript
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: emphasize limit instead of sort

Suggested change
:emphasize-lines: 4
:emphasize-lines: 5

:emphasize-lines: 4

// 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;
}

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 and the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
because the driver reorders the calls to apply the sort first and the
limit after it. The following two calls are equivalent:
because the driver reorders the calls to apply the sort first. The following two calls are equivalent:

limit after it. 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
----

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
Use ``skip`` to omit documents from the beginning of the list of
Use the ``skip()`` method to omit documents from the beginning of the list of

Use ``skip`` to omit documents from the beginning of the list of
returned documents for a read operation. You can combine ``skip`` with
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: since we're getting rid of this individual sort page, you can add a ref anchor to the sort section on this page and link to that here instead

:doc:`sort </fundamentals/crud/read-operations/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
</reference/method/cursor.sort/#result-ordering>` 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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: same suggestion here about using a bulleted list; also, I'd avoid "we" by rewording slightly

Suggested change
In the following example, we query the collection with a filter that
The following example queries the collection with a filter that

In the following example, we query the collection with a filter that
matches all the documents and pass options that specifies ``sort`` and
``skip`` commands as query options. The sort option specifies that fruit
documents that have higher ``length`` values are returned before ones with lower
lengths. The skip option specifies that the first document is
omitted from the result:

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: I would stay consistent with focusing on either the limit/sort/skip methods or options. You can modify this section to introduce the skip() method, then add a note after that describes the skip option as an alternative - or edit the previous section to do the opposite.

.. code-block:: javascript

// define an empty query document
const query = {};
const options = {
// sort in descending (-1) order by length
sort : { length: -1 },
// omit the first document
skip : 1,
}

const cursor = myColl.find(query, options);
for await (const doc of cursor) {
console.dir(doc);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
Since we specified that query skip the first document, the code snippet above prints
Since the query skips the first matching document, the preceding code snippet prints

Since we specified that query skip the first document, the code snippet above prints
the second and third highest length documents:

.. code-block:: json
:copyable: false

{ "_id": 4, "name": "Infinite Jest", "author": "Wallace", "length": 1104 },
{ "_id": 6, "name": "A Dance With Dragons", "author": "Martin", "length": 1104 }


The ``sort`` and ``skip`` options can also be specified as methods chained to
the ``find`` method. The following two commands are equivalent:

.. code-block:: javascript

myColl.find(query, { sort: { rating: -1}, skip: 1});
myColl.find(query).sort({rating: -1}).skip(1);

Sort
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: since you use sort in the skip example, I'd move this section before "Skip"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I actually think the Sort section should come first (before both skip and limit) since it's used in both of them, should've clarified that last time oops

----

Use ``sort`` to change the order in which read operations return
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: similar suggestion as other sections; also to avoid capitalization of Sort:

Suggested change
Use ``sort`` to change the order in which read operations return
documents. ``Sort`` tells MongoDB to order returned documents by the
Use the ``sort()`` method to change the order in which read operations return
documents. This method tells MongoDB to order returned documents by the

documents. ``Sort`` 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.

In the following example, we pass the sort document to a read operation to ensure that the
operation returns books with longer lengths before books with shorter
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
In the following example, we pass the sort document to a read operation to ensure that the
operation returns books with longer lengths before books with shorter
lengths:
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:

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 above case, both "A Dance with Dragons" and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
specified sort. In the above case, both "A Dance with Dragons" and
"Infinite Jest" have ``1104`` pages, so the order in which they are
specified sort. In the above case, 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

"Infinite Jest" have ``1104`` pages, 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, sorting ``"Martin"`` before ``"Wallace"`` for the two books with
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: I'd remove some extra detail here

Suggested change
document. ``find()`` returns the following ordering of documents when this sort is used on
the documents matching the query, sorting ``"Martin"`` before ``"Wallace"`` for the two books with
the same length:
document. ``find()`` returns the following ordering of documents when this sort is used on
the query:

the same length:

.. 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 }

Combine Limit, Sort, and Skip
-----------------------------

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
You can combine ``limit``, ``sort``, and ``skip`` in a single
You can combine the ``limit``, ``sort``, and ``skip`` options in a single

You can combine ``limit``, ``sort``, and ``skip`` 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I: this example is missing limit

document:

.. code-block:: javascript
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: I don't think you need to emphasize any lines here

:emphasize-lines: 5

// 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,
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I: this method call doesn't apply the options

Suggested change
const cursor = myColl.find(query).sort(sort);
const cursor = myColl.find(query, options);

const cursor = myColl.find(query).sort(sort);
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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I: the previous example does specify these as parameters (an options parameter) to the find() method. Either you can show how to specify each as methods chained to find(), or omit this part

You can also limit, sort, and skip results by specifying them as
parameters in 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});

.. 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
~~~~~~~~~~~~~~~~~

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: since these are just methods

Suggested change
To learn more about any of the methods or types discussed in this
To learn more about any of the methods discussed in this

To learn more about any of the methods or types discussed in this
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
guide, see the following API Documentation:
guide, see the following API documentation:

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>`__
2 changes: 1 addition & 1 deletion source/includes/access-cursor-note.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 </fundamentals/crud/read-operations/cursor>`.
:doc:`Access Data From a Cursor page </crud/query/cursor>`.
Loading