Perform an aggregate function based on your queryset params :param pipeline: list of aggregation commands, see: https://www.mongodb.com/docs/manual/core/aggregation-pipeline/ :param suppl_pipeline: unpacked list of pipeline (added to support deprecation of the old interf
(self, pipeline, *suppl_pipeline, **kwargs)
| 1334 | return [self._document._from_son(data) for data in son_data] |
| 1335 | |
| 1336 | def aggregate(self, pipeline, *suppl_pipeline, **kwargs): |
| 1337 | """Perform an aggregate function based on your queryset params |
| 1338 | |
| 1339 | :param pipeline: list of aggregation commands, |
| 1340 | see: https://www.mongodb.com/docs/manual/core/aggregation-pipeline/ |
| 1341 | :param suppl_pipeline: unpacked list of pipeline (added to support deprecation of the old interface) |
| 1342 | parameter will be removed shortly |
| 1343 | :param kwargs: (optional) kwargs dictionary to be passed to pymongo's aggregate call |
| 1344 | See https://pymongo.readthedocs.io/en/stable/api/pymongo/collection.html#pymongo.collection.Collection.aggregate |
| 1345 | """ |
| 1346 | using_deprecated_interface = isinstance(pipeline, dict) or bool(suppl_pipeline) |
| 1347 | user_pipeline = [pipeline] if isinstance(pipeline, dict) else list(pipeline) |
| 1348 | |
| 1349 | if using_deprecated_interface: |
| 1350 | msg = "Calling .aggregate() with un unpacked list (*pipeline) is deprecated, it will soon change and will expect a list (similar to pymongo.Collection.aggregate interface), see documentation" |
| 1351 | warnings.warn(msg, DeprecationWarning) |
| 1352 | |
| 1353 | user_pipeline += suppl_pipeline |
| 1354 | |
| 1355 | initial_pipeline = [] |
| 1356 | if self._none or self._empty: |
| 1357 | initial_pipeline.append({"$limit": 1}) |
| 1358 | initial_pipeline.append({"$match": {"$expr": False}}) |
| 1359 | |
| 1360 | if self._query: |
| 1361 | initial_pipeline.append({"$match": self._query}) |
| 1362 | |
| 1363 | if self._ordering: |
| 1364 | initial_pipeline.append({"$sort": dict(self._ordering)}) |
| 1365 | |
| 1366 | if self._limit is not None: |
| 1367 | # As per MongoDB Documentation (https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit/), |
| 1368 | # keeping limit stage right after sort stage is more efficient. But this leads to wrong set of documents |
| 1369 | # for a skip stage that might succeed these. So we need to maintain more documents in memory in such a |
| 1370 | # case (https://stackoverflow.com/a/24161461). |
| 1371 | initial_pipeline.append({"$limit": self._limit + (self._skip or 0)}) |
| 1372 | |
| 1373 | if self._skip is not None: |
| 1374 | initial_pipeline.append({"$skip": self._skip}) |
| 1375 | |
| 1376 | final_pipeline = initial_pipeline + user_pipeline |
| 1377 | |
| 1378 | collection = self._collection |
| 1379 | if self._read_preference is not None or self._read_concern is not None: |
| 1380 | collection = self._collection.with_options( |
| 1381 | read_preference=self._read_preference, read_concern=self._read_concern |
| 1382 | ) |
| 1383 | |
| 1384 | return collection.aggregate(final_pipeline, cursor={}, **kwargs) |
| 1385 | |
| 1386 | # JS functionality |
| 1387 | def map_reduce( |
no outgoing calls