@@ -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