docs: def map_reduce(self, map, reduce, out, full_response=False, **kwargs):
          """Perform a map/reduce operation on this collection.
  
          If `full_response` is ``False`` (default) returns a
          :class:`~pymongo.collection.Collection` instance containing
          the results of the operation. Otherwise, returns the full
          response from the server to the `map reduce command`_.
  
          :Parameters:
            - `map`: map function (as a JavaScript string)
            - `reduce`: reduce function (as a JavaScript string)
            - `out`: output collection name or `out object` (dict). See
              the `map reduce command`_ documentation for available options.
              Note: `out` options are order sensitive. :class:`~bson.son.SON`
              can be used to specify multiple options.
              e.g. SON([('replace', <collection name>), ('db', <database name>)])
            - `full_response` (optional): if ``True``, return full response to
              this command - otherwise just return the result collection
            - `**kwargs` (optional): additional arguments to the
              `map reduce command`_ may be passed as keyword arguments to this
              helper method, e.g.::
  
              >>> db.test.map_reduce(map, reduce, "myresults", limit=2)
  
          .. note:: The :meth:`map_reduce` method does **not** obey the
             :attr:`read_preference` of this :class:`Collection`. To run
             mapReduce on a secondary use the :meth:`inline_map_reduce` method
             instead.
  
          .. note:: The :attr:`~pymongo.collection.Collection.write_concern` of
             this collection is automatically applied to this operation (if the
             output is not inline) when using MongoDB >= 3.4.
  
          .. versionchanged:: 3.4
             Apply this collection's write concern automatically to this operation
             when connected to MongoDB >= 3.4.
  
          .. seealso:: :doc:`/examples/aggregation`
  
          .. versionchanged:: 3.4
             Added the `collation` option.
          .. versionchanged:: 2.2
             Removed deprecated arguments: merge_output and reduce_output
  
          .. _map reduce command: http://docs.mongodb.org/manual/reference/command/mapReduce/
  
          .. mongodoc:: mapreduce
  
          """
          if not isinstance(out, (string_type, collections.Mapping)):
              raise TypeError("'out' must be an instance of "
                              "%s or a mapping" % (string_type.__name__,))
  
          cmd = SON([("mapreduce", self.__name),
                     ("map", map),
                     ("reduce", reduce),
                     ("out", out)])
          collation = validate_collation_or_none(kwargs.pop('collation', None))
          cmd.update(kwargs)
  
          inline = 'inline' in cmd['out']
          with self._socket_for_primary_reads() as (sock_info, slave_ok):
              if (sock_info.max_wire_version >= 5 and self.write_concern and
                      not inline):
                  cmd['writeConcern'] = self.write_concern.document
              cmd.update(kwargs)
              if (sock_info.max_wire_version >= 4 and 'readConcern' not in cmd and
                      inline):
                  # No need to parse 'writeConcernError' here, since the command
                  # is an inline map reduce.
                  response = self._command(
                      sock_info, cmd, slave_ok, ReadPreference.PRIMARY,
                      read_concern=self.read_concern,
                      collation=collation)
              else:
                  response = self._command(
                      sock_info, cmd, slave_ok, ReadPreference.PRIMARY,
                      parse_write_concern_error=not inline,
                      collation=collation)
  
          if full_response or not response.get('result'):
              return response
          elif isinstance(response['result'], dict):
              dbase = response['result']['db']
              coll = response['result']['collection']
              return self.__database.client[dbase][coll]
          else:
              return self.__database[response["result"]]