【python 第三方库】pymongo

2024-01-25 00:00:00

目录:

安装 PyMongo

# 安装第三方模块
$ pip install pymongo       
# 安装特定版本
pip install pymongo==3.5.1
# 升级到最新版本
pip install --upgrade pymongo

连接 MongoDB

使用 pymongo.MongoClient 类来创建与 MongoDB 实例的连接。

连接本地数据库

from pymongo import MongoClient

# 默认连接 localhost:27017
client = MongoClient()  

# 或显式指定
client = MongoClient('localhost', 27017)
client = MongoClient('mongodb://localhost:27017/')  # 使用连接字符串

连接远程数据库

from pymongo import MongoClient

# 带用户名密码认证的连接
# 格式: client = MongoClient('mongodb://用户名:密码@服务器IP:端口/数据库名')
client = MongoClient('mongodb://admin:123456@192.168.1.100:27017/admin')

选择数据库与集合

# 选择数据库(若不存在,会在第一次插入数据时自动创建)
db = client['my_database']   # 方式1: 类字典访问
db = client.my_database      # 方式2: 属性访问

# 选择集合(同样,首次插入数据时自动创建)
collection = db['my_collection']    # 方式1: 类字典访问
collection = db.my_collection       # 方式2: 属性访问

插入文档

使用 insert_one() 插入单条文档,或 insert_many() 插入多条文档。

# 插入单条数据
student = {'id': 1, 'name': '张三', 'age': 18, 'address': '北京'}
result = collection.insert_one(student)
print(f"插入文档的ID: {result.inserted_id}")

# 插入多条数据
students = [
    {'id': 2, 'name': '李四', 'age': 22},
    {'id': 3, 'name': '王五', 'age': 19}
]
result = collection.insert_many(students)
print(f"插入文档的ID列表: {result.inserted_ids}")

MongoDB 会自动为每个插入的文档生成一个全局唯一的 _id 字段(ObjectId)。

查询文档

find_one() 返回匹配的第一个文档,find() 返回一个游标(Cursor)对象,用于遍历所有匹配的文档。

# 查询单条记录
doc = collection.find_one({'name': '张三'})
print(doc)

# 查询所有记录
for doc in collection.find():
    print(doc)

# 带条件查询(例如:年龄大于18岁)
for doc in collection.find({'age': {'$gt': 18}}):
    print(doc)

# 使用比较操作符:$lt(小于), $gte(大于等于), $ne(不等于), $in(在范围内)等[1](@ref)
for doc in collection.find({'age': {'$in': [18, 22]}}):
    print(doc)

# 使用正则表达式查询
for doc in collection.find({'name': {'$regex': '^张.*'}}):  # 查找姓“张”的
    print(doc)

更新文档

使用 update_one() 或 update_many() 方法,并配合 $set 操作符来安全地更新指定字段,避免误删其他字段。

# 更新单条记录(将名为“张三”的年龄改为20)
result = collection.update_one({'name': '张三'}, {'$set': {'age': 20}})
print(f"匹配到 {result.matched_count} 条,修改了 {result.modified_count} 条")

# 更新多条记录(将所有年龄小于20的文档,状态设为‘未成年’)
result = collection.update_many({'age': {'$lt': 20}}, {'$set': {'status': '未成年'}})
print(f"匹配到 {result.matched_count} 条,修改了 {result.modified_count} 条")

# 使用 $inc 操作符进行原子性增减操作
result = collection.update_many({}, {'$inc': {'age': 1}})  # 所有人年龄加1

删除文档

使用 delete_one() 或 delete_many() 方法进行删除操作。

# 删除单条记录(删除名为“李四”的第一条记录)
result = collection.delete_one({'name': '李四'})
print(f"删除了 {result.deleted_count} 条记录")

# 删除多条记录(删除所有年龄大于30的记录)
result = collection.delete_many({'age': {'$gt': 30}})
print(f"删除了 {result.deleted_count} 条记录")

计数

使用 count_documents() 方法统计符合条件的文档数量。

total = collection.count_documents({})  # 集合中文档总数
adults = collection.count_documents({'age': {'$gte': 18}})  # 成年人数量

排序

使用 sort() 方法,结合 pymongo.ASCENDING(升序)或 pymongo.DESCENDING(降序)。

# 按年龄升序排列
for doc in collection.find().sort('age', pymongo.ASCENDING):
    print(doc)

# 多字段排序:先按年龄降序,再按姓名升序
for doc in collection.find().sort([('age', pymongo.DESCENDING), ('name', pymongo.ASCENDING)]):
    print(doc)

分页

使用 skip() 和 limit() 实现分页查询。

# 实现分页:跳过前 10 条,取接下来的 5 条
for doc in collection.find().skip(10).limit(5):
    print(doc)

索引创建

# 创建单字段索引(升序)
collection.create_index("name")

# 或指定排序方向
collection.create_index([("name", pymongo.ASCENDING)])  # 升序
collection.create_index([("age", pymongo.DESCENDING)])  # 降序

# 创建唯一索引
collection.create_index("email", unique=True)

# 创建复合索引:先按name升序,再按age降序
collection.create_index([("name", pymongo.ASCENDING), ("age", pymongo.DESCENDING)])

聚合操作

def basic_aggregation():
    client = pymongo.MongoClient("mongodb://localhost:27017/")
    db = client['sales']
    orders = db['orders']
    
    # 示例数据
    orders.insert_many([
        {"product": "Laptop", "category": "Electronics", "price": 1200, "quantity": 2},
        {"product": "Mouse", "category": "Electronics", "price": 50, "quantity": 10},
        {"product": "Book", "category": "Education", "price": 30, "quantity": 5},
        {"product": "Laptop", "category": "Electronics", "price": 1200, "quantity": 1},
        {"product": "Notebook", "category": "Education", "price": 15, "quantity": 20}
    ])
    
    # 按类别分组,计算总销售额和平均价格
    pipeline = [
        {
            "$group": {
                "_id": "$category",
                "total_sales": {"$sum": {"$multiply": ["$price", "$quantity"]}},
                "avg_price": {"$avg": "$price"},
                "total_items": {"$sum": "$quantity"},
                "order_count": {"$sum": 1}
            }
        },
        {
            "$sort": {"total_sales": -1}  # 按总销售额降序排序
        }
    ]
    
    results = orders.aggregate(pipeline)
    print("按类别统计:")
    for doc in results:
        print(f"类别: {doc['_id']}")
        print(f"  总销售额: ${doc['total_sales']}")
        print(f"  平均价格: ${doc['avg_price']:.2f}")
        print(f"  总数量: {doc['total_items']}")
        print(f"  订单数: {doc['order_count']}")
        print("-" * 40)
    
    client.close()

返回首页

本文总阅读量  次
皖ICP备17026209号-3
总访问量: 
总访客量: