123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- # Copyright 2015-present MongoDB, Inc.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- """Operation class definitions."""
- from bson.py3compat import string_type
- from pymongo import helpers
- from pymongo.common import validate_boolean, validate_is_mapping, validate_list
- from pymongo.collation import validate_collation_or_none
- from pymongo.helpers import _gen_index_name, _index_document, _index_list
- class InsertOne(object):
- """Represents an insert_one operation."""
- __slots__ = ("_doc",)
- def __init__(self, document):
- """Create an InsertOne instance.
- For use with :meth:`~pymongo.collection.Collection.bulk_write`.
- :Parameters:
- - `document`: The document to insert. If the document is missing an
- _id field one will be added.
- """
- self._doc = document
- def _add_to_bulk(self, bulkobj):
- """Add this operation to the _Bulk instance `bulkobj`."""
- bulkobj.add_insert(self._doc)
- def __repr__(self):
- return "InsertOne(%r)" % (self._doc,)
- def __eq__(self, other):
- if type(other) == type(self):
- return other._doc == self._doc
- return NotImplemented
- def __ne__(self, other):
- return not self == other
- class DeleteOne(object):
- """Represents a delete_one operation."""
- __slots__ = ("_filter", "_collation", "_hint")
- def __init__(self, filter, collation=None, hint=None):
- """Create a DeleteOne instance.
- For use with :meth:`~pymongo.collection.Collection.bulk_write`.
- :Parameters:
- - `filter`: A query that matches the document to delete.
- - `collation` (optional): An instance of
- :class:`~pymongo.collation.Collation`. This option is only
- supported on MongoDB 3.4 and above.
- - `hint` (optional): An index to use to support the query
- predicate specified either by its string name, or in the same
- format as passed to
- :meth:`~pymongo.collection.Collection.create_index` (e.g.
- ``[('field', ASCENDING)]``). This option is only supported on
- MongoDB 4.4 and above.
- .. versionchanged:: 3.11
- Added the ``hint`` option.
- .. versionchanged:: 3.5
- Added the `collation` option.
- """
- if filter is not None:
- validate_is_mapping("filter", filter)
- if hint is not None:
- if not isinstance(hint, string_type):
- hint = helpers._index_document(hint)
- self._filter = filter
- self._collation = collation
- self._hint = hint
- def _add_to_bulk(self, bulkobj):
- """Add this operation to the _Bulk instance `bulkobj`."""
- bulkobj.add_delete(self._filter, 1, collation=self._collation,
- hint=self._hint)
- def __repr__(self):
- return "DeleteOne(%r, %r)" % (self._filter, self._collation)
- def __eq__(self, other):
- if type(other) == type(self):
- return ((other._filter, other._collation) ==
- (self._filter, self._collation))
- return NotImplemented
- def __ne__(self, other):
- return not self == other
- class DeleteMany(object):
- """Represents a delete_many operation."""
- __slots__ = ("_filter", "_collation", "_hint")
- def __init__(self, filter, collation=None, hint=None):
- """Create a DeleteMany instance.
- For use with :meth:`~pymongo.collection.Collection.bulk_write`.
- :Parameters:
- - `filter`: A query that matches the documents to delete.
- - `collation` (optional): An instance of
- :class:`~pymongo.collation.Collation`. This option is only
- supported on MongoDB 3.4 and above.
- - `hint` (optional): An index to use to support the query
- predicate specified either by its string name, or in the same
- format as passed to
- :meth:`~pymongo.collection.Collection.create_index` (e.g.
- ``[('field', ASCENDING)]``). This option is only supported on
- MongoDB 4.4 and above.
- .. versionchanged:: 3.11
- Added the ``hint`` option.
- .. versionchanged:: 3.5
- Added the `collation` option.
- """
- if filter is not None:
- validate_is_mapping("filter", filter)
- if hint is not None:
- if not isinstance(hint, string_type):
- hint = helpers._index_document(hint)
- self._filter = filter
- self._collation = collation
- self._hint = hint
- def _add_to_bulk(self, bulkobj):
- """Add this operation to the _Bulk instance `bulkobj`."""
- bulkobj.add_delete(self._filter, 0, collation=self._collation,
- hint=self._hint)
- def __repr__(self):
- return "DeleteMany(%r, %r)" % (self._filter, self._collation)
- def __eq__(self, other):
- if type(other) == type(self):
- return ((other._filter, other._collation) ==
- (self._filter, self._collation))
- return NotImplemented
- def __ne__(self, other):
- return not self == other
- class ReplaceOne(object):
- """Represents a replace_one operation."""
- __slots__ = ("_filter", "_doc", "_upsert", "_collation", "_hint")
- def __init__(self, filter, replacement, upsert=False, collation=None,
- hint=None):
- """Create a ReplaceOne instance.
- For use with :meth:`~pymongo.collection.Collection.bulk_write`.
- :Parameters:
- - `filter`: A query that matches the document to replace.
- - `replacement`: The new document.
- - `upsert` (optional): If ``True``, perform an insert if no documents
- match the filter.
- - `collation` (optional): An instance of
- :class:`~pymongo.collation.Collation`. This option is only
- supported on MongoDB 3.4 and above.
- - `hint` (optional): An index to use to support the query
- predicate specified either by its string name, or in the same
- format as passed to
- :meth:`~pymongo.collection.Collection.create_index` (e.g.
- ``[('field', ASCENDING)]``). This option is only supported on
- MongoDB 4.2 and above.
- .. versionchanged:: 3.11
- Added the ``hint`` option.
- .. versionchanged:: 3.5
- Added the ``collation`` option.
- """
- if filter is not None:
- validate_is_mapping("filter", filter)
- if upsert is not None:
- validate_boolean("upsert", upsert)
- if hint is not None:
- if not isinstance(hint, string_type):
- hint = helpers._index_document(hint)
- self._filter = filter
- self._doc = replacement
- self._upsert = upsert
- self._collation = collation
- self._hint = hint
- def _add_to_bulk(self, bulkobj):
- """Add this operation to the _Bulk instance `bulkobj`."""
- bulkobj.add_replace(self._filter, self._doc, self._upsert,
- collation=self._collation, hint=self._hint)
- def __eq__(self, other):
- if type(other) == type(self):
- return (
- (other._filter, other._doc, other._upsert, other._collation,
- other._hint) == (self._filter, self._doc, self._upsert,
- self._collation, other._hint))
- return NotImplemented
- def __ne__(self, other):
- return not self == other
- def __repr__(self):
- return "%s(%r, %r, %r, %r, %r)" % (
- self.__class__.__name__, self._filter, self._doc, self._upsert,
- self._collation, self._hint)
- class _UpdateOp(object):
- """Private base class for update operations."""
- __slots__ = ("_filter", "_doc", "_upsert", "_collation", "_array_filters",
- "_hint")
- def __init__(self, filter, doc, upsert, collation, array_filters, hint):
- 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:
- if not isinstance(hint, string_type):
- hint = helpers._index_document(hint)
- self._filter = filter
- self._doc = doc
- self._upsert = upsert
- self._collation = collation
- self._array_filters = array_filters
- self._hint = hint
- def __eq__(self, other):
- if type(other) == type(self):
- return (
- (other._filter, other._doc, other._upsert, other._collation,
- other._array_filters, other._hint) ==
- (self._filter, self._doc, self._upsert, self._collation,
- self._array_filters, self._hint))
- return NotImplemented
- def __ne__(self, other):
- return not self == other
- def __repr__(self):
- return "%s(%r, %r, %r, %r, %r, %r)" % (
- self.__class__.__name__, self._filter, self._doc, self._upsert,
- self._collation, self._array_filters, self._hint)
- class UpdateOne(_UpdateOp):
- """Represents an update_one operation."""
- __slots__ = ()
- def __init__(self, filter, update, upsert=False, collation=None,
- array_filters=None, hint=None):
- """Represents an update_one operation.
- For use with :meth:`~pymongo.collection.Collection.bulk_write`.
- :Parameters:
- - `filter`: A query that matches the document to update.
- - `update`: The modifications to apply.
- - `upsert` (optional): If ``True``, perform an insert if no documents
- match the filter.
- - `collation` (optional): An instance of
- :class:`~pymongo.collation.Collation`. This option is only
- supported on MongoDB 3.4 and above.
- - `array_filters` (optional): A list of filters specifying which
- array elements an update should apply. Requires MongoDB 3.6+.
- - `hint` (optional): An index to use to support the query
- predicate specified either by its string name, or in the same
- format as passed to
- :meth:`~pymongo.collection.Collection.create_index` (e.g.
- ``[('field', ASCENDING)]``). This option is only supported on
- MongoDB 4.2 and above.
- .. versionchanged:: 3.11
- Added the `hint` option.
- .. versionchanged:: 3.9
- Added the ability to accept a pipeline as the `update`.
- .. versionchanged:: 3.6
- Added the `array_filters` option.
- .. versionchanged:: 3.5
- Added the `collation` option.
- """
- super(UpdateOne, self).__init__(filter, update, upsert, collation,
- array_filters, hint)
- def _add_to_bulk(self, bulkobj):
- """Add this operation to the _Bulk instance `bulkobj`."""
- bulkobj.add_update(self._filter, self._doc, False, self._upsert,
- collation=self._collation,
- array_filters=self._array_filters,
- hint=self._hint)
- class UpdateMany(_UpdateOp):
- """Represents an update_many operation."""
- __slots__ = ()
- def __init__(self, filter, update, upsert=False, collation=None,
- array_filters=None, hint=None):
- """Create an UpdateMany instance.
- For use with :meth:`~pymongo.collection.Collection.bulk_write`.
- :Parameters:
- - `filter`: A query that matches the documents to update.
- - `update`: The modifications to apply.
- - `upsert` (optional): If ``True``, perform an insert if no documents
- match the filter.
- - `collation` (optional): An instance of
- :class:`~pymongo.collation.Collation`. This option is only
- supported on MongoDB 3.4 and above.
- - `array_filters` (optional): A list of filters specifying which
- array elements an update should apply. Requires MongoDB 3.6+.
- - `hint` (optional): An index to use to support the query
- predicate specified either by its string name, or in the same
- format as passed to
- :meth:`~pymongo.collection.Collection.create_index` (e.g.
- ``[('field', ASCENDING)]``). This option is only supported on
- MongoDB 4.2 and above.
- .. versionchanged:: 3.11
- Added the `hint` option.
- .. versionchanged:: 3.9
- Added the ability to accept a pipeline as the `update`.
- .. versionchanged:: 3.6
- Added the `array_filters` option.
- .. versionchanged:: 3.5
- Added the `collation` option.
- """
- super(UpdateMany, self).__init__(filter, update, upsert, collation,
- array_filters, hint)
- def _add_to_bulk(self, bulkobj):
- """Add this operation to the _Bulk instance `bulkobj`."""
- bulkobj.add_update(self._filter, self._doc, True, self._upsert,
- collation=self._collation,
- array_filters=self._array_filters,
- hint=self._hint)
- class IndexModel(object):
- """Represents an index to create."""
- __slots__ = ("__document",)
- def __init__(self, keys, **kwargs):
- """Create an Index instance.
- For use with :meth:`~pymongo.collection.Collection.create_indexes`.
- Takes either a single key or a list of (key, direction) pairs.
- The key(s) must be an instance of :class:`basestring`
- (:class:`str` in python 3), and the direction(s) must be one of
- (:data:`~pymongo.ASCENDING`, :data:`~pymongo.DESCENDING`,
- :data:`~pymongo.GEO2D`, :data:`~pymongo.GEOHAYSTACK`,
- :data:`~pymongo.GEOSPHERE`, :data:`~pymongo.HASHED`,
- :data:`~pymongo.TEXT`).
- Valid options include, but are not limited to:
- - `name`: custom name to use for this index - if none is
- given, a name will be generated.
- - `unique`: if ``True``, creates a uniqueness constraint on the index.
- - `background`: if ``True``, this index should be created in the
- background.
- - `sparse`: if ``True``, omit from the index any documents that lack
- the indexed field.
- - `bucketSize`: for use with geoHaystack indexes.
- Number of documents to group together within a certain proximity
- to a given longitude and latitude.
- - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
- index.
- - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
- index.
- - `expireAfterSeconds`: <int> Used to create an expiring (TTL)
- collection. MongoDB will automatically delete documents from
- this collection after <int> seconds. The indexed field must
- be a UTC datetime or the data will not expire.
- - `partialFilterExpression`: A document that specifies a filter for
- a partial index. Requires MongoDB >= 3.2.
- - `collation`: An instance of :class:`~pymongo.collation.Collation`
- that specifies the collation to use in MongoDB >= 3.4.
- - `wildcardProjection`: Allows users to include or exclude specific
- field paths from a `wildcard index`_ using the { "$**" : 1} key
- pattern. Requires MongoDB >= 4.2.
- - `hidden`: if ``True``, this index will be hidden from the query
- planner and will not be evaluated as part of query plan
- selection. Requires MongoDB >= 4.4.
- See the MongoDB documentation for a full list of supported options by
- server version.
- :Parameters:
- - `keys`: a single key or a list of (key, direction)
- pairs specifying the index to create
- - `**kwargs` (optional): any additional index creation
- options (see the above list) should be passed as keyword
- arguments
- .. versionchanged:: 3.11
- Added the ``hidden`` option.
- .. versionchanged:: 3.2
- Added the ``partialFilterExpression`` option to support partial
- indexes.
- .. _wildcard index: https://docs.mongodb.com/master/core/index-wildcard/#wildcard-index-core
- """
- keys = _index_list(keys)
- if "name" not in kwargs:
- kwargs["name"] = _gen_index_name(keys)
- kwargs["key"] = _index_document(keys)
- collation = validate_collation_or_none(kwargs.pop('collation', None))
- self.__document = kwargs
- if collation is not None:
- self.__document['collation'] = collation
- @property
- def document(self):
- """An index document suitable for passing to the createIndexes
- command.
- """
- return self.__document
|