解锁FastAPI与MongoDB聚合管道的性能奥秘
title: 解锁FastAPI与MongoDB聚合管道的性能奥秘


[
{"$match": {"status": "completed"}},
{"$group": {"_id": "$category", "total": {"$sum": "$amount"}}},
{"$sort": {"total": -1}}
]
| 阶段 | 作用 | 使用场景示例 |
|---|---|---|
| $match | 文档筛选 | 过滤特定时间段订单 |
| $group | 文档分组 | 统计各分类商品销售额 |
| $project | 字段投影 | 隐藏敏感字段,重命名字段 |
| $sort | 结果排序 | 按销售额降序排列 |
| $limit | 结果限制 | 获取TOP10销售数据 |
| $unwind | 展开数组字段 | 分析订单中的商品列表 |
from pydantic import BaseModel
from datetime import datetime
class Order(BaseModel):
order_id: str
user_id: int
items: list
status: str
amount: float
created_at: datetime
from fastapi import APIRouter
from motor.motor_asyncio import AsyncIOMotorClient
router = APIRouter()
@router.get("/orders/stats")
async def get_order_stats():
pipeline = [
{"$match": {"status": "completed"}},
{"$group": {
"_id": {"year": {"$year": "$created_at"}, "month": {"$month": "$created_at"}},
"total_orders": {"$sum": 1},
"total_amount": {"$sum": "$amount"}
}},
{"$sort": {"_id.year": 1, "_id.month": 1}}
]
async with AsyncIOMotorClient("mongodb://localhost:27017") as client:
cursor = client.mydb.orders.aggregate(pipeline)
return await cursor.to_list(length=1000)
# 在FastAPI启动时创建索引
@app.on_event("startup")
async def create_indexes():
db = AsyncIOMotorClient().mydb
await db.orders.create_index([("status", 1), ("created_at", -1)])
await db.orders.create_index([("user_id", 1), ("amount", -1)])
pipeline = [
{"$match": {"status": "completed"}},
{"$facet": {
"metadata": [{"$count": "total"}],
"data": [
{"$skip": 100},
{"$limit": 20},
{"$project": {"_id": 0, "order_id": 1, "amount": 1}}
]
}}
]
await db.orders.aggregate(pipeline, allowDiskUse=True).to_list(None)
cursor = db.orders.aggregate(pipeline, batchSize=1000)
async for doc in cursor:
process(doc)
[
{"$project": {"category": 1}},
{"$match": {"category": {"$in": ["electronics", "books"]}}},
{"$group": {"_id": "$category", "count": {"$sum": 1}}}
]
{"$match": {"status": "shipped", "created_at": {"$gte": "2023-01-01"}}}
{"$sort": {"amount": -1}}
pip install fastapi==0.68.0 motor==3.3.2 pydantic==1.10.7 python-multipart==0.0.5
uvicorn main:app --reload --port 8000
curl http://localhost:8000/orders/stats
{"$match": {
"$expr": {
"$and": [
{"$gt": ["$amount", 100]},
{"$lt": ["$amount", 500]}
]
}
}}
{"$group": {
"_id": {
"year": {"$year": "$created_at"},
"week": {"$week": "$created_at"}
},
"count": {"$sum": 1}
}}
{"$project": {
"discount_flag": {
"$cond": {"if": {"$gt": ["$amount", 200]}, "then": "A", "else": "B"}
}
}}
评论
发表评论