Esempio n. 1
0
    def hint(self, index):
        """Adds a 'hint', telling Mongo the proper index to use for the query.

        Judicious use of hints can greatly improve query
        performance. When doing a query on multiple fields (at least
        one of which is indexed) pass the indexed field as a hint to
        the query. Hinting will not do anything if the corresponding
        index does not exist. Raises
        :class:`~pymongo.errors.InvalidOperation` if this cursor has
        already been used.

        `index` should be an index as passed to
        :meth:`~apymongo.collection.Collection.create_index`
        (e.g. ``[('field', ASCENDING)]``). If `index`
        is ``None`` any existing hints for this query are cleared. The
        last hint applied to this cursor takes precedence over all
        others.

        :Parameters:
          - `index`: index to hint on (as an index specifier)
        """
        self.__check_okay_to_chain()
        if index is None:
            self.__hint = None
            return self

        self.__hint = helpers._index_document(index)
        return self
Esempio n. 2
0
    def hint(self, index):
        """Adds a 'hint', telling Mongo the proper index to use for the query.

        Judicious use of hints can greatly improve query
        performance. When doing a query on multiple fields (at least
        one of which is indexed) pass the indexed field as a hint to
        the query. Hinting will not do anything if the corresponding
        index does not exist. Raises
        :class:`~pymongo.errors.InvalidOperation` if this cursor has
        already been used.

        `index` should be an index as passed to
        :meth:`~pymongo.collection.Collection.create_index`
        (e.g. ``[('field', ASCENDING)]``). If `index`
        is ``None`` any existing hints for this query are cleared. The
        last hint applied to this cursor takes precedence over all
        others.

        :Parameters:
          - `index`: index to hint on (as an index specifier)
        """
        self.__check_okay_to_chain()
        if index is None:
            self.__hint = None
            return self

        self.__hint = helpers._index_document(index)
        return self
Esempio n. 3
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:`~apymongo.ASCENDING`,
        :data:`~apymongo.DESCENDING`). Raises
        :class:`~apymongo.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:`~apymongo.ASCENDING` is assumed
        """
        self.__check_okay_to_chain()
        keys = helpers._index_list(key_or_list, direction)
        self.__ordering = helpers._index_document(keys)
        return self
Esempio n. 4
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
Esempio n. 5
0
    def create_index(self, key_or_list, deprecated_unique=None,
                     ttl=300, callback = None, **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:`~apymongo.ASCENDING`,
        :data:`~apymongo.DESCENDING`, :data:`~apymongo.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

        .. 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)
        
        
        def mod_callback(resp):
            
            if not isinstance(resp,Exception):
                self.__database.connection._cache_index(self.__database.name,
                                                    self.__name, name, ttl)
                if callback:
                    callback(name)
            else:
                if callback:
                    callback(resp)
                else:
                    raise resp
                

        self.__database.system.indexes.insert(index, manipulate=False,
                                              check_keys=False,
                                              safe=True,callback = mod_callback)
Esempio n. 6
0
    def __init__(self, collection, 
                 callback = None, 
                 processor = None, 
                 spec=None, 
                 fields=None, 
                 skip=0, 
                 limit=0,
                 timeout=True, 
                 snapshot=False, 
                 tailable=False, 
                 sort=None,
                 max_scan=None, 
                 as_class=None,
                 store = True,
                 _must_use_master=False, 
                 _is_command=False,
                 **kwargs):
        """Create a new cursor.

        Should not be called directly by application developers - see
        :meth:`~pymongo.collection.Collection.find` instead.

        .. mongodoc:: cursors
        """
        self.__id = None

        self.__error = None

        if spec is None:
            spec = {}

        if not isinstance(spec, dict):
            raise TypeError("spec must be an instance of dict")
        if not isinstance(skip, int):
            raise TypeError("skip must be an instance of int")
        if not isinstance(limit, int):
            raise TypeError("limit must be an instance of int")
        if not isinstance(timeout, bool):
            raise TypeError("timeout must be an instance of bool")
        if not isinstance(snapshot, bool):
            raise TypeError("snapshot must be an instance of bool")
        if not isinstance(tailable, bool):
            raise TypeError("tailable must be an instance of bool")

        if fields is not None:
            if not fields:
                fields = {"_id": 1}
            if not isinstance(fields, dict):
                fields = helpers._fields_list_to_dict(fields)

        if as_class is None:
            as_class = collection.database.connection.document_class

        self.__collection = collection
        self.__callback = callback
        self.__processor = processor
        self.__spec = spec
        self.__fields = fields
        self.__skip = skip
        self.__limit = limit
        self.__batch_size = 0
        self.__store = store

        self.__empty = False

        self.__timeout = timeout
        self.__tailable = tailable
        self.__snapshot = snapshot
        self.__ordering = sort and helpers._index_document(sort) or None
        self.__max_scan = max_scan
        self.__explain = False
        self.__hint = None
        self.__as_class = as_class
        self.__tz_aware = collection.database.connection.tz_aware
        self.__must_use_master = _must_use_master
        self.__is_command = _is_command

        self.__data = []
        self.__datastore = []
        self.__connection_id = None
        self.__retrieved = 0
        self.__killed = False

        # this is for passing network_timeout through if it's specified
        # need to use kwargs as None is a legit value for network_timeout
        self.__kwargs = kwargs
Esempio n. 7
0
    def __init__(self,
                 collection,
                 callback=None,
                 processor=None,
                 spec=None,
                 fields=None,
                 skip=0,
                 limit=0,
                 timeout=True,
                 snapshot=False,
                 tailable=False,
                 sort=None,
                 max_scan=None,
                 as_class=None,
                 store=True,
                 _must_use_master=False,
                 _is_command=False,
                 **kwargs):
        """Create a new cursor.

        Should not be called directly by application developers - see
        :meth:`~pymongo.collection.Collection.find` instead.

        .. mongodoc:: cursors
        """
        self.__id = None

        self.__error = None

        if spec is None:
            spec = {}

        if not isinstance(spec, dict):
            raise TypeError("spec must be an instance of dict")
        if not isinstance(skip, int):
            raise TypeError("skip must be an instance of int")
        if not isinstance(limit, int):
            raise TypeError("limit must be an instance of int")
        if not isinstance(timeout, bool):
            raise TypeError("timeout must be an instance of bool")
        if not isinstance(snapshot, bool):
            raise TypeError("snapshot must be an instance of bool")
        if not isinstance(tailable, bool):
            raise TypeError("tailable must be an instance of bool")

        if fields is not None:
            if not fields:
                fields = {"_id": 1}
            if not isinstance(fields, dict):
                fields = helpers._fields_list_to_dict(fields)

        if as_class is None:
            as_class = collection.database.connection.document_class

        self.__collection = collection
        self.__callback = callback
        self.__processor = processor
        self.__spec = spec
        self.__fields = fields
        self.__skip = skip
        self.__limit = limit
        self.__batch_size = 0
        self.__store = store

        self.__empty = False

        self.__timeout = timeout
        self.__tailable = tailable
        self.__snapshot = snapshot
        self.__ordering = sort and helpers._index_document(sort) or None
        self.__max_scan = max_scan
        self.__explain = False
        self.__hint = None
        self.__as_class = as_class
        self.__tz_aware = collection.database.connection.tz_aware
        self.__must_use_master = _must_use_master
        self.__is_command = _is_command

        self.__data = []
        self.__datastore = []
        self.__connection_id = None
        self.__retrieved = 0
        self.__killed = False

        # this is for passing network_timeout through if it's specified
        # need to use kwargs as None is a legit value for network_timeout
        self.__kwargs = kwargs
Esempio n. 8
0
 def __init__(self, collection, callback=None, processor=None, spec=None, fields=None, skip=0, limit=0,
              timeout=True, snapshot=False, tailable=False, sort=None,
              max_scan=None, as_class=None, slave_okay=False,
              await_data=False, partial=False, manipulate=True,
              read_preference=ReadPreference.PRIMARY,
              _must_use_master=False, _is_command=False,
              _uuid_subtype=None, **kwargs):
     """Create a new cursor.
     
     Should not be called directly by application developers - see
     :meth:`~pymongo.collection.Collection.find` instead.
     
     .. mongodoc:: cursors
     """
     self.__id = None
     
     self.__error = None
     
     if spec is None:
         spec = {}
     
     if not isinstance(spec, dict):
         raise TypeError("spec must be an instance of dict")
     if not isinstance(skip, int):
         raise TypeError("skip must be an instance of int")
     if not isinstance(limit, int):
         raise TypeError("limit must be an instance of int")
     if not isinstance(timeout, bool):
         raise TypeError("timeout must be an instance of bool")
     if not isinstance(snapshot, bool):
         raise TypeError("snapshot must be an instance of bool")
     if not isinstance(tailable, bool):
         raise TypeError("tailable must be an instance of bool")
     if not isinstance(slave_okay, bool):
         raise TypeError("slave_okay must be an instance of bool")
     if not isinstance(await_data, bool):
         raise TypeError("await_data must be an instance of bool")
     if not isinstance(partial, bool):
         raise TypeError("partial must be an instance of bool")
     
     if fields is not None:
         if not fields:
             fields = {"_id": 1}
         if not isinstance(fields, dict):
             fields = helpers._fields_list_to_dict(fields)
     
     if as_class is None:
         as_class = collection.database.connection.document_class
     
     self.__collection = collection
     self.__callback = callback
     self.__processor = processor
     self.__spec = spec
     self.__fields = fields
     self.__skip = skip
     self.__limit = limit
     self.__batch_size = 0
     # self.__store = True
     
     # This is ugly. People want to be able to do cursor[5:5] and
     # get an empty result set (old behavior was an
     # exception). It's hard to do that right, though, because the
     # server uses limit(0) to mean 'no limit'. So we set __empty
     # in that case and check for it when iterating. We also unset
     # it anytime we change __limit.
     self.__empty = False
     
     self.__timeout = timeout
     self.__tailable = tailable
     self.__await_data = tailable and await_data
     self.__partial = partial
     self.__snapshot = snapshot
     self.__ordering = sort and helpers._index_document(sort) or None
     self.__max_scan = max_scan
     self.__explain = False
     self.__hint = None
     self.__as_class = as_class
     self.__slave_okay = slave_okay
     self.__manipulate = manipulate
     self.__read_preference = read_preference
     self.__tz_aware = collection.database.connection.tz_aware
     self.__must_use_master = _must_use_master
     self.__is_command = _is_command
     self.__uuid_subtype = _uuid_subtype or collection.uuid_subtype
     self.__query_flags = 0
     
     self.__data = []
     self.__datastore = []
     self.__connection_id = None
     self.__retrieved = 0
     self.__killed = False
     
     # this is for passing network_timeout through if it's specified
     # need to use kwargs as None is a legit value for network_timeout
     self.__kwargs = kwargs