Merge branch 'master' of github.com:mongodb/mongo-python-driver
This commit is contained in:
commit
be9cbd1397
@ -38,36 +38,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
2) License Notice for bson-stdint-win32.h
|
||||
-----------------------------------------
|
||||
|
||||
ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
|
||||
Copyright (c) 2006-2013 Alexander Chemeris
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the product nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@ -19,6 +19,10 @@ PyMongo 4.11 brings a number of changes including:
|
||||
until either connection succeeds or a server selection timeout error is raised.
|
||||
- Added :func:`repr` support to :class:`pymongo.operations.IndexModel`.
|
||||
- Added :func:`repr` support to :class:`pymongo.operations.SearchIndexModel`.
|
||||
- Added ``sort`` parameter to
|
||||
:meth:`~pymongo.collection.Collection.update_one`, :meth:`~pymongo.collection.Collection.replace_one`,
|
||||
:class:`~pymongo.operations.UpdateOne`, and
|
||||
:class:`~pymongo.operations.UpdateMany`,
|
||||
|
||||
Issues Resolved
|
||||
...............
|
||||
|
||||
@ -109,6 +109,7 @@ class _AsyncBulk:
|
||||
self.uses_array_filters = False
|
||||
self.uses_hint_update = False
|
||||
self.uses_hint_delete = False
|
||||
self.uses_sort = False
|
||||
self.is_retryable = True
|
||||
self.retrying = False
|
||||
self.started_retryable_write = False
|
||||
@ -144,6 +145,7 @@ class _AsyncBulk:
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
array_filters: Optional[list[Mapping[str, Any]]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create an update document and add it to the list of ops."""
|
||||
validate_ok_for_update(update)
|
||||
@ -159,6 +161,9 @@ class _AsyncBulk:
|
||||
if hint is not None:
|
||||
self.uses_hint_update = True
|
||||
cmd["hint"] = hint
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
if multi:
|
||||
# A bulk_write containing an update_many is not retryable.
|
||||
self.is_retryable = False
|
||||
@ -171,6 +176,7 @@ class _AsyncBulk:
|
||||
upsert: bool = False,
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create a replace document and add it to the list of ops."""
|
||||
validate_ok_for_replace(replacement)
|
||||
@ -181,6 +187,9 @@ class _AsyncBulk:
|
||||
if hint is not None:
|
||||
self.uses_hint_update = True
|
||||
cmd["hint"] = hint
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
self.ops.append((_UPDATE, cmd))
|
||||
|
||||
def add_delete(
|
||||
@ -699,6 +708,10 @@ class _AsyncBulk:
|
||||
raise ConfigurationError(
|
||||
"Must be connected to MongoDB 4.2+ to use hint on unacknowledged update commands."
|
||||
)
|
||||
if unack and self.uses_sort and conn.max_wire_version < 25:
|
||||
raise ConfigurationError(
|
||||
"Must be connected to MongoDB 8.0+ to use sort on unacknowledged update commands."
|
||||
)
|
||||
# Cannot have both unacknowledged writes and bypass document validation.
|
||||
if self.bypass_doc_val:
|
||||
raise OperationFailure(
|
||||
|
||||
@ -118,6 +118,7 @@ class _AsyncClientBulk:
|
||||
self.uses_array_filters = False
|
||||
self.uses_hint_update = False
|
||||
self.uses_hint_delete = False
|
||||
self.uses_sort = False
|
||||
|
||||
self.is_retryable = self.client.options.retry_writes
|
||||
self.retrying = False
|
||||
@ -148,6 +149,7 @@ class _AsyncClientBulk:
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
array_filters: Optional[list[Mapping[str, Any]]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create an update document and add it to the list of ops."""
|
||||
validate_ok_for_update(update)
|
||||
@ -169,6 +171,9 @@ class _AsyncClientBulk:
|
||||
if collation is not None:
|
||||
self.uses_collation = True
|
||||
cmd["collation"] = collation
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
if multi:
|
||||
# A bulk_write containing an update_many is not retryable.
|
||||
self.is_retryable = False
|
||||
@ -184,6 +189,7 @@ class _AsyncClientBulk:
|
||||
upsert: Optional[bool] = None,
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create a replace document and add it to the list of ops."""
|
||||
validate_ok_for_replace(replacement)
|
||||
@ -202,6 +208,9 @@ class _AsyncClientBulk:
|
||||
if collation is not None:
|
||||
self.uses_collation = True
|
||||
cmd["collation"] = collation
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
self.ops.append(("replace", cmd))
|
||||
self.namespaces.append(namespace)
|
||||
self.total_ops += 1
|
||||
|
||||
@ -993,6 +993,7 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
session: Optional[AsyncClientSession] = None,
|
||||
retryable_write: bool = False,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> Optional[Mapping[str, Any]]:
|
||||
"""Internal update / replace helper."""
|
||||
@ -1024,6 +1025,14 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
if not isinstance(hint, str):
|
||||
hint = helpers_shared._index_document(hint)
|
||||
update_doc["hint"] = hint
|
||||
if sort is not None:
|
||||
if not acknowledged and conn.max_wire_version < 25:
|
||||
raise ConfigurationError(
|
||||
"Must be connected to MongoDB 8.0+ to use sort on unacknowledged update commands."
|
||||
)
|
||||
common.validate_is_mapping("sort", sort)
|
||||
update_doc["sort"] = sort
|
||||
|
||||
command = {"update": self.name, "ordered": ordered, "updates": [update_doc]}
|
||||
if let is not None:
|
||||
common.validate_is_mapping("let", let)
|
||||
@ -1079,6 +1088,7 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
session: Optional[AsyncClientSession] = None,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> Optional[Mapping[str, Any]]:
|
||||
"""Internal update / replace helper."""
|
||||
@ -1102,6 +1112,7 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
session=session,
|
||||
retryable_write=retryable_write,
|
||||
let=let,
|
||||
sort=sort,
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
@ -1122,6 +1133,7 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
session: Optional[AsyncClientSession] = None,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> UpdateResult:
|
||||
"""Replace a single document matching the filter.
|
||||
@ -1176,8 +1188,13 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
aggregate expression context (e.g. "$$var").
|
||||
:param comment: A user-provided comment to attach to this
|
||||
command.
|
||||
:param sort: Specify which document the operation updates if the query matches
|
||||
multiple documents. The first document matched by the sort order will be updated.
|
||||
This option is only supported on MongoDB 8.0 and above.
|
||||
:return: - An instance of :class:`~pymongo.results.UpdateResult`.
|
||||
|
||||
.. versionchanged:: 4.11
|
||||
Added ``sort`` parameter.
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
Added ``comment`` parameter.
|
||||
@ -1209,6 +1226,7 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint=hint,
|
||||
session=session,
|
||||
let=let,
|
||||
sort=sort,
|
||||
comment=comment,
|
||||
),
|
||||
write_concern.acknowledged,
|
||||
@ -1225,6 +1243,7 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
session: Optional[AsyncClientSession] = None,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> UpdateResult:
|
||||
"""Update a single document matching the filter.
|
||||
@ -1283,11 +1302,16 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
:param sort: Specify which document the operation updates if the query matches
|
||||
multiple documents. The first document matched by the sort order will be updated.
|
||||
This option is only supported on MongoDB 8.0 and above.
|
||||
:param comment: A user-provided comment to attach to this
|
||||
command.
|
||||
|
||||
:return: - An instance of :class:`~pymongo.results.UpdateResult`.
|
||||
|
||||
.. versionchanged:: 4.11
|
||||
Added ``sort`` parameter.
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
Added ``comment`` parameter.
|
||||
@ -1322,6 +1346,7 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint=hint,
|
||||
session=session,
|
||||
let=let,
|
||||
sort=sort,
|
||||
comment=comment,
|
||||
),
|
||||
write_concern.acknowledged,
|
||||
|
||||
@ -325,6 +325,7 @@ class ReplaceOne(Generic[_DocumentType]):
|
||||
"_collation",
|
||||
"_hint",
|
||||
"_namespace",
|
||||
"_sort",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@ -335,6 +336,7 @@ class ReplaceOne(Generic[_DocumentType]):
|
||||
collation: Optional[_CollationIn] = None,
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
namespace: Optional[str] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create a ReplaceOne instance.
|
||||
|
||||
@ -353,8 +355,12 @@ class ReplaceOne(Generic[_DocumentType]):
|
||||
:meth:`~pymongo.asynchronous.collection.AsyncCollection.create_index` or :meth:`~pymongo.collection.Collection.create_index` (e.g.
|
||||
``[('field', ASCENDING)]``). This option is only supported on
|
||||
MongoDB 4.2 and above.
|
||||
:param sort: Specify which document the operation updates if the query matches
|
||||
multiple documents. The first document matched by the sort order will be updated.
|
||||
:param namespace: (optional) The namespace in which to replace a document.
|
||||
|
||||
.. versionchanged:: 4.10
|
||||
Added ``sort`` option.
|
||||
.. versionchanged:: 4.9
|
||||
Added the `namespace` option to support `MongoClient.bulk_write`.
|
||||
.. versionchanged:: 3.11
|
||||
@ -371,6 +377,7 @@ class ReplaceOne(Generic[_DocumentType]):
|
||||
else:
|
||||
self._hint = hint
|
||||
|
||||
self._sort = sort
|
||||
self._filter = filter
|
||||
self._doc = replacement
|
||||
self._upsert = upsert
|
||||
@ -385,6 +392,7 @@ class ReplaceOne(Generic[_DocumentType]):
|
||||
self._upsert,
|
||||
collation=validate_collation_or_none(self._collation),
|
||||
hint=self._hint,
|
||||
sort=self._sort,
|
||||
)
|
||||
|
||||
def _add_to_client_bulk(self, bulkobj: _AgnosticClientBulk) -> None:
|
||||
@ -400,6 +408,7 @@ class ReplaceOne(Generic[_DocumentType]):
|
||||
self._upsert,
|
||||
collation=validate_collation_or_none(self._collation),
|
||||
hint=self._hint,
|
||||
sort=self._sort,
|
||||
)
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
@ -411,99 +420,15 @@ class ReplaceOne(Generic[_DocumentType]):
|
||||
other._collation,
|
||||
other._hint,
|
||||
other._namespace,
|
||||
other._sort,
|
||||
) == (
|
||||
self._filter,
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
other._hint,
|
||||
self._namespace,
|
||||
)
|
||||
return NotImplemented
|
||||
|
||||
def __ne__(self, other: Any) -> bool:
|
||||
return not self == other
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self._namespace:
|
||||
return "{}({!r}, {!r}, {!r}, {!r}, {!r}, {!r})".format(
|
||||
self.__class__.__name__,
|
||||
self._filter,
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
self._hint,
|
||||
self._namespace,
|
||||
)
|
||||
return "{}({!r}, {!r}, {!r}, {!r}, {!r})".format(
|
||||
self.__class__.__name__,
|
||||
self._filter,
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
self._hint,
|
||||
)
|
||||
|
||||
|
||||
class _UpdateOp:
|
||||
"""Private base class for update operations."""
|
||||
|
||||
__slots__ = (
|
||||
"_filter",
|
||||
"_doc",
|
||||
"_upsert",
|
||||
"_collation",
|
||||
"_array_filters",
|
||||
"_hint",
|
||||
"_namespace",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
filter: Mapping[str, Any],
|
||||
doc: Union[Mapping[str, Any], _Pipeline],
|
||||
upsert: Optional[bool],
|
||||
collation: Optional[_CollationIn],
|
||||
array_filters: Optional[list[Mapping[str, Any]]],
|
||||
hint: Optional[_IndexKeyHint],
|
||||
namespace: Optional[str],
|
||||
):
|
||||
if filter is not None:
|
||||
validate_is_mapping("filter", filter)
|
||||
if upsert is not None:
|
||||
validate_boolean("upsert", upsert)
|
||||
if array_filters is not None:
|
||||
validate_list("array_filters", array_filters)
|
||||
if hint is not None and not isinstance(hint, str):
|
||||
self._hint: Union[str, dict[str, Any], None] = helpers_shared._index_document(hint)
|
||||
else:
|
||||
self._hint = hint
|
||||
|
||||
self._filter = filter
|
||||
self._doc = doc
|
||||
self._upsert = upsert
|
||||
self._collation = collation
|
||||
self._array_filters = array_filters
|
||||
self._namespace = namespace
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, type(self)):
|
||||
return (
|
||||
other._filter,
|
||||
other._doc,
|
||||
other._upsert,
|
||||
other._collation,
|
||||
other._array_filters,
|
||||
other._hint,
|
||||
other._namespace,
|
||||
) == (
|
||||
self._filter,
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
self._array_filters,
|
||||
self._hint,
|
||||
self._namespace,
|
||||
self._sort,
|
||||
)
|
||||
return NotImplemented
|
||||
|
||||
@ -518,11 +443,104 @@ class _UpdateOp:
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
self._array_filters,
|
||||
self._hint,
|
||||
self._namespace,
|
||||
self._sort,
|
||||
)
|
||||
return "{}({!r}, {!r}, {!r}, {!r}, {!r}, {!r})".format(
|
||||
self.__class__.__name__,
|
||||
self._filter,
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
self._hint,
|
||||
self._sort,
|
||||
)
|
||||
|
||||
|
||||
class _UpdateOp:
|
||||
"""Private base class for update operations."""
|
||||
|
||||
__slots__ = (
|
||||
"_filter",
|
||||
"_doc",
|
||||
"_upsert",
|
||||
"_collation",
|
||||
"_array_filters",
|
||||
"_hint",
|
||||
"_namespace",
|
||||
"_sort",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
filter: Mapping[str, Any],
|
||||
doc: Union[Mapping[str, Any], _Pipeline],
|
||||
upsert: Optional[bool],
|
||||
collation: Optional[_CollationIn],
|
||||
array_filters: Optional[list[Mapping[str, Any]]],
|
||||
hint: Optional[_IndexKeyHint],
|
||||
namespace: Optional[str],
|
||||
sort: Optional[Mapping[str, Any]],
|
||||
):
|
||||
if filter is not None:
|
||||
validate_is_mapping("filter", filter)
|
||||
if upsert is not None:
|
||||
validate_boolean("upsert", upsert)
|
||||
if array_filters is not None:
|
||||
validate_list("array_filters", array_filters)
|
||||
if hint is not None and not isinstance(hint, str):
|
||||
self._hint: Union[str, dict[str, Any], None] = helpers_shared._index_document(hint)
|
||||
else:
|
||||
self._hint = hint
|
||||
self._filter = filter
|
||||
self._doc = doc
|
||||
self._upsert = upsert
|
||||
self._collation = collation
|
||||
self._array_filters = array_filters
|
||||
self._namespace = namespace
|
||||
self._sort = sort
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, type(self)):
|
||||
return (
|
||||
other._filter,
|
||||
other._doc,
|
||||
other._upsert,
|
||||
other._collation,
|
||||
other._array_filters,
|
||||
other._hint,
|
||||
other._namespace,
|
||||
other._sort,
|
||||
) == (
|
||||
self._filter,
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
self._array_filters,
|
||||
self._hint,
|
||||
self._namespace,
|
||||
self._sort,
|
||||
)
|
||||
return NotImplemented
|
||||
|
||||
def __ne__(self, other: Any) -> bool:
|
||||
return not self == other
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self._namespace:
|
||||
return "{}({!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r})".format(
|
||||
self.__class__.__name__,
|
||||
self._filter,
|
||||
self._doc,
|
||||
self._upsert,
|
||||
self._collation,
|
||||
self._array_filters,
|
||||
self._hint,
|
||||
self._namespace,
|
||||
self._sort,
|
||||
)
|
||||
return "{}({!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r})".format(
|
||||
self.__class__.__name__,
|
||||
self._filter,
|
||||
self._doc,
|
||||
@ -530,6 +548,7 @@ class _UpdateOp:
|
||||
self._collation,
|
||||
self._array_filters,
|
||||
self._hint,
|
||||
self._sort,
|
||||
)
|
||||
|
||||
|
||||
@ -547,6 +566,7 @@ class UpdateOne(_UpdateOp):
|
||||
array_filters: Optional[list[Mapping[str, Any]]] = None,
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
namespace: Optional[str] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Represents an update_one operation.
|
||||
|
||||
@ -567,8 +587,12 @@ class UpdateOne(_UpdateOp):
|
||||
:meth:`~pymongo.asynchronous.collection.AsyncCollection.create_index` or :meth:`~pymongo.collection.Collection.create_index` (e.g.
|
||||
``[('field', ASCENDING)]``). This option is only supported on
|
||||
MongoDB 4.2 and above.
|
||||
:param namespace: (optional) The namespace in which to update a document.
|
||||
:param namespace: The namespace in which to update a document.
|
||||
:param sort: Specify which document the operation updates if the query matches
|
||||
multiple documents. The first document matched by the sort order will be updated.
|
||||
|
||||
.. versionchanged:: 4.10
|
||||
Added ``sort`` option.
|
||||
.. versionchanged:: 4.9
|
||||
Added the `namespace` option to support `MongoClient.bulk_write`.
|
||||
.. versionchanged:: 3.11
|
||||
@ -580,7 +604,7 @@ class UpdateOne(_UpdateOp):
|
||||
.. versionchanged:: 3.5
|
||||
Added the `collation` option.
|
||||
"""
|
||||
super().__init__(filter, update, upsert, collation, array_filters, hint, namespace)
|
||||
super().__init__(filter, update, upsert, collation, array_filters, hint, namespace, sort)
|
||||
|
||||
def _add_to_bulk(self, bulkobj: _AgnosticBulk) -> None:
|
||||
"""Add this operation to the _AsyncBulk/_Bulk instance `bulkobj`."""
|
||||
@ -592,6 +616,7 @@ class UpdateOne(_UpdateOp):
|
||||
collation=validate_collation_or_none(self._collation),
|
||||
array_filters=self._array_filters,
|
||||
hint=self._hint,
|
||||
sort=self._sort,
|
||||
)
|
||||
|
||||
def _add_to_client_bulk(self, bulkobj: _AgnosticClientBulk) -> None:
|
||||
@ -609,6 +634,7 @@ class UpdateOne(_UpdateOp):
|
||||
collation=validate_collation_or_none(self._collation),
|
||||
array_filters=self._array_filters,
|
||||
hint=self._hint,
|
||||
sort=self._sort,
|
||||
)
|
||||
|
||||
|
||||
@ -659,7 +685,7 @@ class UpdateMany(_UpdateOp):
|
||||
.. versionchanged:: 3.5
|
||||
Added the `collation` option.
|
||||
"""
|
||||
super().__init__(filter, update, upsert, collation, array_filters, hint, namespace)
|
||||
super().__init__(filter, update, upsert, collation, array_filters, hint, namespace, None)
|
||||
|
||||
def _add_to_bulk(self, bulkobj: _AgnosticBulk) -> None:
|
||||
"""Add this operation to the _AsyncBulk/_Bulk instance `bulkobj`."""
|
||||
|
||||
@ -109,6 +109,7 @@ class _Bulk:
|
||||
self.uses_array_filters = False
|
||||
self.uses_hint_update = False
|
||||
self.uses_hint_delete = False
|
||||
self.uses_sort = False
|
||||
self.is_retryable = True
|
||||
self.retrying = False
|
||||
self.started_retryable_write = False
|
||||
@ -144,6 +145,7 @@ class _Bulk:
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
array_filters: Optional[list[Mapping[str, Any]]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create an update document and add it to the list of ops."""
|
||||
validate_ok_for_update(update)
|
||||
@ -159,6 +161,9 @@ class _Bulk:
|
||||
if hint is not None:
|
||||
self.uses_hint_update = True
|
||||
cmd["hint"] = hint
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
if multi:
|
||||
# A bulk_write containing an update_many is not retryable.
|
||||
self.is_retryable = False
|
||||
@ -171,6 +176,7 @@ class _Bulk:
|
||||
upsert: bool = False,
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create a replace document and add it to the list of ops."""
|
||||
validate_ok_for_replace(replacement)
|
||||
@ -181,6 +187,9 @@ class _Bulk:
|
||||
if hint is not None:
|
||||
self.uses_hint_update = True
|
||||
cmd["hint"] = hint
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
self.ops.append((_UPDATE, cmd))
|
||||
|
||||
def add_delete(
|
||||
@ -697,6 +706,10 @@ class _Bulk:
|
||||
raise ConfigurationError(
|
||||
"Must be connected to MongoDB 4.2+ to use hint on unacknowledged update commands."
|
||||
)
|
||||
if unack and self.uses_sort and conn.max_wire_version < 25:
|
||||
raise ConfigurationError(
|
||||
"Must be connected to MongoDB 8.0+ to use sort on unacknowledged update commands."
|
||||
)
|
||||
# Cannot have both unacknowledged writes and bypass document validation.
|
||||
if self.bypass_doc_val:
|
||||
raise OperationFailure(
|
||||
|
||||
@ -118,6 +118,7 @@ class _ClientBulk:
|
||||
self.uses_array_filters = False
|
||||
self.uses_hint_update = False
|
||||
self.uses_hint_delete = False
|
||||
self.uses_sort = False
|
||||
|
||||
self.is_retryable = self.client.options.retry_writes
|
||||
self.retrying = False
|
||||
@ -148,6 +149,7 @@ class _ClientBulk:
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
array_filters: Optional[list[Mapping[str, Any]]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create an update document and add it to the list of ops."""
|
||||
validate_ok_for_update(update)
|
||||
@ -169,6 +171,9 @@ class _ClientBulk:
|
||||
if collation is not None:
|
||||
self.uses_collation = True
|
||||
cmd["collation"] = collation
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
if multi:
|
||||
# A bulk_write containing an update_many is not retryable.
|
||||
self.is_retryable = False
|
||||
@ -184,6 +189,7 @@ class _ClientBulk:
|
||||
upsert: Optional[bool] = None,
|
||||
collation: Optional[Mapping[str, Any]] = None,
|
||||
hint: Union[str, dict[str, Any], None] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Create a replace document and add it to the list of ops."""
|
||||
validate_ok_for_replace(replacement)
|
||||
@ -202,6 +208,9 @@ class _ClientBulk:
|
||||
if collation is not None:
|
||||
self.uses_collation = True
|
||||
cmd["collation"] = collation
|
||||
if sort is not None:
|
||||
self.uses_sort = True
|
||||
cmd["sort"] = sort
|
||||
self.ops.append(("replace", cmd))
|
||||
self.namespaces.append(namespace)
|
||||
self.total_ops += 1
|
||||
|
||||
@ -992,6 +992,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
session: Optional[ClientSession] = None,
|
||||
retryable_write: bool = False,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> Optional[Mapping[str, Any]]:
|
||||
"""Internal update / replace helper."""
|
||||
@ -1023,6 +1024,14 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
if not isinstance(hint, str):
|
||||
hint = helpers_shared._index_document(hint)
|
||||
update_doc["hint"] = hint
|
||||
if sort is not None:
|
||||
if not acknowledged and conn.max_wire_version < 25:
|
||||
raise ConfigurationError(
|
||||
"Must be connected to MongoDB 8.0+ to use sort on unacknowledged update commands."
|
||||
)
|
||||
common.validate_is_mapping("sort", sort)
|
||||
update_doc["sort"] = sort
|
||||
|
||||
command = {"update": self.name, "ordered": ordered, "updates": [update_doc]}
|
||||
if let is not None:
|
||||
common.validate_is_mapping("let", let)
|
||||
@ -1078,6 +1087,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
session: Optional[ClientSession] = None,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> Optional[Mapping[str, Any]]:
|
||||
"""Internal update / replace helper."""
|
||||
@ -1101,6 +1111,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
session=session,
|
||||
retryable_write=retryable_write,
|
||||
let=let,
|
||||
sort=sort,
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
@ -1121,6 +1132,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
session: Optional[ClientSession] = None,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> UpdateResult:
|
||||
"""Replace a single document matching the filter.
|
||||
@ -1175,8 +1187,13 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
aggregate expression context (e.g. "$$var").
|
||||
:param comment: A user-provided comment to attach to this
|
||||
command.
|
||||
:param sort: Specify which document the operation updates if the query matches
|
||||
multiple documents. The first document matched by the sort order will be updated.
|
||||
This option is only supported on MongoDB 8.0 and above.
|
||||
:return: - An instance of :class:`~pymongo.results.UpdateResult`.
|
||||
|
||||
.. versionchanged:: 4.11
|
||||
Added ``sort`` parameter.
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
Added ``comment`` parameter.
|
||||
@ -1208,6 +1225,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint=hint,
|
||||
session=session,
|
||||
let=let,
|
||||
sort=sort,
|
||||
comment=comment,
|
||||
),
|
||||
write_concern.acknowledged,
|
||||
@ -1224,6 +1242,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint: Optional[_IndexKeyHint] = None,
|
||||
session: Optional[ClientSession] = None,
|
||||
let: Optional[Mapping[str, Any]] = None,
|
||||
sort: Optional[Mapping[str, Any]] = None,
|
||||
comment: Optional[Any] = None,
|
||||
) -> UpdateResult:
|
||||
"""Update a single document matching the filter.
|
||||
@ -1282,11 +1301,16 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
:param sort: Specify which document the operation updates if the query matches
|
||||
multiple documents. The first document matched by the sort order will be updated.
|
||||
This option is only supported on MongoDB 8.0 and above.
|
||||
:param comment: A user-provided comment to attach to this
|
||||
command.
|
||||
|
||||
:return: - An instance of :class:`~pymongo.results.UpdateResult`.
|
||||
|
||||
.. versionchanged:: 4.11
|
||||
Added ``sort`` parameter.
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
Added ``comment`` parameter.
|
||||
@ -1321,6 +1345,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
hint=hint,
|
||||
session=session,
|
||||
let=let,
|
||||
sort=sort,
|
||||
comment=comment,
|
||||
),
|
||||
write_concern.acknowledged,
|
||||
|
||||
@ -971,6 +971,9 @@ class AsyncTestBulkWriteConcern(AsyncBulkTestBase):
|
||||
@async_client_context.require_replica_set
|
||||
@async_client_context.require_secondaries_count(1)
|
||||
async def test_write_concern_failure_ordered(self):
|
||||
self.skipTest("Skipping until PYTHON-4865 is resolved.")
|
||||
details = None
|
||||
|
||||
# Ensure we don't raise on wnote.
|
||||
coll_ww = self.coll.with_options(write_concern=WriteConcern(w=self.w))
|
||||
result = await coll_ww.bulk_write([DeleteOne({"something": "that does no exist"})])
|
||||
@ -1051,6 +1054,9 @@ class AsyncTestBulkWriteConcern(AsyncBulkTestBase):
|
||||
@async_client_context.require_replica_set
|
||||
@async_client_context.require_secondaries_count(1)
|
||||
async def test_write_concern_failure_unordered(self):
|
||||
self.skipTest("Skipping until PYTHON-4865 is resolved.")
|
||||
details = None
|
||||
|
||||
# Ensure we don't raise on wnote.
|
||||
coll_ww = self.coll.with_options(write_concern=WriteConcern(w=self.w))
|
||||
result = await coll_ww.bulk_write(
|
||||
|
||||
@ -78,11 +78,6 @@
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"collectionName": "coll1",
|
||||
"databaseName": "db0",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
@ -159,22 +154,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll1",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -250,22 +229,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll1",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -344,22 +307,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll1",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -438,22 +385,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll1",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
239
test/crud/unified/bulkWrite-replaceOne-sort.json
Normal file
239
test/crud/unified/bulkWrite-replaceOne-sort.json
Normal file
@ -0,0 +1,239 @@
|
||||
{
|
||||
"description": "BulkWrite replaceOne-sort",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "BulkWrite replaceOne with sort option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"replaceOne": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"replacement": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": {
|
||||
"x": 1
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"ok": 1,
|
||||
"n": 1
|
||||
},
|
||||
"commandName": "update"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "BulkWrite replaceOne with sort option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"maxServerVersion": "7.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"replaceOne": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"replacement": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"expectError": {
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": {
|
||||
"x": 1
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
255
test/crud/unified/bulkWrite-updateOne-sort.json
Normal file
255
test/crud/unified/bulkWrite-updateOne-sort.json
Normal file
@ -0,0 +1,255 @@
|
||||
{
|
||||
"description": "BulkWrite updateOne-sort",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "BulkWrite updateOne with sort option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"updateOne": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": [
|
||||
{
|
||||
"$set": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"ok": 1,
|
||||
"n": 1
|
||||
},
|
||||
"commandName": "update"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "BulkWrite updateOne with sort option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"maxServerVersion": "7.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"updateOne": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"expectError": {
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": [
|
||||
{
|
||||
"$set": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
540
test/crud/unified/client-bulkWrite-partialResults.json
Normal file
540
test/crud/unified/client-bulkWrite-partialResults.json
Normal file
@ -0,0 +1,540 @@
|
||||
{
|
||||
"description": "client bulkWrite partial results",
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0",
|
||||
"serverless": "forbid"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"_yamlAnchors": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"newDocument": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "partialResult is unset when first operation fails during an ordered bulk write (verbose)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"verboseResults": true
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"$$unsetOrMatches": {
|
||||
"insertedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"upsertedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"matchedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"modifiedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"deletedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"insertResults": {
|
||||
"$$exists": false
|
||||
},
|
||||
"updateResults": {
|
||||
"$$exists": false
|
||||
},
|
||||
"deleteResults": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is unset when first operation fails during an ordered bulk write (summary)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"verboseResults": false
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"$$unsetOrMatches": {
|
||||
"insertedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"upsertedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"matchedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"modifiedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"deletedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"insertResults": {
|
||||
"$$exists": false
|
||||
},
|
||||
"updateResults": {
|
||||
"$$exists": false
|
||||
},
|
||||
"deleteResults": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is set when second operation fails during an ordered bulk write (verbose)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"verboseResults": true
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"insertedCount": 1,
|
||||
"upsertedCount": 0,
|
||||
"matchedCount": 0,
|
||||
"modifiedCount": 0,
|
||||
"deletedCount": 0,
|
||||
"insertResults": {
|
||||
"0": {
|
||||
"insertedId": 2
|
||||
}
|
||||
},
|
||||
"updateResults": {},
|
||||
"deleteResults": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is set when second operation fails during an ordered bulk write (summary)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"verboseResults": false
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"insertedCount": 1,
|
||||
"upsertedCount": 0,
|
||||
"matchedCount": 0,
|
||||
"modifiedCount": 0,
|
||||
"deletedCount": 0,
|
||||
"insertResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
},
|
||||
"updateResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
},
|
||||
"deleteResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is unset when all operations fail during an unordered bulk write",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": false
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"$$unsetOrMatches": {
|
||||
"insertedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"upsertedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"matchedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"modifiedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"deletedCount": {
|
||||
"$$exists": false
|
||||
},
|
||||
"insertResults": {
|
||||
"$$exists": false
|
||||
},
|
||||
"updateResults": {
|
||||
"$$exists": false
|
||||
},
|
||||
"deleteResults": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is set when first operation fails during an unordered bulk write (verbose)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": false,
|
||||
"verboseResults": true
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"insertedCount": 1,
|
||||
"upsertedCount": 0,
|
||||
"matchedCount": 0,
|
||||
"modifiedCount": 0,
|
||||
"deletedCount": 0,
|
||||
"insertResults": {
|
||||
"1": {
|
||||
"insertedId": 2
|
||||
}
|
||||
},
|
||||
"updateResults": {},
|
||||
"deleteResults": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is set when first operation fails during an unordered bulk write (summary)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": false,
|
||||
"verboseResults": false
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"insertedCount": 1,
|
||||
"upsertedCount": 0,
|
||||
"matchedCount": 0,
|
||||
"modifiedCount": 0,
|
||||
"deletedCount": 0,
|
||||
"insertResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
},
|
||||
"updateResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
},
|
||||
"deleteResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is set when second operation fails during an unordered bulk write (verbose)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": false,
|
||||
"verboseResults": true
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"insertedCount": 1,
|
||||
"upsertedCount": 0,
|
||||
"matchedCount": 0,
|
||||
"modifiedCount": 0,
|
||||
"deletedCount": 0,
|
||||
"insertResults": {
|
||||
"0": {
|
||||
"insertedId": 2
|
||||
}
|
||||
},
|
||||
"updateResults": {},
|
||||
"deleteResults": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "partialResult is set when first operation fails during an unordered bulk write (summary)",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"insertOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": false,
|
||||
"verboseResults": false
|
||||
},
|
||||
"expectError": {
|
||||
"expectResult": {
|
||||
"insertedCount": 1,
|
||||
"upsertedCount": 0,
|
||||
"matchedCount": 0,
|
||||
"modifiedCount": 0,
|
||||
"deletedCount": 0,
|
||||
"insertResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
},
|
||||
"updateResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
},
|
||||
"deleteResults": {
|
||||
"$$unsetOrMatches": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
162
test/crud/unified/client-bulkWrite-replaceOne-sort.json
Normal file
162
test/crud/unified/client-bulkWrite-replaceOne-sort.json
Normal file
@ -0,0 +1,162 @@
|
||||
{
|
||||
"description": "client bulkWrite updateOne-sort",
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"_yamlAnchors": {
|
||||
"namespace": "crud-tests.coll0"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "client bulkWrite replaceOne with sort option",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"replaceOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"replacement": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "bulkWrite",
|
||||
"databaseName": "admin",
|
||||
"command": {
|
||||
"bulkWrite": 1,
|
||||
"ops": [
|
||||
{
|
||||
"update": 0,
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"updateMods": {
|
||||
"x": 1
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"nsInfo": [
|
||||
{
|
||||
"ns": "crud-tests.coll0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"ok": 1,
|
||||
"nErrors": 0,
|
||||
"nMatched": 1,
|
||||
"nModified": 1
|
||||
},
|
||||
"commandName": "bulkWrite"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
166
test/crud/unified/client-bulkWrite-updateOne-sort.json
Normal file
166
test/crud/unified/client-bulkWrite-updateOne-sort.json
Normal file
@ -0,0 +1,166 @@
|
||||
{
|
||||
"description": "client bulkWrite updateOne-sort",
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"_yamlAnchors": {
|
||||
"namespace": "crud-tests.coll0"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "client bulkWrite updateOne with sort option",
|
||||
"operations": [
|
||||
{
|
||||
"object": "client0",
|
||||
"name": "clientBulkWrite",
|
||||
"arguments": {
|
||||
"models": [
|
||||
{
|
||||
"updateOne": {
|
||||
"namespace": "crud-tests.coll0",
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "bulkWrite",
|
||||
"databaseName": "admin",
|
||||
"command": {
|
||||
"bulkWrite": 1,
|
||||
"ops": [
|
||||
{
|
||||
"update": 0,
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"updateMods": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"nsInfo": [
|
||||
{
|
||||
"ns": "crud-tests.coll0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"ok": 1,
|
||||
"nErrors": 0,
|
||||
"nMatched": 1,
|
||||
"nModified": 1
|
||||
},
|
||||
"commandName": "bulkWrite"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 34
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -52,13 +52,6 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "db0",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "Database-level aggregate with $out includes read preference for 5.0+ server",
|
||||
@ -141,17 +134,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -235,17 +217,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -332,17 +303,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -429,17 +389,6 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "db0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
232
test/crud/unified/replaceOne-sort.json
Normal file
232
test/crud/unified/replaceOne-sort.json
Normal file
@ -0,0 +1,232 @@
|
||||
{
|
||||
"description": "replaceOne-sort",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "ReplaceOne with sort option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "replaceOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"replacement": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"matchedCount": 1,
|
||||
"modifiedCount": 1,
|
||||
"upsertedCount": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": {
|
||||
"x": 1
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"ok": 1,
|
||||
"n": 1
|
||||
},
|
||||
"commandName": "update"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "replaceOne with sort option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"maxServerVersion": "7.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "replaceOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"replacement": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": {
|
||||
"x": 1
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
240
test/crud/unified/updateOne-sort.json
Normal file
240
test/crud/unified/updateOne-sort.json
Normal file
@ -0,0 +1,240 @@
|
||||
{
|
||||
"description": "updateOne-sort",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "UpdateOne with sort option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "updateOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"matchedCount": 1,
|
||||
"modifiedCount": 1,
|
||||
"upsertedCount": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"ok": 1,
|
||||
"n": 1
|
||||
},
|
||||
"commandName": "update"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 34
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "updateOne with sort option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"maxServerVersion": "7.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "updateOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"u": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": -1
|
||||
},
|
||||
"multi": {
|
||||
"$$unsetOrMatches": false
|
||||
},
|
||||
"upsert": {
|
||||
"$$unsetOrMatches": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -969,6 +969,9 @@ class TestBulkWriteConcern(BulkTestBase):
|
||||
@client_context.require_replica_set
|
||||
@client_context.require_secondaries_count(1)
|
||||
def test_write_concern_failure_ordered(self):
|
||||
self.skipTest("Skipping until PYTHON-4865 is resolved.")
|
||||
details = None
|
||||
|
||||
# Ensure we don't raise on wnote.
|
||||
coll_ww = self.coll.with_options(write_concern=WriteConcern(w=self.w))
|
||||
result = coll_ww.bulk_write([DeleteOne({"something": "that does no exist"})])
|
||||
@ -1049,6 +1052,9 @@ class TestBulkWriteConcern(BulkTestBase):
|
||||
@client_context.require_replica_set
|
||||
@client_context.require_secondaries_count(1)
|
||||
def test_write_concern_failure_unordered(self):
|
||||
self.skipTest("Skipping until PYTHON-4865 is resolved.")
|
||||
details = None
|
||||
|
||||
# Ensure we don't raise on wnote.
|
||||
coll_ww = self.coll.with_options(write_concern=WriteConcern(w=self.w))
|
||||
result = coll_ww.bulk_write([DeleteOne({"something": "that does no exist"})], ordered=False)
|
||||
|
||||
@ -958,10 +958,6 @@ def parse_spec_options(opts):
|
||||
def prepare_spec_arguments(spec, arguments, opname, entity_map, with_txn_callback):
|
||||
for arg_name in list(arguments):
|
||||
c2s = camel_to_snake(arg_name)
|
||||
# PyMongo accepts sort as list of tuples.
|
||||
if arg_name == "sort":
|
||||
sort_dict = arguments[arg_name]
|
||||
arguments[arg_name] = list(sort_dict.items())
|
||||
# Named "key" instead not fieldName.
|
||||
if arg_name == "fieldName":
|
||||
arguments["key"] = arguments.pop(arg_name)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user