@@ -75,7 +75,6 @@ def _maybe_add_read_preference(spec, read_preference):
7575 return spec
7676
7777
78- # XXX: What to do about exhaust?
7978_OPTIONS = SON ([
8079 ('tailable' , 2 ),
8180 ('oplogReplay' , 8 ),
@@ -84,7 +83,6 @@ def _maybe_add_read_preference(spec, read_preference):
8483 ('allowPartialResults' , 128 )])
8584
8685
87- # XXX: What about $explain? Time to switch to explain command?
8886_MODIFIERS = SON ([
8987 ('$query' , 'filter' ),
9088 ('$orderby' , 'sort' ),
@@ -101,11 +99,20 @@ def _maybe_add_read_preference(spec, read_preference):
10199 ('$snapshot' , 'snapshot' )])
102100
103101
102+ def _gen_explain_command (
103+ coll , spec , projection , skip , limit , batch_size , options ):
104+ """Generate an explain command document."""
105+ cmd = _gen_find_command (
106+ coll , spec , projection , skip , limit , batch_size , options )
107+ return SON ([('explain' , cmd )])
108+
109+
104110def _gen_find_command (coll , spec , projection , skip , limit , batch_size , options ):
105111 """Generate a find command document."""
106112 cmd = SON ([('find' , coll )])
107113 if '$query' in spec :
108- cmd .update ([(_MODIFIERS [key ], val ) for key , val in spec .items ()])
114+ cmd .update ([(_MODIFIERS [key ], val )
115+ for key , val in spec .items () if key in _MODIFIERS ])
109116 else :
110117 cmd ['filter' ] = spec
111118
@@ -143,9 +150,8 @@ class _Query(object):
143150 """A query operation."""
144151
145152 __slots__ = ('flags' , 'ns' , 'ntoskip' , 'ntoreturn' , 'spec' , 'fields' ,
146- 'codec_options' , 'read_preference' , 'limit' , 'batch_size' )
147-
148- name = 'find'
153+ 'codec_options' , 'read_preference' , 'limit' , 'batch_size' ,
154+ 'name' )
149155
150156 def __init__ (self , flags , ns , ntoskip , ntoreturn , spec , fields ,
151157 codec_options , read_preference , limit , batch_size ):
@@ -159,13 +165,19 @@ def __init__(self, flags, ns, ntoskip, ntoreturn, spec, fields,
159165 self .read_preference = read_preference
160166 self .limit = limit
161167 self .batch_size = batch_size
168+ self .name = 'find'
162169
163170 def as_command (self ):
164171 """Return a find command document for this query.
165172
166173 Should be called *after* get_message.
167174 """
168175 dbn , coll = self .ns .split ('.' , 1 )
176+ if '$explain' in self .spec :
177+ self .name = 'explain'
178+ return _gen_explain_command (
179+ coll , self .spec , self .fields , self .ntoskip ,
180+ self .limit , self .batch_size , self .flags ), dbn
169181 return _gen_find_command (coll , self .spec , self .fields , self .ntoskip ,
170182 self .limit , self .batch_size , self .flags ), dbn
171183
0 commit comments