Skip to content

DOCSP-13696 correct sort stability language #4909

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
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions source/includes/fact-sort-consistency.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
MongoDB does not store documents in a collection in a particular order.
When sorting on a field which contains duplicate values, documents
containing those values may be returned in any order.

If consistent sort order is desired, include at least one field in your
sort that contains unique values. The easiest way to guarantee this is
to include the ``_id`` field in your sort query.
11 changes: 0 additions & 11 deletions source/includes/fact-sort-stability.rst

This file was deleted.

6 changes: 3 additions & 3 deletions source/reference/command/findAndModify.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Definition



* - .. _findandmodify-command-stable-sorting:
* - .. _findandmodify-command-consistent-sorting:

``sort``

Expand All @@ -94,9 +94,9 @@ Definition
Starting in MongoDB 4.2 (and 4.0.12+, 3.6.14+, and 3.4.23+), the operation
errors if the sort argument is not a document.

.. include:: /includes/fact-sort-stability.rst
.. include:: /includes/fact-sort-consistency.rst

See :ref:`sort-cursor-stable-sorting` for more information.
See :ref:`sort-cursor-consistent-sorting` for more information.



Expand Down
20 changes: 12 additions & 8 deletions source/reference/method/cursor.limit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,15 @@ Using ``limit()`` with ``sort()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If using :method:`~cursor.limit()` with :method:`~cursor.sort()`, be
sure that you are performing a *stable sort* before passing
results to :method:`~cursor.limit()`. A stable sort ensures that the
sort order of returned documents remains the same across multiple
executions of the same sort; especially important when used with the
:method:`~cursor.limit()` method.

See :ref:`Stable sorting with the sort() method
<sort-cursor-stable-sorting>` for more information.
sure to include at least one field in your sort that contains
unique values, before passing results to :method:`~cursor.limit()`.

Sorting on fields that contain duplicate values may return an
inconsistent sort order for those duplicate fields over multiple
executions, especially when the collection is actively receiving writes.

The easiest way to guarantee sort consistency is to include the
``_id`` field in your sort query.

See :ref:`Consistent sorting with the sort() method
<sort-cursor-consistent-sorting>` for more information.
22 changes: 13 additions & 9 deletions source/reference/method/cursor.skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,19 @@ Behavior
Using ``skip()`` with ``sort()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If using :method:`~cursor.skip()` with :method:`~cursor.sort()`,
be sure that you are performing a *stable sort* before passing
results to :method:`~cursor.skip()`. A stable sort ensures that the sort
order of returned documents remains the same across multiple executions
of the same sort; especially important when used with the
:method:`~cursor.skip()` method.

See :ref:`Stable sorting with the sort() method
<sort-cursor-stable-sorting>` for more information.
If using :method:`~cursor.skip()` with :method:`~cursor.sort()`, be
sure to include at least one field in your sort that contains
unique values, before passing results to :method:`~cursor.skip()`.

Sorting on fields that contain duplicate values may return an
inconsistent sort order for those duplicate fields over multiple
executions, especially when the collection is actively receiving writes.

The easiest way to guarantee sort consistency is to include the
``_id`` field in your sort query.

See :ref:`Consistent sorting with the sort() method
<sort-cursor-consistent-sorting>` for more information.

Pagination Example
------------------
Expand Down
19 changes: 9 additions & 10 deletions source/reference/method/cursor.sort.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ Definition
Behaviors
---------

.. _sort-cursor-stable-sorting:
.. _sort-cursor-consistent-sorting:

Sort Stability
~~~~~~~~~~~~~~
Sort Consistency
~~~~~~~~~~~~~~~~

.. versionchanged:: 4.4

.. include:: /includes/fact-sort-stability.rst
.. include:: /includes/fact-sort-consistency.rst

Consider the following ``restaurant`` collection:

Expand All @@ -88,13 +88,12 @@ on the ``borough`` field:

db.restaurants.find().sort( { "borough": 1 } )

In this example, the sort is *unstable*, since the ``borough`` field
contains duplicate values for both ``Manhattan`` and ``Brooklyn``.
In this example, sort order may be inconsistent, since the ``borough``
field contains duplicate values for both ``Manhattan`` and ``Brooklyn``.
Documents are returned in alphabetical order by ``borough``, but the
order of those documents with duplicate values for ``borough`` might not
the be the same across multiple executions of the same sort. For
example, here are the results from two different executions of the
above command:
be the same across multiple executions of the same sort. For example,
here are the results from two different executions of the above command:

.. code-block:: js
:copyable: false
Expand All @@ -115,7 +114,7 @@ While the values for ``borough`` are still sorted in alphabetical order,
the order of the documents containing duplicate values for ``borough``
(i.e. ``Manhattan`` and ``Brooklyn``) is not the same.

To achieve a *stable sort*, add a field which contains exclusively
To achieve a *consistent sort*, add a field which contains exclusively
unique values to the sort. The following command uses the
:method:`~cursor.sort()` method to sort on both the ``borough`` field
and the ``_id`` field:
Expand Down
6 changes: 3 additions & 3 deletions source/reference/method/db.collection.findAndModify.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Definition



* - .. _findandmodify-method-stable-sorting:
* - .. _findandmodify-method-consistent-sorting:

``sort``

Expand All @@ -102,9 +102,9 @@ Definition
Starting in MongoDB 4.2 (and 4.0.12+, 3.6.14+, and 3.4.23+), the operation
errors if the sort argument is not a document.

.. include:: /includes/fact-sort-stability.rst
.. include:: /includes/fact-sort-consistency.rst

See :ref:`sort-cursor-stable-sorting` for more information.
See :ref:`sort-cursor-consistent-sorting` for more information.



Expand Down
32 changes: 18 additions & 14 deletions source/reference/operator/aggregation/limit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,28 @@ If using the :pipeline:`$limit` stage with any of:
- the :pipeline:`$sort` aggregation stage,
- the :method:`~cursor.sort()` method, or
- the ``sort`` field to the :dbcommand:`findAndModify` command or the
:method:`~db.collection.findAndModify()` shell method.
:method:`~db.collection.findAndModify()` shell method,

be sure that you are performing a *stable sort* before passing results
to the :pipeline:`$limit` stage. A stable sort ensures that the sort
order of returned documents remains the same across multiple executions
of the same sort; especially important when used with the
:pipeline:`$limit` stage.
be sure to include at least one field in your sort that contains
unique values, before passing results to the :pipeline:`$limit` stage.

Sorting on fields that contain duplicate values may return an
inconsistent sort order for those duplicate fields over multiple
executions, especially when the collection is actively receiving writes.

The easiest way to guarantee sort consistency is to include the
``_id`` field in your sort query.

See the following for more information on each:

- :ref:`Stable sorting with $sort (aggregation)
<sort-aggregation-stable-sorting>`
- :ref:`Stable sorting with the sort() method
<sort-cursor-stable-sorting>`
- :ref:`Stable sorting with the findAndModify command
<findandmodify-command-stable-sorting>`
- :ref:`Stable sorting with the findAndModify() method
<findandmodify-method-stable-sorting>`
- :ref:`Consistent sorting with $sort (aggregation)
<sort-aggregation-consistent-sorting>`
- :ref:`Consistent sorting with the sort() shell method
<sort-cursor-consistent-sorting>`
- :ref:`Consistent sorting with the findAndModify command
<findandmodify-command-consistent-sorting>`
- :ref:`Consistent sorting with the findAndModify() shell method
<findandmodify-method-consistent-sorting>`

Example
-------
Expand Down
32 changes: 18 additions & 14 deletions source/reference/operator/aggregation/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,28 @@ If using the :pipeline:`$skip` stage with any of:
- the :pipeline:`$sort` aggregation stage,
- the :method:`~cursor.sort()` method, or
- the ``sort`` field to the :dbcommand:`findAndModify` command or the
:method:`~db.collection.findAndModify()` shell method.
:method:`~db.collection.findAndModify()` shell method,

be sure that you are performing a *stable sort* before passing results
to the :pipeline:`$skip` stage. A stable sort ensures that the sort
order of returned documents remains the same across multiple executions
of the same sort; especially important when used with the
:pipeline:`$skip` stage.
be sure to include at least one field in your sort that contains
unique values, before passing results to the :pipeline:`$skip` stage.

Sorting on fields that contain duplicate values may return a different
sort order for those duplicate fields over multiple executions,
especially when the collection is actively receiving writes.

The easiest way to guarantee sort consistency is to include the
``_id`` field in your sort query.

See the following for more information on each:

- :ref:`Stable sorting with $sort (aggregation)
<sort-aggregation-stable-sorting>`
- :ref:`Stable sorting with the sort() method
<sort-cursor-stable-sorting>`
- :ref:`Stable sorting with the findAndModify command
<findandmodify-command-stable-sorting>`
- :ref:`Stable sorting with the findAndModify() method
<findandmodify-method-stable-sorting>`
- :ref:`Consistent sorting with $sort (aggregation)
<sort-aggregation-consistent-sorting>`
- :ref:`Consistent sorting with the sort() shell method
<sort-cursor-consistent-sorting>`
- :ref:`Consistent sorting with the findAndModify command
<findandmodify-command-consistent-sorting>`
- :ref:`Consistent sorting with the findAndModify() shell method
<findandmodify-method-consistent-sorting>`

Example
-------
Expand Down
14 changes: 7 additions & 7 deletions source/reference/operator/aggregation/sort.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ Definition
Behavior
--------

.. _sort-aggregation-stable-sorting:
.. _sort-aggregation-consistent-sorting:

Sort Stability
~~~~~~~~~~~~~~
Sort Consistency
~~~~~~~~~~~~~~~~

.. include:: /includes/fact-sort-stability.rst
.. include:: /includes/fact-sort-consistency.rst

Consider the following ``restaurant`` collection:

Expand All @@ -85,8 +85,8 @@ the ``borough`` field:
]
)

In this example, the sort is *unstable*, since the ``borough`` field
contains duplicate values for both ``Manhattan`` and ``Brooklyn``.
In this example, sort order may be inconsistent, since the ``borough``
field contains duplicate values for both ``Manhattan`` and ``Brooklyn``.
Documents are returned in alphabetical order by ``borough``, but the
order of those documents with duplicate values for ``borough`` might not
the be the same across multiple executions of the same sort. For
Expand All @@ -112,7 +112,7 @@ While the values for ``borough`` are still sorted in alphabetical order,
the order of the documents containing duplicate values for ``borough``
(i.e. ``Manhattan`` and ``Brooklyn``) is not the same.

To achieve a *stable sort*, add a field which contains exclusively
To achieve a *consistent sort*, add a field which contains exclusively
unique values to the sort. The following command uses the
:pipeline:`$sort` stage to sort on both the ``borough`` field and the
``_id`` field:
Expand Down
8 changes: 4 additions & 4 deletions source/release-notes/4.4-compatibility.txt
Original file line number Diff line number Diff line change
Expand Up @@ -182,23 +182,23 @@ Text Search Metadata { $meta: "textScore" } Query Requirement

.. include:: /includes/extracts/4.4-changes-textscore-predicate.rst

``$sort`` Stability Changes
---------------------------
``$sort`` Changes
-----------------

Starting in MongoDB 4.4, the :method:`~cursor.sort()` method now uses
the same sort algorithm as the :pipeline:`$sort` aggregation stage. With
this change, queries which perform a :method:`~cursor.sort()` on
fields that contain duplicate values are much more likely to result in
inconsistent sort orders for those values.

To guarantee sort stability when using :method:`~cursor.sort()` on
To guarantee sort consistency when using :method:`~cursor.sort()` on
duplicate values, include an additional field in your sort that contains
exclusively unique values.

This can be accomplished easily by adding the ``_id`` field to your
sort.

See :ref:`sort-cursor-stable-sorting` for more information.
See :ref:`sort-cursor-consistent-sorting` for more information.

Map Reduce Changes
------------------
Expand Down
8 changes: 4 additions & 4 deletions source/release-notes/4.4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1020,23 +1020,23 @@ Transactions
Sorting
-------

``$sort`` Stability Changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
``$sort`` Changes
~~~~~~~~~~~~~~~~~

Starting in MongoDB 4.4, the :method:`~cursor.sort()` method now uses
the same sort algorithm as the :pipeline:`$sort` aggregation stage. With
this change, queries which perform a :method:`~cursor.sort()` on
fields that contain duplicate values are much more likely to result in
inconsistent sort orders for those values.

To guarantee sort stability when using :method:`~cursor.sort()` on
To guarantee sort consistency when using :method:`~cursor.sort()` on
duplicate values, include an additional field in your sort that contains
exclusively unique values.

This can be accomplished easily by adding the ``_id`` field to your
sort.

See :ref:`sort-cursor-stable-sorting` for more information.
See :ref:`sort-cursor-consistent-sorting` for more information.

Security Improvements
---------------------
Expand Down