CodeWalk

MongoDB与Motor:同步/异步ODM与聚合管道

作者:我是大山 · 2026-05-30 12:55

请介绍Python操作MongoDB的同步驱动(pymongo)和异步驱动(motor)的用法。说明连接配置、文档CRUD、索引创建和聚合管道的使用。如何用pymongo实现GridFS大文件存储?对比PyMongo的find()游标和聚合管道(aggregate())的适用场景。

回答

我是大山

PyMongo(同步)

from pymongo import MongoClient, ASCENDING

client = MongoClient('mongodb://localhost:27017', maxPoolSize=50)
db = client['mydb']
col = db['users']

# 创建索引
col.create_index([('email', ASCENDING)], unique=True)

# CRUD
col.insert_one({'name': 'Alice', 'age': 30})
user = col.find_one({'email': 'alice@example.com'})
col.update_one({'name': 'Alice'}, {'$set': {'age': 31}})
col.delete_one({'name': 'Alice'})

# 聚合管道
pipeline = [
    {'$match': {'age': {'$gte': 18}}},
    {'$group': {'_id': '$city', 'count': {'$sum': 1}, 'avg_age': {'$avg': '$age'}}},
    {'$sort': {'count': -1}},
    {'$limit': 5}
]
results = col.aggregate(pipeline)

Motor(异步)

from motor.motor_asyncio import AsyncIOMotorClient

client = AsyncIOMotorClient('mongodb://localhost:27017')
col = client['mydb']['users']

async def get_user(email):
    return await col.find_one({'email': email})

GridFS(大文件)

from pymongo import MongoClient
import gridfs

db = MongoClient()['files_db']
fs = gridfs.GridFS(db)
with open('large_video.mp4', 'rb') as f:
    file_id = fs.put(f, filename='video.mp4')

with open('output.mp4', 'wb') as f:
    f.write(fs.get(file_id).read())

find vs aggregate

  • find():简单过滤、投影、基本排序
  • aggregate():多阶段管道($group/$lookup/$unwind/$bucket等),适合复杂报表
  • 性能:find() + 索引更快;aggregate()灵活但计算密集