Skip to content

DOCS-874 changes to push operator #701

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

Closed
wants to merge 1 commit into from
Closed
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
45 changes: 34 additions & 11 deletions source/reference/operator/each.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,44 @@
$each
=====

.. default-domain:: mongodb

.. note::

The :mongodb:operator:`$each` operator is only used with the
:mongodb:operator:`$addToSet` see the documentation of
:doc:`/reference/operator/addToSet` for more information.

.. default-domain:: mongodb
The :operator:`$each` modifier is only used with the
:operator:`$addToSet` operator and the :operator:`$push` operator.
See the documentation of :operator:`$addToSet` and :operator:`$push`
for more information.

.. operator:: $each

The :operator:`$each` operator is available within the
:operator:`$addToSet`, which allows you to add multiple values
to the array if they do not exist in the ``field`` array in a
single operation. Consider the following prototype:
The :operator:`$each` modifier is available for use with the
:operator:`$addToSet` operator and the :operator:`$addToSet`
operator.

- Use the :operator:`$each` modifier with the :operator:`$addToSet`
operator to add multiple values to an array ``<field>`` if the
values do not exist in the ``<field>``.

.. code-block:: javascript

db.collection.update( <query>,
{
$addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } }
}
)

- Use the :operator:`$each` modifier with the :operator:`$push`
operator to append multiple values to an array ``<field>``.

.. code-block:: javascript

.. code-block:: javascript
db.collection.update( <query>,
{
$push: { <field>: { $each: [ <value1>, <value2> ... ] } }
}
)

db.collection.update( { field: value }, { $addToSet: { field: { $each : [ value1, value2, value3 ] } } } );
.. versionchanged:: 2.4
Before MongoDB 2.4, :operator:`$each` modifier was not available for
use with the :operator:`$push` operator.
93 changes: 77 additions & 16 deletions source/reference/operator/push.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,87 @@ $push

.. operator:: $push

The :operator:`$push` operator appends a specified value to an array. For
example:
The :operator:`$push` operator appends a specified value to an array.

.. code-block:: javascript

db.collection.update( { field: value }, { $push: { field: value1 } } );
db.collection.update( <query>,
{ $push: { <field>: <value> } }
)

Here, :operator:`$push` appends ``value1`` to the array identified by
``value`` in ``field``. Be aware of the following behaviors:
The following example appends ``89`` to the ``scores`` array for the
first document where the ``name`` field equals ``joe``:

- If the field specified in the :operator:`$push` statement
(e.g. ``{ $push: { field: value1 } }``) does not exist in the
matched document, the operation adds a new array with the
specified field and value (e.g. ``value1``) to the matched
document.
.. code-block:: javascript

db.students.update(
{ name: "joe" },
{ $push: { scores: 89 } }
)

.. note::

- If the field is absent in the document to update, the
operation adds the array field with the value as its
element.

- If the field is **not** an array, the operation will fail.

- If the value is an array, :operator:`$push` appends the whole
array as a *single* element. To add each element of the value
separately, use :operator:`$push` with the :operator:`$each`
modifier.

The following example appends each element of ``[ 90, 92, 85 ]`` to
the ``scores`` array for the document where the ``name`` field
equals ``joe``:

.. code-block:: javascript

db.students.update(
{ name: "joe" },
{ $push: { scores: { $each: [ 90, 92, 85 ] } } }
)

.. versionchanged:: 2.4
Before MongoDB 2.4, :operator:`$each` modifier was
unavailable for use with :operator:`$push`.
Instead, you would use the :operator:`$pushAll` operator to
add each element separately.

- The operation will fail if the field specified in the
:operator:`$push` statement is *not* an array. :operator:`$push`
does not fail when pushing a value to a non-existent field.
.. versionchanged:: 2.4
You can use the :operator:`$push` operator with the following
modifiers:

- :operator:`$each` to append multiple values to the array field,

- :operator:`$slice` to limit the number of array elements and
which must be used with :operator:`$each`, and

- :operator:`$sort` to order the array elements, and which must be
used with :operator:`$slice`, and can **only** sort arrays that
contain documents.

The following example uses:

- the :operator:`$each` modifier to append documents to the
``quizzes`` array,

- the :operator:`$sort` modifier to sort all the elements of the
modified ``quizzes`` array by the ascending ``score`` field, and

- the :operator:`$slice` modifier to keep only the **last** five
sorted elements of the ``quizzes`` array.

.. code-block:: javascript

- If ``value1`` is an array itself, :operator:`$push` appends the whole array as an
element in the identified array. To add multiple items to an
array, use :operator:`$pushAll`.
db.students.update( { name: "joe" },
{ $push: { quizzes: { $each: [ { id: 3, score: 8 },
{ id: 4, score: 7 },
{ id: 5, score: 6 } ],
$sort: { score: 1 },
$slice: -5
}
}
}
)
3 changes: 3 additions & 0 deletions source/reference/operator/pushAll.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ $pushAll

.. operator:: $pushAll

.. deprecated:: 2.4
Use the :operator:`$push` operator with :operator:`$each` instead.

The :operator:`$pushAll` operator is similar to the :operator:`$push` but
adds the ability to append several values to an array at once.

Expand Down
52 changes: 52 additions & 0 deletions source/reference/operator/slice.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
======
$slice
======

.. default-domain:: mongodb

.. operator:: $slice

.. versionadded:: 2.4

The :operator:`$slice` modifier limits the number of array
elements during a :operator:`$push` operation. To project, or return,
a specified number of array elements from a read operation, see the
:projection:`$slice` projection operator instead.

To use the :operator:`$slice` modifier, it must appear with the
:operator:`$each` modifier, *and* the :operator:`$each` modifier must
be the first modifier for the :operator:`$push` operation.

.. code-block:: javascript

db.collection.update( <query>,
{ $push: {
<field>: {
$each: [ <value1>, <value2>, ... ],
$slice: <num>
}
}
}
)

The ``<num>`` is either a **negative** number or **zero**
[#future-num-values]_:

- If ``<num>`` is **negative**, the array ``<field>`` contains only
the last ``<num>`` elements.

- If ``<num>`` is **zero**, the array ``<field>`` is an empty array.

.. code-block:: javascript

db.students.update( { _id: 2 },
{ $push: { grades: {
$each: [ 80, 78, 86 ],
$slice: -5
}
}
}
)

.. [#future-num-values] In future releases, ``<num>`` will accept
positive numbers as well as negative numbers and zero.
91 changes: 91 additions & 0 deletions source/reference/operator/sort.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
=====
$sort
=====

.. default-domain:: mongodb

.. operator:: $sort

.. versionadded:: 2.4

The :operator:`$sort` modifier orders the elements of an array
during a :operator:`$push` operation. The elements of the array
**must** be documents [#future-arrary-elements]_.

To apply the :operator:`$sort` modifier, it must appear **with** the
:operator:`$each` and :operator:`$slice` modifiers, *and* the
:operator:`$each` modifier must be the first modifier for the
:operator:`$push` operation.

.. code-block:: javascript

db.collection.update( <query>,
{ $push: {
<field>: {
$each: [ <document1>,
<document2>,
...
],
$slice: <num>,
$sort: <sort document>,
}
}
}
)

.. important::

The ``<sort document>`` only accesses the fields from the
elements in the array and does **not** refer to the array
``<field>``.

Consider the following example where the collection ``students``
contain the following document:

.. code-block:: javascript

{ "_id": 3,
"name": "joe",
"quizzes": [
{ "id" : 1, "score" : 6 },
{ "id" : 2, "score" : 9 }
]
}

The following update appends additional documents to the ``quizzes``
array, sorts all the elements of the array by ascending ``score``
field, and slices the array to keep the last five elements:

.. code-block:: javascript

db.students.update( { name: "joe" },
{ $push: { quizzes: { $each: [ { id: 3, score: 8 },
{ id: 4, score: 7 },
{ id: 5, score: 6 } ],
$sort: { score: 1 },
$slice: -5
}
}
}
)

After the update, the array elements are in order of ascending
``score`` field.:

.. code-block:: javascript

{
"_id" : 3,
"name" : "joe",
"quizzes" : [
{ "id" : 1, "score" : 6 },
{ "id" : 5, "score" : 6 },
{ "id" : 4, "score" : 7 },
{ "id" : 3, "score" : 8 },
{ "id" : 2, "score" : 9 }
]
}

.. [#future-arrary-elements] In future releases, the
:operator:`$sort` modifier will be able to sort elements of
other types, not just documents.
6 changes: 6 additions & 0 deletions source/reference/operators.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ Array
- :operator:`$pushAll`
- :operator:`$push`

- :operator:`$each` modifier

- :operator:`$slice` modifier

- :operator:`$sort` modifier

Bitwise
~~~~~~~

Expand Down
8 changes: 6 additions & 2 deletions source/reference/projection/slice.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ $slice (projection)

.. projection:: $slice

The :projection:`$slice` operator controls the number of items of an array
that a query returns. Consider the following prototype query:
The :projection:`$slice` operator controls the number of items of an
array that a query returns. For information on limiting the size of
an array during an update with :operator:`$push`, see the
:operator:`$slice` modifier instead.

Consider the following prototype query:

.. code-block:: javascript

Expand Down
15 changes: 15 additions & 0 deletions source/release-notes/2.4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,21 @@ performs an insert, use the :operator:`$setOnInsert` operator with the
update and for :method:`updates <db.collection.update()>` when the
``upsert`` option is ``false``.

``$each``, ``$slice``, and ``$sort`` Available for Use with ``$push``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can now use the :operator:`$push` operator with the following
modifiers:

- :operator:`$each` to append multiple values to the array field,

- :operator:`$slice` to restrict the number of array elements and which
must be used with :operator:`$each`, and

- :operator:`$sort` to order the elements of the array, which
must be used with :operator:`$slice` and can **only** sort
arrays that contain documents.

``--setParameter`` Option Available on the ``mongos`` and ``mongod`` Command Line
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down