我来提供一个完整的Python连接本地MongoDB的示例代码,包含基本的CRUD操作。
1. 首先安装必要的库
pip install pymongo
2. 完整示例代码
import pymongo
from pymongo import MongoClient
from datetime import datetime
from bson import ObjectId
import json
from typing import List, Dict, Any
class MongoDBManager:
"""MongoDB管理类"""
def __init__(self, host='localhost', port=27017, username=None, password=None, database_name='mydatabase'):
"""
初始化MongoDB连接
Args:
host: MongoDB主机地址,默认为localhost
port: MongoDB端口,默认为27017
username: 用户名(如果有认证)
password: 密码(如果有认证)
database_name: 数据库名称
"""
try:
# 构建连接字符串
if username and password:
# 有认证的连接
connection_string = f"mongodb://{username}:{password}@{host}:{port}/"
self.client = MongoClient(connection_string)
else:
# 无认证的连接(本地开发常用)
self.client = MongoClient(host, port)
# 测试连接
self.client.admin.command('ping')
print("✅ MongoDB连接成功!")
# 选择数据库
self.db = self.client[database_name]
print(f"📁 已选择数据库: {database_name}")
except Exception as e:
print(f"❌ MongoDB连接失败: {e}")
raise
def list_databases(self):
"""列出所有数据库"""
databases = self.client.list_database_names()
print("📚 所有数据库:")
for db in databases:
print(f" - {db}")
return databases
def list_collections(self):
"""列出当前数据库的所有集合"""
collections = self.db.list_collection_names()
print(f"📋 数据库 '{self.db.name}' 中的集合:")
for col in collections:
print(f" - {col}")
return collections
def insert_one(self, collection_name: str, document: Dict[str, Any]):
"""
插入单个文档
Args:
collection_name: 集合名称
document: 要插入的文档
Returns:
插入的文档ID
"""
try:
collection = self.db[collection_name]
result = collection.insert_one(document)
print(f"✅ 文档插入成功,ID: {result.inserted_id}")
return result.inserted_id
except Exception as e:
print(f"❌ 插入失败: {e}")
return None
def insert_many(self, collection_name: str, documents: List[Dict[str, Any]]):
"""
插入多个文档
Args:
collection_name: 集合名称
documents: 要插入的文档列表
Returns:
插入的文档ID列表
"""
try:
collection = self.db[collection_name]
result = collection.insert_many(documents)
print(f"✅ 批量插入成功,共 {len(result.inserted_ids)} 个文档")
return result.inserted_ids
except Exception as e:
print(f"❌ 批量插入失败: {e}")
return []
def find_all(self, collection_name: str):
"""
查询集合中的所有文档
Args:
collection_name: 集合名称
Returns:
文档列表
"""
try:
collection = self.db[collection_name]
documents = list(collection.find())
print(f"✅ 查询到 {len(documents)} 个文档")
return documents
except Exception as e:
print(f"❌ 查询失败: {e}")
return []
def find_with_filter(self, collection_name: str, filter_query: Dict[str, Any]):
"""
根据条件查询文档
Args:
collection_name: 集合名称
filter_query: 查询条件
Returns:
匹配的文档列表
"""
try:
collection = self.db[collection_name]
documents = list(collection.find(filter_query))
print(f"✅ 查询到 {len(documents)} 个匹配的文档")
return documents
except Exception as e:
print(f"❌ 条件查询失败: {e}")
return []
def find_one(self, collection_name: str, filter_query: Dict[str, Any]):
"""
查询单个文档
Args:
collection_name: 集合名称
filter_query: 查询条件
Returns:
单个文档或None
"""
try:
collection = self.db[collection_name]
document = collection.find_one(filter_query)
if document:
print("✅ 找到匹配的文档")
else:
print("⚠️ 未找到匹配的文档")
return document
except Exception as e:
print(f"❌ 查询单个文档失败: {e}")
return None
def update_one(self, collection_name: str, filter_query: Dict[str, Any], update_data: Dict[str, Any]):
"""
更新单个文档
Args:
collection_name: 集合名称
filter_query: 查询条件
update_data: 更新数据
Returns:
更新结果
"""
try:
collection = self.db[collection_name]
# 使用 $set 操作符更新指定字段
result = collection.update_one(filter_query, {"$set": update_data})
print(f"✅ 更新成功,匹配到 {result.matched_count} 个文档,修改了 {result.modified_count} 个文档")
return result
except Exception as e:
print(f"❌ 更新失败: {e}")
return None
def delete_one(self, collection_name: str, filter_query: Dict[str, Any]):
"""
删除单个文档
Args:
collection_name: 集合名称
filter_query: 查询条件
Returns:
删除结果
"""
try:
collection = self.db[collection_name]
result = collection.delete_one(filter_query)
print(f"✅ 删除成功,删除了 {result.deleted_count} 个文档")
return result
except Exception as e:
print(f"❌ 删除失败: {e}")
return None
def delete_many(self, collection_name: str, filter_query: Dict[str, Any]):
"""
删除多个文档
Args:
collection_name: 集合名称
filter_query: 查询条件
Returns:
删除结果
"""
try:
collection = self.db[collection_name]
result = collection.delete_many(filter_query)
print(f"✅ 批量删除成功,删除了 {result.deleted_count} 个文档")
return result
except Exception as e:
print(f"❌ 批量删除失败: {e}")
return None
def create_index(self, collection_name: str, field: str, unique=False):
"""
创建索引
Args:
collection_name: 集合名称
field: 索引字段
unique: 是否唯一索引
Returns:
索引名称
"""
try:
collection = self.db[collection_name]
index_result = collection.create_index([(field, pymongo.ASCENDING)], unique=unique)
print(f"✅ 索引创建成功: {index_result}")
return index_result
except Exception as e:
print(f"❌ 创建索引失败: {e}")
return None
def count_documents(self, collection_name: str, filter_query: Dict[str, Any] = None):
"""
统计文档数量
Args:
collection_name: 集合名称
filter_query: 查询条件(可选)
Returns:
文档数量
"""
try:
collection = self.db[collection_name]
if filter_query:
count = collection.count_documents(filter_query)
else:
count = collection.count_documents({})
print(f"📊 文档数量: {count}")
return count
except Exception as e:
print(f"❌ 统计失败: {e}")
return 0
def drop_collection(self, collection_name: str):
"""
删除集合
Args:
collection_name: 集合名称
Returns:
True if successful, False otherwise
"""
try:
collection = self.db[collection_name]
collection.drop()
print(f"🗑️ 集合 '{collection_name}' 已删除")
return True
except Exception as e:
print(f"❌ 删除集合失败: {e}")
return False
def close_connection(self):
"""关闭数据库连接"""
self.client.close()
print("🔌 MongoDB连接已关闭")
@staticmethod
def pretty_print(documents: List[Dict[str, Any]]):
"""美化打印文档"""
for i, doc in enumerate(documents):
print(f"\n📄 文档 {i+1}:")
# 处理ObjectId使其可序列化
doc_copy = doc.copy()
if '_id' in doc_copy:
doc_copy['_id'] = str(doc_copy['_id'])
print(json.dumps(doc_copy, indent=2, ensure_ascii=False))
# 使用示例
def main():
# 1. 创建MongoDB管理器实例(连接本地MongoDB)
mongo = MongoDBManager(
host='localhost',
port=27017,
database_name='testdb' # 数据库名称
)
try:
# 2. 列出所有数据库和集合
mongo.list_databases()
# 3. 示例数据:用户信息
users_collection = 'users'
# 4. 插入单个文档
print("\n1. 插入单个用户:")
user1 = {
"name": "张三",
"age": 25,
"email": "zhangsan@example.com",
"city": "北京",
"hobbies": ["读书", "游泳", "编程"],
"created_at": datetime.now(),
"is_active": True
}
user1_id = mongo.insert_one(users_collection, user1)
# 5. 插入多个文档
print("\n2. 批量插入用户:")
users = [
{
"name": "李四",
"age": 30,
"email": "lisi@example.com",
"city": "上海",
"hobbies": ["旅游", "摄影"],
"created_at": datetime.now(),
"is_active": True
},
{
"name": "王五",
"age": 28,
"email": "wangwu@example.com",
"city": "广州",
"hobbies": ["篮球", "音乐"],
"created_at": datetime.now(),
"is_active": True
},
{
"name": "赵六",
"age": 35,
"email": "zhaoliu@example.com",
"city": "北京",
"hobbies": ["烹饪", "电影"],
"created_at": datetime.now(),
"is_active": False
}
]
user_ids = mongo.insert_many(users_collection, users)
# 6. 查询所有文档
print("\n3. 查询所有用户:")
all_users = mongo.find_all(users_collection)
mongo.pretty_print(all_users)
# 7. 条件查询
print("\n4. 查询北京的用户:")
beijing_users = mongo.find_with_filter(users_collection, {"city": "北京"})
mongo.pretty_print(beijing_users)
# 8. 查询单个文档
print("\n5. 查询年龄大于30的用户:")
older_user = mongo.find_one(users_collection, {"age": {"$gt": 30}})
if older_user:
print(f"找到用户: {older_user['name']}, 年龄: {older_user['age']}")
# 9. 更新文档
print("\n6. 更新用户信息:")
mongo.update_one(
users_collection,
{"name": "张三"},
{"age": 26, "email": "zhangsan_new@example.com"}
)
# 10. 验证更新
updated_user = mongo.find_one(users_collection, {"name": "张三"})
if updated_user:
print(f"更新后的用户: {updated_user['name']}, 年龄: {updated_user['age']}, 邮箱: {updated_user['email']}")
# 11. 统计文档
print("\n7. 统计活跃用户:")
active_count = mongo.count_documents(users_collection, {"is_active": True})
print(f"活跃用户数量: {active_count}")
# 12. 删除文档
print("\n8. 删除非活跃用户:")
mongo.delete_many(users_collection, {"is_active": False})
# 13. 再次统计
remaining_count = mongo.count_documents(users_collection)
print(f"剩余用户数量: {remaining_count}")
# 14. 创建索引
print("\n9. 创建索引:")
mongo.create_index(users_collection, "email", unique=True)
# 15. 列出所有集合
mongo.list_collections()
except Exception as e:
print(f"程序执行出错: {e}")
finally:
# 16. 关闭连接
mongo.close_connection()
# 高级用法示例:使用聚合管道
def advanced_example():
"""高级查询示例:使用聚合管道"""
mongo = MongoDBManager(database_name='testdb')
try:
# 创建订单数据
orders_collection = 'orders'
# 插入一些订单数据
orders = [
{"customer": "张三", "amount": 150, "status": "completed", "date": datetime(2024, 1, 15)},
{"customer": "李四", "amount": 200, "status": "completed", "date": datetime(2024, 1, 16)},
{"customer": "张三", "amount": 300, "status": "pending", "date": datetime(2024, 1, 17)},
{"customer": "王五", "amount": 100, "status": "completed", "date": datetime(2024, 1, 18)},
{"customer": "李四", "amount": 250, "status": "completed", "date": datetime(2024, 1, 19)}
]
mongo.insert_many(orders_collection, orders)
# 使用聚合管道:按客户分组,计算总金额
print("\n🔍 聚合查询:每个客户的总订单金额")
pipeline = [
{"$match": {"status": "completed"}}, # 只选择已完成的订单
{"$group": {
"_id": "$customer", # 按客户分组
"total_amount": {"$sum": "$amount"}, # 计算总金额
"order_count": {"$sum": 1} # 计算订单数量
}},
{"$sort": {"total_amount": -1}} # 按总金额降序排序
]
collection = mongo.db[orders_collection]
results = list(collection.aggregate(pipeline))
print("客户消费统计:")
for result in results:
print(f" 客户: {result['_id']}, 总金额: ¥{result['total_amount']}, 订单数: {result['order_count']}")
finally:
mongo.close_connection()
# 使用上下文管理器(推荐方式)
def with_context_manager():
"""使用上下文管理器管理连接"""
from contextlib import contextmanager
@contextmanager
def get_mongo_connection():
"""获取MongoDB连接的上下文管理器"""
mongo = None
try:
mongo = MongoDBManager(database_name='testdb')
yield mongo
finally:
if mongo:
mongo.close_connection()
print("\n🎯 使用上下文管理器示例:")
with get_mongo_connection() as mongo:
# 在这里执行数据库操作
users = mongo.find_all('users')
print(f"当前有 {len(users)} 个用户")
if __name__ == "__main__":
print("=" * 50)
print("MongoDB CRUD 操作示例")
print("=" * 50)
# 运行基本示例
main()
print("\n" + "=" * 50)
print("高级查询示例")
print("=" * 50)
# 运行高级示例
advanced_example()
# 运行上下文管理器示例
with_context_manager()
3. 简化的快速使用版本
如果你需要一个更简洁的版本:
from pymongo import MongoClient
from datetime import datetime
# 1. 连接MongoDB
client = MongoClient('localhost', 27017) # 默认配置
# 2. 选择数据库
db = client['mydatabase']
# 3. 选择集合(类似于SQL的表)
collection = db['users']
# 4. 插入数据
user_data = {
"name": "张三",
"age": 25,
"email": "zhangsan@example.com",
"created_at": datetime.now()
}
result = collection.insert_one(user_data)
print(f"插入成功,ID: {result.inserted_id}")
# 5. 查询数据
# 查询所有文档
all_users = collection.find()
for user in all_users:
print(user)
# 条件查询
query = {"age": {"$gt": 20}} # 年龄大于20
users = collection.find(query)
for user in users:
print(user)
# 查询单个文档
user = collection.find_one({"name": "张三"})
print(f"找到用户: {user}")
# 6. 更新数据
collection.update_one(
{"name": "张三"},
{"$set": {"age": 26, "updated_at": datetime.now()}}
)
# 7. 删除数据
collection.delete_one({"name": "张三"})
# 8. 关闭连接
client.close()
4. 环境配置建议
创建 config.py 文件管理配置:
# config.py
class MongoDBConfig:
HOST = 'localhost'
PORT = 27017
USERNAME = None
PASSWORD = None
DATABASE = 'mydatabase'
# 连接字符串
@classmethod
def get_connection_string(cls):
if cls.USERNAME and cls.PASSWORD:
return f"mongodb://{cls.USERNAME}:{cls.PASSWORD}@{cls.HOST}:{cls.PORT}/"
return f"mongodb://{cls.HOST}:{cls.PORT}/"
5. 常见查询操作符
# 常用查询操作符示例
query_examples = {
# 等于
"等于": {"name": "张三"},
# 大于
"大于": {"age": {"$gt": 20}},
# 小于
"小于": {"age": {"$lt": 30}},
# 范围
"范围": {"age": {"$gte": 20, "$lte": 30}},
# 包含在数组中
"包含": {"hobbies": {"$in": ["读书", "游泳"]}},
# 不包含
"不包含": {"hobbies": {"$nin": ["游戏"]}},
# 存在字段
"存在字段": {"email": {"$exists": True}},
# 正则匹配
"正则": {"name": {"$regex": "^张"}}, # 姓张的
# 逻辑AND
"AND": {"$and": [{"age": {"$gt": 20}}, {"city": "北京"}]},
# 逻辑OR
"OR": {"$or": [{"city": "北京"}, {"city": "上海"}]},
}
6. 启动MongoDB服务
在运行代码前,确保MongoDB服务已启动:
Windows:
# 启动MongoDB服务
net start MongoDB
macOS:
# 使用Homebrew安装后启动
brew services start mongodb-community
Linux:
# Ubuntu/Debian
sudo systemctl start mongod
# 检查状态
sudo systemctl status mongod
这个完整示例涵盖了MongoDB的基本操作,包括连接、CRUD操作、聚合查询等。你可以根据实际需求调整和扩展这些代码。