Motor 异步 MongoDB 驱动使用指南

Motor 异步 MongoDB 驱动使用指南

【免费下载链接】motor Motor - the async Python driver for MongoDB and Tornado or asyncio 【免费下载链接】motor 项目地址: https://gitcode.com/gh_mirrors/mo/motor

前言

Motor 是 MongoDB 官方推出的异步 Python 驱动,专为 asyncio 生态设计。本文将详细介绍如何使用 Motor 进行 MongoDB 异步操作,帮助开发者快速掌握这一强大工具。

环境准备

系统要求

  • Python 3.5 或更高版本
  • 运行中的 MongoDB 实例(默认端口 27017)

安装步骤

python3 -m pip install motor

启动 MongoDB 服务:

mongod

核心概念

对象层次结构

Motor 采用与 PyMongo 相同的四层对象模型:

  1. AsyncIOMotorClient:代表 MongoDB 服务器或集群
  2. AsyncIOMotorDatabase:单个 MongoDB 实例中的数据库
  3. AsyncIOMotorCollection:数据库中的集合(类似关系型数据库的表)
  4. AsyncIOMotorCursor:查询结果集的游标

基础操作

创建客户端连接

import motor.motor_asyncio

# 默认连接
client = motor.motor_asyncio.AsyncIOMotorClient()

# 指定主机和端口
client = motor.motor_asyncio.AsyncIOMotorClient("localhost", 27017)

# 使用连接字符串
client = motor.motor_asyncio.AsyncIOMotorClient("mongodb://localhost:27017")

# 连接副本集
client = motor.motor_asyncio.AsyncIOMotorClient(
    'mongodb://host1,host2/?replicaSet=my-replicaset-name'
)

数据库与集合操作

获取数据库和集合引用不会触发 I/O 操作:

db = client.test_database  # 或 client["test_database"]
collection = db.test_collection  # 或 db["test_collection"]

CRUD 操作

文档插入

单文档插入:

async def insert_doc():
    document = {"key": "value"}
    result = await collection.insert_one(document)
    print(f"插入文档ID: {result.inserted_id}")

批量插入:

async def bulk_insert():
    docs = [{"i": i} for i in range(2000)]
    result = await collection.insert_many(docs)
    print(f"已插入 {len(result.inserted_ids)} 个文档")

文档查询

单文档查询:

async def find_one_doc():
    doc = await collection.find_one({"i": {"$lt": 1}})
    print(doc)

多文档查询(使用游标):

async def find_many():
    cursor = collection.find({"i": {"$lt": 5}}).sort("i")
    async for doc in cursor:
        print(doc)

文档更新

替换整个文档:

async def replace_doc():
    result = await collection.replace_one(
        {"i": 50}, 
        {"new_key": "new_value"}
    )

部分更新:

async def update_doc():
    await collection.update_one(
        {"i": 51},
        {"$set": {"key": "value"}}
    )

文档删除

删除单个文档:

async def delete_one():
    await collection.delete_one({"i": {"$gte": 1000}})

批量删除:

async def delete_many():
    await collection.delete_many({"i": {"$gte": 1000}})

高级特性

命令执行

直接执行 MongoDB 命令:

from bson import SON

async def run_command():
    response = await db.command(SON([
        ("distinct", "test_collection"),
        ("key", "i")
    ]))

聚合操作

async def aggregate():
    pipeline = [{"$group": {"_id": "$status", "count": {"$sum": 1}}}]
    cursor = collection.aggregate(pipeline)
    async for doc in cursor:
        print(doc)

性能优化建议

  1. 客户端管理:避免为每个请求创建新客户端,应复用同一个客户端实例
  2. 批量操作:优先使用 insert_many 而非循环调用 insert_one
  3. 游标控制:合理设置 batch_sizelimit 参数
  4. 索引优化:为常用查询字段创建适当索引

实际应用示例

基于 aiohttp 的 Web 应用

from aiohttp import web
import motor.motor_asyncio

async def setup_db():
    client = motor.motor_asyncio.AsyncIOMotorClient()
    db = client.test_database
    await db.pages.drop()
    await db.pages.insert_many([
        {"_id": "page-one", "body": "<html><body>Hello!</body></html>"},
        {"_id": "page-two", "body": "<html><body>Goodbye.</body></html>"}
    ])
    return db

async def page_handler(request):
    db = request.app["db"]
    page_name = request.match_info["page_name"]
    document = await db.pages.find_one({"_id": page_name})
    if document:
        return web.Response(text=document["body"], content_type="text/html")
    return web.Response(text="Not found", status=404)

async def init_app():
    app = web.Application()
    app["db"] = await setup_db()
    app.router.add_get("/pages/{page_name}", page_handler)
    return app

web.run_app(init_app())

迁移说明

Motor 将在 2026 年 5 月 14 日停止维护,建议用户迁移至 PyMongo 的异步驱动版本。在过渡期内,Motor 仍会提供关键 bug 修复。

学习资源

  • MongoDB 官方文档
  • Python asyncio 文档
  • Motor API 参考文档

通过本文介绍,您应该已经掌握了使用 Motor 进行 MongoDB 异步操作的核心知识。Motor 的强大功能与 asyncio 生态的完美结合,将为您的应用带来显著的性能提升。

【免费下载链接】motor Motor - the async Python driver for MongoDB and Tornado or asyncio 【免费下载链接】motor 项目地址: https://gitcode.com/gh_mirrors/mo/motor

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值