Example #1
0
    def ensure_index(self, key_or_list, cache_for=300, **kwargs):
        """Ensures that an index exists on this collection.

        Unlike :meth:`create_index`, which attempts to create an index
        unconditionally, :meth:`ensure_index` takes advantage of some
        caching within the driver such that it only attempts to create
        indexes that might not already exist. When an index is created
        (or ensured) by PyMongo it is "remembered" for `cache_for`
        seconds. Repeated calls to :meth:`ensure_index` within that
        time limit will be lightweight - they will not attempt to
        actually create the index.

        Care must be taken when the database is being accessed through
        multiple Database objects at once. If an index is created and
        then deleted using another database object any call to
        :meth:`ensure_index` within the cache window will fail to
        re-create the missing index.

        .. seealso:: :meth:`create_index`
        """
        if "name" in kwargs:
            name = kwargs["name"]
        else:
            keys = _index_list(key_or_list)
            name = kwargs["name"] = helpers._gen_index_name(keys)

        if not self._database._cached(self._collection, name):
            return self.create_index(key_or_list, cache_for, **kwargs)
Example #2
0
    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.

        See the MongoDB documentation for a full list of supported options by
        server version.

        .. note:: `partialFilterExpression` requires server version **>= 3.2**

        :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.2
            Added partialFilterExpression to support partial indexes.
        """
        keys = _index_list(keys)
        if "name" not in kwargs:
            kwargs["name"] = _gen_index_name(keys)
        kwargs["key"] = _index_document(keys)
        self.__document = kwargs
Example #3
0
    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.

        See the MongoDB documentation for a full list of supported options by
        server version.

        .. note:: `partialFilterExpression` requires server version **>= 3.2**

        :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.2
            Added partialFilterExpression to support partial indexes.
        """
        keys = _index_list(keys)
        if "name" not in kwargs:
            kwargs["name"] = _gen_index_name(keys)
        kwargs["key"] = _index_document(keys)
        self.__document = kwargs
    def create_index(self, key_or_list, unique=False, ttl=300):
        """Creates an index on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        directions must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`). Returns the name of the created
        index.

        To create a single key index on the key ``'mike'`` we just use
        a string argument:

        >>> my_collection.create_index("mike")

        For a `compound index`_ on ``'mike'`` descending and
        ``'eliot'`` ascending we need to use a list of tuples:

        >>> my_collection.create_index([("mike", pymongo.DESCENDING),
        ...                             ("eliot", pymongo.ASCENDING)])

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to create
          - `unique` (optional): should this index guarantee
            uniqueness?
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index` - see documentation for
            :meth:`ensure_index` for details

        .. seealso:: :meth:`ensure_index`

        .. _compound index: http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeysIndexes

        .. mongodoc:: indexes
        """
        if not isinstance(key_or_list, (str, unicode, list)):
            raise TypeError("key_or_list must either be a single key "
                            "or a list of (key, direction) pairs")

        to_save = SON()
        keys = helpers._index_list(key_or_list)
        name = self._gen_index_name(keys)
        to_save["name"] = name
        to_save["ns"] = self.__full_name
        to_save["key"] = helpers._index_document(keys)
        to_save["unique"] = unique

        self.__database.connection._cache_index(self.__database.name,
                                                self.__name, name, ttl)

        self.__database.system.indexes.insert(to_save, manipulate=False,
                                              check_keys=False)
        return to_save["name"]
Example #5
0
    def create_index(self, key_or_list, unique=False, ttl=300):
        """Creates an index on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        directions must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`). Returns the name of the created
        index.

        To create a single key index on the key ``'mike'`` we just use
        a string argument:

        >>> my_collection.create_index("mike")

        For a `compound index`_ on ``'mike'`` descending and
        ``'eliot'`` ascending we need to use a list of tuples:

        >>> my_collection.create_index([("mike", pymongo.DESCENDING),
        ...                             ("eliot", pymongo.ASCENDING)])

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to create
          - `unique` (optional): should this index guarantee
            uniqueness?
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index` - see documentation for
            :meth:`ensure_index` for details

        .. seealso:: :meth:`ensure_index`

        .. _compound index: http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeysIndexes

        .. mongodoc:: indexes
        """
        keys = helpers._index_list(key_or_list)
        index_doc = helpers._index_document(keys)
        name = self._gen_index_name(keys)
        to_save = SON()
        to_save["name"] = name
        to_save["ns"] = self.__full_name
        to_save["key"] = index_doc
        to_save["unique"] = unique

        self.__database.connection._cache_index(self.__database.name,
                                                self.__name, name, ttl)

        self.__database.system.indexes.insert(to_save,
                                              manipulate=False,
                                              check_keys=False)
        return to_save["name"]
Example #6
0
    def sort(
        self,
        key_or_list: _Hint,
        direction: Optional[Union[int,
                                  str]] = None) -> "Cursor[_DocumentType]":
        """Sorts this cursor's results.

        Pass a field name and a direction, either
        :data:`~pymongo.ASCENDING` or :data:`~pymongo.DESCENDING`::

            for doc in collection.find().sort('field', pymongo.ASCENDING):
                print(doc)

        To sort by multiple fields, pass a list of (key, direction) pairs::

            for doc in collection.find().sort([
                    ('field1', pymongo.ASCENDING),
                    ('field2', pymongo.DESCENDING)]):
                print(doc)

        Text search results can be sorted by relevance::

            cursor = db.test.find(
                {'$text': {'$search': 'some words'}},
                {'score': {'$meta': 'textScore'}})

            # Sort by 'score' field.
            cursor.sort([('score', {'$meta': 'textScore'})])

            for doc in cursor:
                print(doc)

        For more advanced text search functionality, see MongoDB's
        `Atlas Search <https://docs.atlas.mongodb.com/atlas-search/>`_.

        Raises :class:`~pymongo.errors.InvalidOperation` if this cursor has
        already been used. Only the last :meth:`sort` applied to this
        cursor has any effect.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the keys to sort on
          - `direction` (optional): only used if `key_or_list` is a single
            key, if not given :data:`~pymongo.ASCENDING` is assumed
        """
        self.__check_okay_to_chain()
        keys = helpers._index_list(key_or_list, direction)
        self.__ordering = helpers._index_document(keys)
        return self
Example #7
0
    def ensure_index(self, key_or_list, unique=False, ttl=300):
        """Ensures that an index exists on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        direction(s) must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`). See :meth:`create_index` for a
        detailed example.

        Unlike :meth:`create_index`, which attempts to create an index
        unconditionally, :meth:`ensure_index` takes advantage of some
        caching within the driver such that it only attempts to create
        indexes that might not already exist. When an index is created
        (or ensured) by PyMongo it is "remembered" for `ttl`
        seconds. Repeated calls to :meth:`ensure_index` within that
        time limit will be lightweight - they will not attempt to
        actually create the index.

        Care must be taken when the database is being accessed through
        multiple connections at once. If an index is created using
        PyMongo and then deleted using another connection any call to
        :meth:`ensure_index` within the cache window will fail to
        re-create the missing index.

        Returns the name of the created index if an index is actually
        created. Returns ``None`` if the index already exists.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to ensure
          - `unique` (optional): should this index guarantee
            uniqueness?
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index`

        .. seealso:: :meth:`create_index`
        """
        if not isinstance(key_or_list, (str, unicode, list)):
            raise TypeError(
                "key_or_list must either be a single key or a list of (key, direction) pairs"
            )

        keys = helpers._index_list(key_or_list)
        name = self._gen_index_name(keys)
        if self.__database.connection._cache_index(self.__database.name,
                                                   self.__name, name, ttl):
            return self.create_index(key_or_list, unique=unique, ttl=ttl)
        return None
Example #8
0
    def ensure_index(self, key_or_list, unique=False, ttl=300):
        """Ensures that an index exists on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        direction(s) must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`). See :meth:`create_index` for a
        detailed example.

        Unlike :meth:`create_index`, which attempts to create an index
        unconditionally, :meth:`ensure_index` takes advantage of some
        caching within the driver such that it only attempts to create
        indexes that might not already exist. When an index is created
        (or ensured) by PyMongo it is "remembered" for `ttl`
        seconds. Repeated calls to :meth:`ensure_index` within that
        time limit will be lightweight - they will not attempt to
        actually create the index.

        Care must be taken when the database is being accessed through
        multiple connections at once. If an index is created using
        PyMongo and then deleted using another connection any call to
        :meth:`ensure_index` within the cache window will fail to
        re-create the missing index.

        Returns the name of the created index if an index is actually
        created. Returns ``None`` if the index already exists.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to ensure
          - `unique` (optional): should this index guarantee
            uniqueness?
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index`

        .. seealso:: :meth:`create_index`
        """
        if not isinstance(key_or_list, (str, unicode, list)):
            raise TypeError("key_or_list must either be a single key or a list of (key, direction) pairs")

        keys = helpers._index_list(key_or_list)
        name = self._gen_index_name(keys)
        if self.__database.connection._cache_index(self.__database.name,
                                                   self.__name, name, ttl):
            return self.create_index(key_or_list, unique=unique, ttl=ttl)
        return None
Example #9
0
    def sort(self,
             key_or_list: Union[str, List[tuple]],
             direction: Optional[int] = None) -> 'Cursor':
        """Sorts this cursor's results.

        Pass a field name and a direction, either
        :data:`~pymongo.ASCENDING` or :data:`~pymongo.DESCENDING`::

            async for doc in collection.find().sort('field', pymongo.ASCENDING):
                print(doc)

        To sort by multiple fields, pass a list of (key, direction) pairs::

            async for doc in collection.find().sort([
                    ('field1', pymongo.ASCENDING),
                    ('field2', pymongo.DESCENDING)]):
                print(doc)

        Beginning with MongoDB version 2.6, text search results can be
        sorted by relevance::

            cursor = db.test.find(
                {'$text': {'$search': 'some words'}},
                {'score': {'$meta': 'textScore'}})

            # Sort by 'score' field.
            cursor.sort([('score', {'$meta': 'textScore'})])

            async for doc in cursor:
                print(doc)

        Raises :class:`~pymongo.errors.InvalidOperation` if this cursor has
        already been used. Only the last :meth:`sort` applied to this
        cursor has any effect.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the keys to sort on
          - `direction` (optional): only used if `key_or_list` is a single
            key, if not given :data:`~pymongo.ASCENDING` is assumed
        """
        self.__check_okay_to_chain()
        keys = helpers._index_list(key_or_list, direction)
        self.__ordering = helpers._index_document(keys)
        return self
Example #10
0
    def sort(self, key_or_list, direction=None):
        """Sorts this cursor's results.

        Pass a field name and a direction, either
        :data:`~pymongo.ASCENDING` or :data:`~pymongo.DESCENDING`::

            for doc in collection.find().sort('field', pymongo.ASCENDING):
                print(doc)

        To sort by multiple fields, pass a list of (key, direction) pairs::

            for doc in collection.find().sort([
                    ('field1', pymongo.ASCENDING),
                    ('field2', pymongo.DESCENDING)]):
                print(doc)

        Beginning with MongoDB version 2.6, text search results can be
        sorted by relevance::

            cursor = db.test.find(
                {'$text': {'$search': 'some words'}},
                {'score': {'$meta': 'textScore'}})

            # Sort by 'score' field.
            cursor.sort([('score', {'$meta': 'textScore'})])

            for doc in cursor:
                print(doc)

        Raises :class:`~pymongo.errors.InvalidOperation` if this cursor has
        already been used. Only the last :meth:`sort` applied to this
        cursor has any effect.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the keys to sort on
          - `direction` (optional): only used if `key_or_list` is a single
            key, if not given :data:`~pymongo.ASCENDING` is assumed
        """
        self.__check_okay_to_chain()
        keys = helpers._index_list(key_or_list, direction)
        self.__ordering = helpers._index_document(keys)
        return self
Example #11
0
    def sort(self, key_or_list, direction=None):
        """Sorts this cursor's results.

        Takes either a single key and a direction, or a list of (key,
        direction) pairs. The key(s) must be an instance of ``(str,
        unicode)``, and the direction(s) must be one of
        (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`). Raises
        :class:`~pymongo.errors.InvalidOperation` if this cursor has
        already been used. Only the last :meth:`sort` applied to this
        cursor has any effect.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the keys to sort on
          - `direction` (optional): only used if `key_or_list` is a single
            key, if not given :data:`~pymongo.ASCENDING` is assumed
        """
        self.__check_okay_to_chain()
        keys = helpers._index_list(key_or_list, direction)
        self.__ordering = helpers._index_document(keys)
        return self
Example #12
0
    def sort(self, key_or_list, direction=None):
        """Sorts this cursor's results.

        Takes either a single key and a direction, or a list of (key,
        direction) pairs. The key(s) must be an instance of ``(str,
        unicode)``, and the direction(s) must be one of
        (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`). Raises
        :class:`~pymongo.errors.InvalidOperation` if this cursor has
        already been used. Only the last :meth:`sort` applied to this
        cursor has any effect.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the keys to sort on
          - `direction` (optional): only used if `key_or_list` is a single
            key, if not given :data:`~pymongo.ASCENDING` is assumed
        """
        self.__check_okay_to_chain()
        keys = helpers._index_list(key_or_list, direction)
        self.__ordering = helpers._index_document(keys)
        return self
Example #13
0
    def create_index(self, key_or_list, cache_for=300, **kwargs):
        """Creates an index on this collection.

        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 directions must be one of
        (:data:`~pymongo.ASCENDING`, :data:`~pymongo.DESCENDING`,
        :data:`~pymongo.GEO2D`). Returns the name of the created index.

        All optional index creation paramaters should be passed as
        keyword arguments to this method. Valid options include:
        check http://docs.mongodb.org/manual/reference/method/db.collection.ensureIndex/#db.collection.ensureIndex
        """
        keys = _index_list(key_or_list)
        index = {"key": _index_document(keys), "ns": self._collection_name}
        name = "name" in kwargs and kwargs["name"] or helpers._gen_index_name(keys)
        index["name"] = name
        index.update(kwargs)

        Client(self._database, 'system.indexes').insert(index, check_keys=False)
        self._database._cache_index(self._collection, name, cache_for)

        return name
    def create_index(self, key_or_list, unique=False, ttl=300):
        """Creates an index on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        directions must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`). Returns the name of the created
        index.

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to create
          - `unique` (optional): should this index guarantee
            uniqueness?
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index` - see documentation for
            :meth:`ensure_index` for details
        """
        if not isinstance(key_or_list, (str, unicode, list)):
            raise TypeError("key_or_list must either be a single key "
                            "or a list of (key, direction) pairs")

        to_save = SON()
        keys = helpers._index_list(key_or_list)
        name = self._gen_index_name(keys)
        to_save["name"] = name
        to_save["ns"] = self.__full_name
        to_save["key"] = helpers._index_document(keys)
        to_save["unique"] = unique

        self.__database.connection._cache_index(self.__database.name,
                                                self.__name, name, ttl)

        self.__database.system.indexes.insert(to_save, manipulate=False,
                                              check_keys=False)
        return to_save["name"]
Example #15
0
    def ensure_index(self, key_or_list, deprecated_unique=None,
                     ttl=300, **kwargs):
        """Ensures that an index exists on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        direction(s) must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). See
        :meth:`create_index` for a detailed example.

        Unlike :meth:`create_index`, which attempts to create an index
        unconditionally, :meth:`ensure_index` takes advantage of some
        caching within the driver such that it only attempts to create
        indexes that might not already exist. When an index is created
        (or ensured) by PyMongo it is "remembered" for `ttl`
        seconds. Repeated calls to :meth:`ensure_index` within that
        time limit will be lightweight - they will not attempt to
        actually create the index.

        Care must be taken when the database is being accessed through
        multiple connections at once. If an index is created using
        PyMongo and then deleted using another connection any call to
        :meth:`ensure_index` within the cache window will fail to
        re-create the missing index.

        Returns the name of the created index if an index is actually
        created. Returns ``None`` if the index already exists.

        All optional index creation paramaters should be passed as
        keyword arguments to this method. Valid options include:

          - `name`: custom name to use for this index - if none is
            given, a name will be generated
          - `unique`: should this index guarantee uniqueness?
          - `dropDups` or `drop_dups`: should we drop duplicates
            during index creation when creating a unique index?
          - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
            index
          - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
            index

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to create
          - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index`
          - `**kwargs` (optional): any additional index creation
            options (see the above list) should be passed as keyword
            arguments

        .. versionchanged:: 1.5.1
           Accept kwargs to support all index creation options.

        .. versionadded:: 1.5
           The `name` parameter.

        .. seealso:: :meth:`create_index`
        """
        if "name" in kwargs:
            name = kwargs["name"]
        else:
            keys = helpers._index_list(key_or_list)
            name = kwargs["name"] = _gen_index_name(keys)

        if self.__database.connection._cache_index(self.__database.name,
                                                   self.__name, name, ttl):
            return self.create_index(key_or_list, deprecated_unique,
                                     ttl, **kwargs)
        return None
Example #16
0
    def create_index(self, key_or_list, deprecated_unique=None,
                     ttl=300, **kwargs):
        """Creates an index on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        directions must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). Returns
        the name of the created index.

        To create a single key index on the key ``'mike'`` we just use
        a string argument:

        >>> my_collection.create_index("mike")

        For a compound index on ``'mike'`` descending and ``'eliot'``
        ascending we need to use a list of tuples:

        >>> my_collection.create_index([("mike", pymongo.DESCENDING),
        ...                             ("eliot", pymongo.ASCENDING)])

        All optional index creation paramaters should be passed as
        keyword arguments to this method. Valid options include:

          - `name`: custom name to use for this index - if none is
            given, a name will be generated
          - `unique`: should this index guarantee uniqueness?
          - `dropDups` or `drop_dups`: should we drop duplicates
            during index creation when creating a unique index?
          - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
            index
          - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
            index

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to create
          - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index` - see documentation for
            :meth:`ensure_index` for details
          - `**kwargs` (optional): any additional index creation
            options (see the above list) should be passed as keyword
            arguments

        .. versionchanged:: 1.5.1
           Accept kwargs to support all index creation options.

        .. versionadded:: 1.5
           The `name` parameter.

        .. seealso:: :meth:`ensure_index`

        .. mongodoc:: indexes
        """
        keys = helpers._index_list(key_or_list)
        index_doc = helpers._index_document(keys)

        index = {"key": index_doc, "ns": self.__full_name}

        if deprecated_unique is not None:
            warnings.warn("using a positional arg to specify unique is "
                          "deprecated, please use kwargs",
                          DeprecationWarning)
            index["unique"] = deprecated_unique

        name = "name" in kwargs and kwargs["name"] or _gen_index_name(keys)
        index["name"] = name

        if "drop_dups" in kwargs:
            kwargs["dropDups"] = kwargs.pop("drop_dups")

        index.update(kwargs)

        self.__database.connection._cache_index(self.__database.name,
                                                self.__name, name, ttl)

        self.__database.system.indexes.insert(index, manipulate=False,
                                              check_keys=False)
        return name
    def ensure_index(self, key_or_list, deprecated_unique=None,
                     ttl=300, **kwargs):
        """Ensures that an index exists on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        direction(s) must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). See
        :meth:`create_index` for a detailed example.

        Unlike :meth:`create_index`, which attempts to create an index
        unconditionally, :meth:`ensure_index` takes advantage of some
        caching within the driver such that it only attempts to create
        indexes that might not already exist. When an index is created
        (or ensured) by PyMongo it is "remembered" for `ttl`
        seconds. Repeated calls to :meth:`ensure_index` within that
        time limit will be lightweight - they will not attempt to
        actually create the index.

        Care must be taken when the database is being accessed through
        multiple connections at once. If an index is created using
        PyMongo and then deleted using another connection any call to
        :meth:`ensure_index` within the cache window will fail to
        re-create the missing index.

        Returns the name of the created index if an index is actually
        created. Returns ``None`` if the index already exists.

        All optional index creation paramaters should be passed as
        keyword arguments to this method. Valid options include:

          - `name`: custom name to use for this index - if none is
            given, a name will be generated
          - `unique`: should this index guarantee uniqueness?
          - `dropDups` or `drop_dups`: should we drop duplicates
            during index creation when creating a unique index?
          - `background`: if this index should be created in the
            background
          - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
            index
          - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
            index

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to create
          - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index`
          - `**kwargs` (optional): any additional index creation
            options (see the above list) should be passed as keyword
            arguments

        .. versionchanged:: 1.5.1
           Accept kwargs to support all index creation options.

        .. versionadded:: 1.5
           The `name` parameter.

        .. seealso:: :meth:`create_index`
        """
        if "name" in kwargs:
            name = kwargs["name"]
        else:
            keys = helpers._index_list(key_or_list)
            name = kwargs["name"] = _gen_index_name(keys)

        if self.__database.connection._cache_index(self.__database.name,
                                                   self.__name, name, ttl):
            return self.create_index(key_or_list, deprecated_unique,
                                     ttl, **kwargs)
        return None
    def create_index(self, key_or_list, deprecated_unique=None,
                     ttl=300, **kwargs):
        """Creates an index on this collection.

        Takes either a single key or a list of (key, direction) pairs.
        The key(s) must be an instance of :class:`basestring`, and the
        directions must be one of (:data:`~pymongo.ASCENDING`,
        :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). Returns
        the name of the created index.

        To create a single key index on the key ``'mike'`` we just use
        a string argument:

        >>> my_collection.create_index("mike")

        For a compound index on ``'mike'`` descending and ``'eliot'``
        ascending we need to use a list of tuples:

        >>> my_collection.create_index([("mike", pymongo.DESCENDING),
        ...                             ("eliot", pymongo.ASCENDING)])

        All optional index creation paramaters should be passed as
        keyword arguments to this method. Valid options include:

          - `name`: custom name to use for this index - if none is
            given, a name will be generated
          - `unique`: should this index guarantee uniqueness?
          - `dropDups` or `drop_dups`: should we drop duplicates
            during index creation when creating a unique index?
          - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
            index
          - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
            index

        :Parameters:
          - `key_or_list`: a single key or a list of (key, direction)
            pairs specifying the index to create
          - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
          - `ttl` (optional): time window (in seconds) during which
            this index will be recognized by subsequent calls to
            :meth:`ensure_index` - see documentation for
            :meth:`ensure_index` for details
          - `**kwargs` (optional): any additional index creation
            options (see the above list) should be passed as keyword
            arguments

        .. versionchanged:: 1.5.1
           Accept kwargs to support all index creation options.

        .. versionadded:: 1.5
           The `name` parameter.

        .. seealso:: :meth:`ensure_index`

        .. mongodoc:: indexes
        """
        keys = helpers._index_list(key_or_list)
        index_doc = helpers._index_document(keys)

        index = {"key": index_doc, "ns": self.__full_name}

        if deprecated_unique is not None:
            warnings.warn("using a positional arg to specify unique is "
                          "deprecated, please use kwargs",
                          DeprecationWarning)
            index["unique"] = deprecated_unique

        name = "name" in kwargs and kwargs["name"] or _gen_index_name(keys)
        index["name"] = name

        if "drop_dups" in kwargs:
            kwargs["dropDups"] = kwargs.pop("drop_dups")

        index.update(kwargs)

        self.__database.system.indexes.insert(index, manipulate=False,
                                              check_keys=False,
                                              safe=True)

        self.__database.connection._cache_index(self.__database.name,
                                                self.__name, name, ttl)

        return name
Example #19
0
    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