@@ -222,7 +222,7 @@ class _Query(object):
222
222
__slots__ = ('flags' , 'db' , 'coll' , 'ntoskip' , 'spec' ,
223
223
'fields' , 'codec_options' , 'read_preference' , 'limit' ,
224
224
'batch_size' , 'name' , 'read_concern' , 'collation' ,
225
- 'session' , 'client' )
225
+ 'session' , 'client' , '__as_command' )
226
226
227
227
def __init__ (self , flags , db , coll , ntoskip , spec , fields ,
228
228
codec_options , read_preference , limit ,
@@ -242,6 +242,7 @@ def __init__(self, flags, db, coll, ntoskip, spec, fields,
242
242
self .session = session
243
243
self .client = client
244
244
self .name = 'find'
245
+ self .__as_command = None
245
246
246
247
def use_command (self , sock_info , exhaust ):
247
248
use_find_cmd = False
@@ -265,10 +266,13 @@ def use_command(self, sock_info, exhaust):
265
266
return use_find_cmd
266
267
267
268
def as_command (self , sock_info ):
268
- """Return a find command document for this query.
269
+ """Return a find command document for this query."""
270
+ # We use the command twice: on the wire and for command monitoring.
271
+ # Generate it once, for speed and to avoid repeating side-effects
272
+ # like incrementing the session's statement id.
273
+ if self .__as_command is not None :
274
+ return self .__as_command
269
275
270
- Should be called *after* get_message.
271
- """
272
276
explain = '$explain' in self .spec
273
277
cmd = _gen_find_command (
274
278
self .coll , self .spec , self .fields , self .ntoskip ,
@@ -288,7 +292,8 @@ def as_command(self, sock_info):
288
292
'readConcern' , {})[
289
293
'afterClusterTime' ] = session .operation_time
290
294
sock_info .send_cluster_time (cmd , session , self .client )
291
- return cmd , self .db
295
+ self .__as_command = cmd , self .db
296
+ return self .__as_command
292
297
293
298
def get_message (self , set_slave_ok , sock_info , use_cmd = False ):
294
299
"""Get a query message, possibly setting the slaveOk bit."""
@@ -328,7 +333,7 @@ class _GetMore(object):
328
333
"""A getmore operation."""
329
334
330
335
__slots__ = ('db' , 'coll' , 'ntoreturn' , 'cursor_id' , 'max_await_time_ms' ,
331
- 'codec_options' , 'session' , 'client' )
336
+ 'codec_options' , 'session' , 'client' , '__as_command' )
332
337
333
338
name = 'getMore'
334
339
@@ -342,21 +347,27 @@ def __init__(self, db, coll, ntoreturn, cursor_id, codec_options, session,
342
347
self .session = session
343
348
self .client = client
344
349
self .max_await_time_ms = max_await_time_ms
350
+ self .__as_command = None
345
351
346
352
def use_command (self , sock_info , exhaust ):
347
353
sock_info .validate_session (self .client , self .session )
348
354
return sock_info .max_wire_version >= 4 and not exhaust
349
355
350
356
def as_command (self , sock_info ):
351
357
"""Return a getMore command document for this query."""
358
+ # See _Query.as_command for an explanation of this caching.
359
+ if self .__as_command is not None :
360
+ return self .__as_command
361
+
352
362
cmd = _gen_get_more_command (self .cursor_id , self .coll ,
353
363
self .ntoreturn ,
354
364
self .max_await_time_ms )
355
365
356
366
if self .session :
357
367
self .session ._apply_to (cmd , False )
358
368
sock_info .send_cluster_time (cmd , self .session , self .client )
359
- return cmd , self .db
369
+ self .__as_command = cmd , self .db
370
+ return self .__as_command
360
371
361
372
def get_message (self , dummy0 , sock_info , use_cmd = False ):
362
373
"""Get a getmore message."""
0 commit comments