def _copy_only_fields(self, doc, fields): """Copy only the specified fields.""" if fields is None: return copy.deepcopy(doc) else: if not fields: fields = {"_id": 1} if not isinstance(fields, dict): fields = helpers._fields_list_to_dict(fields) #we can pass in something like {"_id":0, "field":1}, so pull the id value out and hang on to it until later id_value = fields.pop('_id', 1) #other than the _id field, all fields must be either includes or excludes, this can evaluate to 0 if len(set(list(fields.values()))) > 1: raise ValueError('You cannot currently mix including and excluding fields.') #if we have novalues passed in, make a doc_copy based on the id_value if len(list(fields.values())) == 0: if id_value == 1: doc_copy = {} else: doc_copy = copy.deepcopy(doc) #if 1 was passed in as the field values, include those fields elif list(fields.values())[0] == 1: doc_copy = {} for key in fields: if key in doc: doc_copy[key] = doc[key] #otherwise, exclude the fields passed in else: doc_copy = copy.deepcopy(doc) for key in fields: if key in doc_copy: del doc_copy[key] #set the _id value if we requested it, otherwise remove it if id_value == 0: if '_id' in doc_copy: del doc_copy['_id'] else: if '_id' in doc: doc_copy['_id'] = doc['_id'] fields['_id'] = id_value #put _id back in fields return doc_copy
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()
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
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