21
21
from pymongo import (helpers ,
22
22
message )
23
23
from pymongo .cursor import Cursor
24
- from pymongo .errors import InvalidName
24
+ from pymongo .errors import InvalidName , InvalidOperation
25
25
26
26
_ZERO = "\x00 \x00 \x00 \x00 "
27
27
@@ -914,7 +914,8 @@ def distinct(self, key):
914
914
"""
915
915
return self .find ().distinct (key )
916
916
917
- def map_reduce (self , map , reduce , full_response = False , ** kwargs ):
917
+ def map_reduce (self , map , reduce , out , merge_output = False ,
918
+ reduce_output = False , full_response = False , ** kwargs ):
918
919
"""Perform a map/reduce operation on this collection.
919
920
920
921
If `full_response` is ``False`` (default) returns a
@@ -925,6 +926,15 @@ def map_reduce(self, map, reduce, full_response=False, **kwargs):
925
926
:Parameters:
926
927
- `map`: map function (as a JavaScript string)
927
928
- `reduce`: reduce function (as a JavaScript string)
929
+ - `out` (required): output collection name
930
+ - `merge_output` (optional): Merge output into `out`. If the same
931
+ key exists in both the result set and the existing output collection,
932
+ the new key will overwrite the existing key
933
+ - `reduce_output` (optional): If documents exist for a given key
934
+ in the result set and in the existing output collection, then a
935
+ reduce operation (using the specified reduce function) will be
936
+ performed on the two values and the result will be written to
937
+ the output collection
928
938
- `full_response` (optional): if ``True``, return full response to
929
939
this command - otherwise just return the result collection
930
940
- `**kwargs` (optional): additional arguments to the
@@ -943,11 +953,62 @@ def map_reduce(self, map, reduce, full_response=False, **kwargs):
943
953
944
954
.. mongodoc:: mapreduce
945
955
"""
956
+ if not isinstance (out , basestring ):
957
+ raise TypeError ("'out' must be an instance of basestring" )
958
+
959
+ if merge_output and reduce_output :
960
+ raise InvalidOperation ("Can't do both merge and re-reduce of output." )
961
+
962
+ if merge_output :
963
+ out_conf = {"merge" : out }
964
+ elif reduce_output :
965
+ out_conf = {"reduce" : out }
966
+ else :
967
+ out_conf = out
968
+
969
+ response = self .__database .command ("mapreduce" , self .__name ,
970
+ map = map , reduce = reduce ,
971
+ out = out_conf , ** kwargs )
972
+ if full_response :
973
+ return response
974
+ else :
975
+ return self .__database [response ["result" ]]
976
+
977
+ def inline_map_reduce (self , map , reduce , full_response = False , ** kwargs ):
978
+ """Perform an inline map/reduce operation on this collection.
979
+
980
+ Perform the map/reduce operation on the server in RAM. A result
981
+ collection is not created. The result set is returned as a list
982
+ of documents.
983
+
984
+ If `full_response` is ``False`` (default) returns the
985
+ result documents in a list. Otherwise, returns the full
986
+ response from the server to the `map reduce command`_.
987
+
988
+ :Parameters:
989
+ - `map`: map function (as a JavaScript string)
990
+ - `reduce`: reduce function (as a JavaScript string)
991
+ - `full_response` (optional): if ``True``, return full response to
992
+ this command - otherwise just return the result collection
993
+ - `**kwargs` (optional): additional arguments to the
994
+ `map reduce command`_ may be passed as keyword arguments to this
995
+ helper method, e.g.::
996
+
997
+ >>> db.test.map_reduce(map, reduce, limit=2)
998
+
999
+ .. note:: Requires server version **>= 1.7.4**
1000
+
1001
+ .. versionadded:: 1.10
1002
+ """
1003
+
946
1004
response = self .__database .command ("mapreduce" , self .__name ,
947
- map = map , reduce = reduce , ** kwargs )
1005
+ map = map , reduce = reduce ,
1006
+ out = {"inline" : 1 }, ** kwargs )
1007
+
948
1008
if full_response :
949
1009
return response
950
- return self .__database [response ["result" ]]
1010
+ else :
1011
+ return response .get ("results" )
951
1012
952
1013
def find_and_modify (self , query = {}, update = None , upsert = False , ** kwargs ):
953
1014
"""Update and return an object.
0 commit comments