def group(self, key, condition, initial, reduce, callback, finalize=None, command=True): """Perform a query similar to an SQL *group by* operation. Returns an array of grouped items. The `key` parameter can be: - ``None`` to use the entire document as a key. - A :class:`list` of keys (each a :class:`basestring`) to group by. - A :class:`basestring` or :class:`~bson.code.Code` instance containing a JavaScript function to be applied to each document, returning the key to group by. :Parameters: - `key`: fields to group by (see above description) - `condition`: specification of rows to be considered (as a :meth:`find` query specification) - `initial`: initial value of the aggregation counter object - `reduce`: aggregation function as a JavaScript string - `finalize`: function to be called on each object in output list. - `command` (optional): DEPRECATED if ``True``, run the group as a command instead of in an eval - this option is deprecated and will be removed in favor of running all groups as commands .. versionchanged:: 1.4 The `key` argument can now be ``None`` or a JavaScript function, in addition to a :class:`list` of keys. .. versionchanged:: 1.3 The `command` argument now defaults to ``True`` and is deprecated. """ if not command: warnings.warn("eval-based groups are deprecated, and the " "command option will be removed.", DeprecationWarning) group = {} if isinstance(key, basestring): group["$keyf"] = Code(key) elif key is not None: group = {"key": helpers._fields_list_to_dict(key)} group["ns"] = self.__name group["$reduce"] = Code(reduce) group["cond"] = condition group["initial"] = initial if finalize is not None: group["finalize"] = Code(finalize) def mod_callback(resp): callback(resp["retval"]) self.__database.command("group", callback=mod_callback, value = group)
def command(self, command, value=1, callback=None, check=True, allowable_errors=[], uuid_subtype=OLD_UUID_SUBTYPE, **kwargs): """Issue a MongoDB command. Send command `command` to the database and return the response. If `command` is an instance of :class:`basestring` (:class:`str` in python 3) then the command {`command`: `value`} will be sent. Otherwise, `command` must be an instance of :class:`dict` and will be sent as is. Command responses will be passed to callback. Any additional keyword arguments will be added to the final command document before it is sent. For example, a command like ``{buildinfo: 1}`` can be sent using: >>> db.command("buildinfo") For a command where the value matters, like ``{collstats: collection_name}`` we can do: >>> db.command("collstats", collection_name) For commands that take additional arguments we can use kwargs. So ``{filemd5: object_id, root: file_root}`` becomes: >>> db.command("filemd5", object_id, root=file_root) :Parameters: - `command`: document representing the command to be issued, or the name of the command (for simple commands only). .. note:: the order of keys in the `command` document is significant (the "verb" must come first), so commands which require multiple keys (e.g. `findandmodify`) should use an instance of :class:`~bson.son.SON` or a string and kwargs instead of a Python `dict`. - `value` (optional): value to use for the command verb when `command` is passed as a string - `check` (optional): check the response for errors, raising :class:`~pymongo.errors.OperationFailure` if there are any - `allowable_errors`: if `check` is ``True``, error messages in this list will be ignored by error-checking - `uuid_subtype` (optional): The BSON binary subtype to use for a UUID used in this command. - `**kwargs` (optional): additional keyword arguments will be added to the command document before it is sent .. versionchanged:: 2.1.1+ Added support for `as_class` - the class you want to use for the resulting documents .. versionchanged:: 1.6 Added the `value` argument for string commands, and keyword arguments for additional command options. .. versionchanged:: 1.5 `command` can be a string in addition to a full document. .. versionadded:: 1.4 .. mongodoc:: commands """ if isinstance(command, basestring): command = SON([(command, value)]) extra_opts = { 'as_class': kwargs.pop('as_class', None), 'read_preference': kwargs.pop('read_preference', self.read_preference), 'slave_okay': kwargs.pop('slave_okay', self.slave_okay), '_must_use_master': kwargs.pop('_use_master', True), '_is_command': True, '_uuid_subtype': uuid_subtype } fields = kwargs.get('fields') if fields is not None and not isinstance(fields, dict): kwargs['fields'] = helpers._fields_list_to_dict(fields) command.update(kwargs) if callback: def mod_callback(result): if not isinstance(result, Exception): if check: msg = "command %s failed: %%s" % repr(command).replace("%", "%%") helpers._check_command_response(result, self.connection.disconnect, msg, allowable_errors) callback(result) else: callback(result) else: mod_callback = None self["$cmd"].find_one(spec_or_id = command, callback=mod_callback, **extra_opts)
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
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
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