@@ -77,6 +77,11 @@ def _cursor_namespace(self):
77
77
"""The namespace in which the aggregate command is run."""
78
78
raise NotImplementedError
79
79
80
+ @property
81
+ def _cursor_collection (self , cursor_doc ):
82
+ """The Collection used for the aggregate command cursor."""
83
+ raise NotImplementedError
84
+
80
85
@property
81
86
def _database (self ):
82
87
"""The database against which the aggregation command is run."""
@@ -152,18 +157,9 @@ def get_cursor(self, session, server, sock_info, slave_ok):
152
157
"ns" : self ._cursor_namespace ,
153
158
}
154
159
155
- # Get collection to target with cursor.
156
- ns = cursor ["ns" ]
157
- _ , collname = ns .split ("." , 1 )
158
- aggregation_collection = self ._database .get_collection (
159
- collname , codec_options = self ._target .codec_options ,
160
- read_preference = read_preference ,
161
- write_concern = self ._target .write_concern ,
162
- read_concern = self ._target .read_concern )
163
-
164
160
# Create and return cursor instance.
165
161
return self ._cursor_class (
166
- aggregation_collection , cursor , sock_info .address ,
162
+ self . _cursor_collection ( cursor ) , cursor , sock_info .address ,
167
163
batch_size = self ._batch_size or 0 ,
168
164
max_await_time_ms = self ._max_await_time_ms ,
169
165
session = session , explicit_session = self ._explicit_session )
@@ -188,6 +184,10 @@ def _aggregation_target(self):
188
184
def _cursor_namespace (self ):
189
185
return self ._target .full_name
190
186
187
+ def _cursor_collection (self , cursor ):
188
+ """The Collection used for the aggregate command cursor."""
189
+ return self ._target
190
+
191
191
@property
192
192
def _database (self ):
193
193
return self ._target .database
@@ -209,16 +209,24 @@ def _aggregation_target(self):
209
209
210
210
@property
211
211
def _cursor_namespace (self ):
212
- return "%s.%s .aggregate" % (self ._target .name , "$cmd" )
212
+ return "%s.$cmd .aggregate" % (self ._target .name ,)
213
213
214
214
@property
215
215
def _database (self ):
216
216
return self ._target
217
217
218
+ def _cursor_collection (self , cursor ):
219
+ """The Collection used for the aggregate command cursor."""
220
+ # Collection level aggregate may not always return the "ns" field
221
+ # according to our MockupDB tests. Let's handle that case for db level
222
+ # aggregate too by defaulting to the <db>.$cmd.aggregate namespace.
223
+ _ , collname = cursor .get ("ns" , self ._cursor_namespace ).split ("." , 1 )
224
+ return self ._database [collname ]
225
+
218
226
@staticmethod
219
227
def _check_compat (sock_info ):
220
228
# Older server version don't raise a descriptive error, so we raise
221
229
# one instead.
222
230
if not sock_info .max_wire_version >= 6 :
223
- err_msg = "Database.aggregation is only supported on MongoDB 3.6+."
231
+ err_msg = "Database.aggregate() is only supported on MongoDB 3.6+."
224
232
raise ConfigurationError (err_msg )
0 commit comments