Motor Async MongoDB Aggregation Pipeline
Run aggregation pipelines with the async Motor driver, streaming large result sets via async iteration and cursor batching.
Code
import asyncio
from motor.motor_asyncio import AsyncIOMotorClient
client = AsyncIOMotorClient('mongodb://localhost:27017')
orders = client['shop']['orders']
PIPELINE = [
{'$match': {'status': 'paid'}},
{'$unwind': '$items'},
{'$group': {
'_id': '$items.sku',
'units': {'$sum': '$items.qty'},
'revenue': {'$sum': {'$multiply': ['$items.qty', '$items.price']}},
}},
{'$sort': {'revenue': -1}},
{'$limit': 20},
]
async def top_products() -> list[dict]:
cursor = orders.aggregate(
PIPELINE,
batchSize=200,
allowDiskUse=True,
)
results: list[dict] = []
async for doc in cursor:
results.append({
'sku': doc['_id'],
'units': doc['units'],
'revenue': round(doc['revenue'], 2),
})
return results
async def seed() -> None:
await orders.delete_many({})
await orders.insert_many([
{'status': 'paid', 'items': [
{'sku': 'A-1', 'qty': 2, 'price': 10.0},
{'sku': 'B-2', 'qty': 1, 'price': 30.0},
]},
{'status': 'paid', 'items': [
{'sku': 'A-1', 'qty': 5, 'price': 10.0},
]},
{'status': 'refunded', 'items': [
{'sku': 'C-3', 'qty': 1, 'price': 99.0},
]},
])
async def main() -> None:
await seed()
for row in await top_products():
print(row)
client.close()
asyncio.run(main())Report a problem with this exampleOpens a pre-filled issue on GitHub.