Exemplo 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:`~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

        if not isinstance(index, (types.ListType)):
            raise TypeError("hint takes a list specifying an index")
        self.__hint = helpers._index_document(index)
        return self
Exemplo 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

        if not isinstance(index, (types.ListType)):
            raise TypeError("hint takes a list specifying an index")
        self.__hint = helpers._index_document(index)
        return self
Exemplo n.º 3
0
    def create_index(self, key_or_list, direction=None, 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 ``(str, unicode)``, 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
          - `direction` (optional): DEPRECATED this option will be removed
          - `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"
            )

        if direction is not None:
            warnings.warn(
                "specifying a direction for a single key index is "
                "deprecated and will be removed. there is no need "
                "for a direction on a single key index", DeprecationWarning)

        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"]
Exemplo n.º 4
0
    def create_index(self, key_or_list, direction=None, 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 ``(str, unicode)``, 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
          - `direction` (optional): DEPRECATED this option will be removed
          - `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")

        if direction is not None:
            warnings.warn("specifying a direction for a single key index is "
                          "deprecated and will be removed. there is no need "
                          "for a direction on a single key index",
                          DeprecationWarning)

        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"]
Exemplo n.º 5
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
Exemplo n.º 6
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
Exemplo n.º 7
0
 def find(self, spec=None, fields=None, skip=0, limit=0,
              timeout=True, snapshot=False, tailable=False, sort=None,
              max_scan=None,
              _must_use_master=False, _is_command=False,
              callback=None):
     """Query the database.
     
     The `spec` argument is a prototype document that all results
     must match. For example:
     
     >>> db.test.find({"hello": "world"}, callback=...)
     
     only matches documents that have a key "hello" with value
     "world".  Matches can have other keys *in addition* to
     "hello". The `fields` argument is used to specify a subset of
     fields that should be included in the result documents. By
     limiting results to a certain subset of fields you can cut
     down on network traffic and decoding time.
     
     Raises :class:`TypeError` if any of the arguments are of
     improper type.
     
     :Parameters:
       - `spec` (optional): a SON object specifying elements which
         must be present for a document to be included in the
         result set
       - `fields` (optional): a list of field names that should be
         returned in the result set ("_id" will always be
         included), or a dict specifying the fields to return
       - `skip` (optional): the number of documents to omit (from
         the start of the result set) when returning the results
       - `limit` (optional): the maximum number of results to
         return
       - `timeout` (optional): if True, any returned cursor will be
         subject to the normal timeout behavior of the mongod
         process. Otherwise, the returned cursor will never timeout
         at the server. Care should be taken to ensure that cursors
         with timeout turned off are properly closed.
       - `snapshot` (optional): if True, snapshot mode will be used
         for this query. Snapshot mode assures no duplicates are
         returned, or objects missed, which were present at both
         the start and end of the query's execution. For details,
         see the `snapshot documentation
         <http://dochub.mongodb.org/core/snapshot>`_.
       - `tailable` (optional): the result of this find call will
         be a tailable cursor - tailable cursors aren't closed when
         the last data is retrieved but are kept open and the
         cursors location marks the final document's position. if
         more data is received iteration of the cursor will
         continue from the last document received. For details, see
         the `tailable cursor documentation
         <http://www.mongodb.org/display/DOCS/Tailable+Cursors>`_.
       - `sort` (optional): a list of (key, direction) pairs
         specifying the sort order for this query. See
         :meth:`~pymongo.cursor.Cursor.sort` for details.
       - `max_scan` (optional): limit the number of documents
         examined when performing the query
     
     .. mongodoc:: find
     """
     
     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 callable(callback):
         raise TypeError("callback must be callable")
     
     if fields is not None:
         if not fields:
             fields = {"_id": 1}
         if not isinstance(fields, dict):
             fields = helpers._fields_list_to_dict(fields)
     
     self.__spec = spec
     self.__fields = fields
     self.__skip = skip
     self.__limit = limit
     self.__batch_size = 0
     
     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 = False #collection.database.connection.tz_aware
     self.__must_use_master = _must_use_master
     self.__is_command = _is_command
     
     connection = self.__pool.connection()
     try:
         connection.send_message(
             message.query(self.__query_options(),
                           self.full_collection_name,
                           self.__skip, 
                           self.__limit,
                           self.__query_spec(),
                           self.__fields), 
             callback=functools.partial(self._handle_response, orig_callback=callback))
     except Exception as e:
         connection.close()
Exemplo n.º 8
0
 def find(self, spec=None, fields=None, skip=0, limit=0,
              timeout=True, snapshot=False, tailable=False, sort=None,
              max_scan=None, slave_okay=False,
              _must_use_master=False, _is_command=False,
              callback=None):
     """Query the database.
     
     The `spec` argument is a prototype document that all results
     must match. For example:
     
     >>> db.test.find({"hello": "world"}, callback=...)
     
     only matches documents that have a key "hello" with value
     "world".  Matches can have other keys *in addition* to
     "hello". The `fields` argument is used to specify a subset of
     fields that should be included in the result documents. By
     limiting results to a certain subset of fields you can cut
     down on network traffic and decoding time.
     
     Raises :class:`TypeError` if any of the arguments are of
     improper type.
     
     :Parameters:
       - `spec` (optional): a SON object specifying elements which
         must be present for a document to be included in the
         result set
       - `fields` (optional): a list of field names that should be
         returned in the result set ("_id" will always be
         included), or a dict specifying the fields to return
       - `skip` (optional): the number of documents to omit (from
         the start of the result set) when returning the results
       - `limit` (optional): the maximum number of results to
         return
       - `timeout` (optional): if True, any returned cursor will be
         subject to the normal timeout behavior of the mongod
         process. Otherwise, the returned cursor will never timeout
         at the server. Care should be taken to ensure that cursors
         with timeout turned off are properly closed.
       - `snapshot` (optional): if True, snapshot mode will be used
         for this query. Snapshot mode assures no duplicates are
         returned, or objects missed, which were present at both
         the start and end of the query's execution. For details,
         see the `snapshot documentation
         <http://dochub.mongodb.org/core/snapshot>`_.
       - `tailable` (optional): the result of this find call will
         be a tailable cursor - tailable cursors aren't closed when
         the last data is retrieved but are kept open and the
         cursors location marks the final document's position. if
         more data is received iteration of the cursor will
         continue from the last document received. For details, see
         the `tailable cursor documentation
         <http://www.mongodb.org/display/DOCS/Tailable+Cursors>`_.
       - `sort` (optional): a list of (key, direction) pairs
         specifying the sort order for this query. See
         :meth:`~pymongo.cursor.Cursor.sort` for details.
       - `max_scan` (optional): limit the number of documents
         examined when performing the query
       - `slave_okay` (optional): is it okay to connect directly
         to and perform queries on a slave instance
     
     .. mongodoc:: find
     """
     
     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 callable(callback):
         raise TypeError("callback must be callable")
     
     if fields is not None:
         if not fields:
             fields = {"_id": 1}
         if not isinstance(fields, dict):
             fields = helpers._fields_list_to_dict(fields)
     
     self.__spec = spec
     self.__fields = fields
     self.__skip = skip
     self.__limit = limit
     self.__batch_size = 0
     
     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.__slave_okay = slave_okay
     self.__explain = False
     self.__hint = None
     # self.__as_class = as_class
     self.__tz_aware = False #collection.database.connection.tz_aware
     self.__must_use_master = _must_use_master
     self.__is_command = _is_command
     
     connection = self.__pool.connection()
     try:
         connection.send_message(
             message.query(self.__query_options(),
                           self.full_collection_name,
                           self.__skip, 
                           self.__limit,
                           self.__query_spec(),
                           self.__fields), 
             callback=functools.partial(self._handle_response, orig_callback=callback))
     except Exception, e:
         logging.error('Error sending query %s' % e)
         connection.close()
         raise
Exemplo n.º 9
0
    def find(self, spec=None, fields=None, skip=0, limit=0,
                 timeout=True, snapshot=False, tailable=False, sort=None,
                 max_scan=None, slave_okay=False,
                 await_data=False,
                 _must_use_master=False, _is_command=False,
                 callback=None, batch_size=0):
        """Query the database.

        The `spec` argument is a prototype document that all results
        must match. For example:

        >>> db.test.find({"hello": "world"}, callback=...)

        only matches documents that have a key "hello" with value
        "world".  Matches can have other keys *in addition* to
        "hello". The `fields` argument is used to specify a subset of
        fields that should be included in the result documents. By
        limiting results to a certain subset of fields you can cut
        down on network traffic and decoding time.

        Raises :class:`TypeError` if any of the arguments are of
        improper type.

        Returns a cursor. find() calls your callback either with an error,
        or with the first 100 documents. You must call get_more() repeatedly
        on the cursor until it is exhausted:

        class Handler(tornado.web.RequestHandler):
          @tornado.web.asynchronous
          def get(self):
            self.cursor = self.db.collection.find({}, batch_size=300,
              callback=self._on_response
            )

          def _on_response(self, response, error):
            assert not error
            self.write(str(response))
            if self.cursor.alive:
              self.cursor.get_more(self._on_response)
            else:
              self.finish()

        :Parameters:
          - `spec` (optional): a SON object specifying elements which
            must be present for a document to be included in the
            result set
          - `fields` (optional): a list of field names that should be
            returned in the result set ("_id" will always be
            included), or a dict specifying the fields to return
          - `skip` (optional): the number of documents to omit (from
            the start of the result set) when returning the results
          - `limit` (optional): the maximum number of results to
            return
          - `timeout` (optional): if True, any returned cursor will be
            subject to the normal timeout behavior of the mongod
            process. Otherwise, the returned cursor will never timeout
            at the server. Care should be taken to ensure that cursors
            with timeout turned off are properly closed.
          - `snapshot` (optional): if True, snapshot mode will be used
            for this query. Snapshot mode assures no duplicates are
            returned, or objects missed, which were present at both
            the start and end of the query's execution. For details,
            see the `snapshot documentation
            <http://dochub.mongodb.org/core/snapshot>`_.
          - `tailable` (optional): the result of this find call will
            be a tailable cursor - tailable cursors aren't closed when
            the last data is retrieved but are kept open and the
            cursors location marks the final document's position. if
            more data is received iteration of the cursor will
            continue from the last document received. For details, see
            the `tailable cursor documentation
            <http://www.mongodb.org/display/DOCS/Tailable+Cursors>`_.
            .. versionadded:: 1.2
          - `sort` (optional): a list of (key, direction) pairs
            specifying the sort order for this query. See
            :meth:`~pymongo.cursor.Cursor.sort` for details.
          - `max_scan` (optional): limit the number of documents
            examined when performing the query
          - `slave_okay` (optional): is it okay to connect directly
            to and perform queries on a slave instance
          - `await_data` (optional): if True, the server will block for
            some extra time before returning, waiting for more data to
            return. Ignored if `tailable` is False.
            .. versionadded:: 1.2
          - `callback` (optional): a function that takes arguments (result,
            error): a list of result documents, or an Exception
          - `batch_size`: The size of each batch of results requested.
            .. versionadded:: 1.2

        .. mongodoc:: find
        """

        if self.__id and self.alive:
            logging.warn("Do not call find() twice on the same collection object")

        if spec is None:
            spec = {}
        
        if limit is None:
            limit = 0

        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 or None")
        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(await_data, bool):
            raise TypeError("await_data must be an instance of bool")
        if not callable(callback):
            raise TypeError("callback must be callable")

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

        self.__spec = spec
        self.__fields = fields
        self.__skip = skip
        self.__limit = limit
        self.__batch_size = batch_size

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

        ntoreturn = self.__batch_size
        if self.__limit:
            if self.__batch_size:
                ntoreturn = min(self.__limit, self.__batch_size)
            else:
                ntoreturn = self.__limit

        def _handle_conn(connection):
            try:
                connection.send_message(
                    message.query(self.__query_options(),
                                  self.full_collection_name,
                                  self.__skip,
                                  ntoreturn,
                                  self.__query_spec(),
                                  self.__fields),
                    callback=functools.partial(self._handle_response, orig_callback=callback))
            except Exception, e:
                logging.error('Error sending query %s' % e)
                connection.close()
                raise