5353
5454_NO_OBJ_ERROR = "No matching object found"
5555_UJOIN = u"%s.%s"
56+ _FIND_AND_MODIFY_DOC_FIELDS = {'value' : dict }
5657
5758
5859class ReturnDocument (object ):
@@ -203,7 +204,8 @@ def _command(self, sock_info, command, slave_ok=False,
203204 write_concern = None ,
204205 collation = None ,
205206 session = None ,
206- retryable_write = False ):
207+ retryable_write = False ,
208+ user_fields = None ):
207209 """Internal command helper.
208210
209211 :Parameters:
@@ -242,7 +244,8 @@ def _command(self, sock_info, command, slave_ok=False,
242244 collation = collation ,
243245 session = s ,
244246 client = self .__database .client ,
245- retryable_write = retryable_write )
247+ retryable_write = retryable_write ,
248+ user_fields = user_fields )
246249
247250 def __create (self , options , collation , session ):
248251 """Sends a create command with the given options.
@@ -315,9 +318,8 @@ def database(self):
315318 """
316319 return self .__database
317320
318- def with_options (
319- self , codec_options = None , read_preference = None ,
320- write_concern = None , read_concern = None ):
321+ def with_options (self , codec_options = None , read_preference = None ,
322+ write_concern = None , read_concern = None ):
321323 """Get a clone of this collection changing the specified settings.
322324
323325 >>> coll1.read_preference
@@ -2310,7 +2312,8 @@ def _aggregate(self, pipeline, cursor_class, first_batch_size, session,
23102312 write_concern = write_concern ,
23112313 collation = collation ,
23122314 session = session ,
2313- client = self .__database .client )
2315+ client = self .__database .client ,
2316+ user_fields = {'cursor' : {'firstBatch' : list }})
23142317
23152318 if "cursor" in result :
23162319 cursor = result ["cursor" ]
@@ -2571,7 +2574,8 @@ def group(self, key, condition, initial, reduce, finalize=None, **kwargs):
25712574
25722575 with self ._socket_for_reads (session = None ) as (sock_info , slave_ok ):
25732576 return self ._command (sock_info , cmd , slave_ok ,
2574- collation = collation )["retval" ]
2577+ collation = collation ,
2578+ user_fields = {'retval' : list })["retval" ]
25752579
25762580 def rename (self , new_name , session = None , ** kwargs ):
25772581 """Rename this collection.
@@ -2675,7 +2679,8 @@ def distinct(self, key, filter=None, session=None, **kwargs):
26752679 with self ._socket_for_reads (session ) as (sock_info , slave_ok ):
26762680 return self ._command (sock_info , cmd , slave_ok ,
26772681 read_concern = self .read_concern ,
2678- collation = collation , session = session )["values" ]
2682+ collation = collation ,
2683+ session = session )["values" ]
26792684
26802685 def map_reduce (self , map , reduce , out , full_response = False , session = None ,
26812686 ** kwargs ):
@@ -2755,12 +2760,17 @@ def map_reduce(self, map, reduce, out, full_response=False, session=None,
27552760 write_concern = self ._write_concern_for (session )
27562761 else :
27572762 write_concern = None
2763+ if inline :
2764+ user_fields = {'results' : list }
2765+ else :
2766+ user_fields = None
27582767
27592768 response = self ._command (
27602769 sock_info , cmd , slave_ok , read_pref ,
27612770 read_concern = read_concern ,
27622771 write_concern = write_concern ,
2763- collation = collation , session = session )
2772+ collation = collation , session = session ,
2773+ user_fields = user_fields )
27642774
27652775 if full_response or not response .get ('result' ):
27662776 return response
@@ -2810,16 +2820,19 @@ def inline_map_reduce(self, map, reduce, full_response=False, session=None,
28102820 ("map" , map ),
28112821 ("reduce" , reduce ),
28122822 ("out" , {"inline" : 1 })])
2823+ user_fields = {'results' : list }
28132824 collation = validate_collation_or_none (kwargs .pop ('collation' , None ))
28142825 cmd .update (kwargs )
28152826 with self ._socket_for_reads (session ) as (sock_info , slave_ok ):
28162827 if sock_info .max_wire_version >= 4 and 'readConcern' not in cmd :
28172828 res = self ._command (sock_info , cmd , slave_ok ,
28182829 read_concern = self .read_concern ,
2819- collation = collation , session = session )
2830+ collation = collation , session = session ,
2831+ user_fields = user_fields )
28202832 else :
28212833 res = self ._command (sock_info , cmd , slave_ok ,
2822- collation = collation , session = session )
2834+ collation = collation , session = session ,
2835+ user_fields = user_fields )
28232836
28242837 if full_response :
28252838 return res
@@ -2837,6 +2850,7 @@ def __find_and_modify(self, filter, projection, sort, upsert=None,
28372850 return_document = ReturnDocument .BEFORE ,
28382851 array_filters = None , session = None , ** kwargs ):
28392852 """Internal findAndModify helper."""
2853+
28402854 common .validate_is_mapping ("filter" , filter )
28412855 if not isinstance (return_document , bool ):
28422856 raise ValueError ("return_document must be "
@@ -2876,8 +2890,10 @@ def _find_and_modify(session, sock_info, retryable_write):
28762890 write_concern = write_concern ,
28772891 allowable_errors = [_NO_OBJ_ERROR ],
28782892 collation = collation , session = session ,
2879- retryable_write = retryable_write )
2893+ retryable_write = retryable_write ,
2894+ user_fields = _FIND_AND_MODIFY_DOC_FIELDS )
28802895 _check_write_command_response (out )
2896+
28812897 return out .get ("value" )
28822898
28832899 return self .__database .client ._retryable_write (
@@ -3293,7 +3309,8 @@ def _find_and_modify(session, sock_info, retryable_write):
32933309 result = self ._command (
32943310 sock_info , cmd , read_preference = ReadPreference .PRIMARY ,
32953311 allowable_errors = [_NO_OBJ_ERROR ], collation = collation ,
3296- session = session , retryable_write = retryable_write )
3312+ session = session , retryable_write = retryable_write ,
3313+ user_fields = _FIND_AND_MODIFY_DOC_FIELDS )
32973314
32983315 _check_write_command_response (result )
32993316 return result
0 commit comments