数据存储:一文掌握存储数据到MongoDB详解

文章目录

    • 一、环境准备
      • 1.1 安装MongoDB
      • 1.2 安装Python MongoDB驱动
    • 二、连接到MongoDB
      • 2.1 基本连接
      • 2.2 连接到MongoDB Atlas(云服务)
    • 三、基本CRUD操作
      • 3.1 创建(Create):插入数据
      • 3.2 读取(Read):查询数据
      • 3.3 更新(Update):修改数据
      • 3.4 删除(Delete):删除数据
      • 3.5 完整示例
    • 四、高级操作
      • 4.1 使用索引
      • 4.2 事务处理
      • 4.3 聚合管道
    • 五、使用MongoEngine进行ODM操作
      • 5.1 安装MongoEngine
      • 5.2 定义文档模型
      • 5.3 执行CRUD操作
    • 六、最佳实践
    • 七、总结

MongoDB是一种流行的NoSQL数据库,以其灵活的文档模型和高可扩展性而闻名。Python提供了多种库来与MongoDB进行交互,其中最常用的是pymongo和mongoengine。本文将详细介绍如何使用Python将数据存储到MongoDB,包括环境设置、基本操作(CRUD)、高级功能以及最佳实践。

关于mongo的更多样例请参考:MongoDB基础和进阶

一、环境准备

1.1 安装MongoDB

首先,确保已经在系统中安装并运行了MongoDB。可以从 MongoDB官方网站 下载并安装适合你操作系统的版本。

1.2 安装Python MongoDB驱动

使用pip安装pymongo库,这是Python中最常用的MongoDB驱动。

pip install pymongo

如果需要使用MongoDB的认证功能或其他高级特性,可以考虑安装官方推荐的驱动:

pip install pymongo[srv]

二、连接到MongoDB

2.1 基本连接

以下是使用pymongo连接到MongoDB的基本示例:

from pymongo import MongoClient# 连接到本地MongoDB实例
client = MongoClient('mongodb://localhost:27017/')# 选择数据库,如果不存在则会在第一次写入时创建
db = client['mydatabase']# 选择集合(类似于表),如果不存在则会在第一次插入时创建
collection = db['mycollection']

2.2 连接到MongoDB Atlas(云服务)

如果使用MongoDB Atlas等云服务,连接字符串会包含用户名和密码:

from pymongo import MongoClient# 替换为你的连接字符串
uri = "mongodb+srv://<username>:<password>@cluster0.mongodb.net/mydatabase?retryWrites=true&w=majority"client = MongoClient(uri)
db = client['mydatabase']
collection = db['mycollection']

三、基本CRUD操作

3.1 创建(Create):插入数据

插入单条文档

document = {"name": "张三","age": 28,"email": "zhangsan@example.com"
}insert_result = collection.insert_one(document)
print(f"插入文档的ID: {insert_result.inserted_id}")

插入多条文档

documents = [{"name": "李四", "age": 34, "email": "lisi@example.com"},{"name": "王五", "age": 23, "email": "wangwu@example.com"}
]insert_many_result = collection.insert_many(documents)
print(f"插入文档的IDs: {insert_many_result.inserted_ids}")

3.2 读取(Read):查询数据

查询所有文档

results = collection.find()
for doc in results:print(doc)

条件查询

query = {"age": {"$gt": 25}}
results = collection.find(query)
for doc in results:print(doc)

投影(选择特定字段)

query = {"name": "张三"}
projection = {"_id": 0, "email": 1}
result = collection.find_one(query, projection)
print(result)

3.3 更新(Update):修改数据

更新单个文档

query = {"name": "李四"}
new_values = {"$set": {"age": 35}}
update_result = collection.update_one(query, new_values)
print(f"匹配的文档数: {update_result.matched_count}, 修改的文档数: {update_result.modified_count}")

更新多个文档

query = {"age": {"$lt": 30}}
new_values = {"$inc": {"age": 1}}
update_result = collection.update_many(query, new_values)
print(f"匹配的文档数: {update_result.matched_count}, 修改的文档数: {update_result.modified_count}")

3.4 删除(Delete):删除数据

删除单个文档

query = {"name": "王五"}
delete_result = collection.delete_one(query)
print(f"删除的文档数: {delete_result.deleted_count}")

删除多个文档

query = {"age": {"$gt": 30}}
delete_result = collection.delete_many(query)
print(f"删除的文档数: {delete_result.deleted_count}")

3.5 完整示例

from pymongo import MongoClientdef main():# 连接 MongoDBclient = MongoClient("mongodb://localhost:27017/")print("连接 MongoDB 成功")# 选择数据库和集合db = client["testdb"]collection = db["users"]print("数据库和集合已选择")try:# 插入单条数据data = {"name": "张三", "age": 25, "email": "zhangsan@example.com"}result = collection.insert_one(data)print(f"插入成功,文档 ID: {result.inserted_id}")# 插入多条数据data = [{"name": "李四", "age": 30, "email": "lisi@example.com"},{"name": "王五", "age": 28, "email": "wangwu@example.com"}]result = collection.insert_many(data)print(f"插入成功,文档 IDs: {result.inserted_ids}")# 查询所有数据print("查询所有数据:")results = collection.find()for result in results:print(result)# 条件查询print("查询 age 大于 25 的数据:")query = {"age": {"$gt": 25}}results = collection.find(query)for result in results:print(result)# 更新单条数据query = {"name": "张三"}new_values = {"$set": {"age": 26}}result = collection.update_one(query, new_values)print(f"更新成功,匹配文档数: {result.matched_count}, 修改文档数: {result.modified_count}")# 删除单条数据query = {"name": "张三"}result = collection.delete_one(query)print(f"删除成功,删除文档数: {result.deleted_count}")finally:# 关闭连接client.close()print("MongoDB 连接已关闭")if __name__ == "__main__":main()

运行上述代码后,输出如下:

连接 MongoDB 成功
数据库和集合已选择
插入成功,文档 ID: 651f8b7e4b8e4e1f2c8e4f1a
插入成功,文档 IDs: [651f8b7e4b8e4e1f2c8e4f1b, 651f8b7e4b8e4e1f2c8e4f1c]
查询所有数据:
{'_id': ObjectId('651f8b7e4b8e4e1f2c8e4f1a'), 'name': '张三', 'age': 25, 'email': 'zhangsan@example.com'}
{'_id': ObjectId('651f8b7e4b8e4e1f2c8e4f1b'), 'name': '李四', 'age': 30, 'email': 'lisi@example.com'}
{'_id': ObjectId('651f8b7e4b8e4e1f2c8e4f1c'), 'name': '王五', 'age': 28, 'email': 'wangwu@example.com'}
查询 age 大于 25 的数据:
{'_id': ObjectId('651f8b7e4b8e4e1f2c8e4f1b'), 'name': '李四', 'age': 30, 'email': 'lisi@example.com'}
{'_id': ObjectId('651f8b7e4b8e4e1f2c8e4f1c'), 'name': '王五', 'age': 28, 'email': 'wangwu@example.com'}
更新成功,匹配文档数: 1, 修改文档数: 1
删除成功,删除文档数: 1
MongoDB 连接已关闭

四、高级操作

4.1 使用索引

索引可以提高查询性能。以下是创建索引的示例:

# 创建单字段索引
collection.create_index("email", unique=True)# 创建复合索引
collection.create_index([("name", pymongo.ASCENDING), ("age", pymongo.DESCENDING)])

4.2 事务处理

MongoDB支持多文档事务,适用于需要原子性的操作。

from pymongo import MongoClient
from pymongo.errors import ConnectionFailureclient = MongoClient('mongodb://localhost:27017/')
db = client['mydatabase']
collection = db['mycollection']with client.start_session() as session:with session.start_transaction():try:collection.insert_one({"name": "赵六", "age": 29}, session=session)collection.update_one({"name": "张三"}, {"$set": {"age": 28}}, session=session)except ConnectionFailure:session.abort_transaction()print("事务失败,已回滚")

4.3 聚合管道

聚合管道用于数据处理和分析。

pipeline = [{"$match": {"age": {"$gt": 25}}},{"$group": {"_id": "$name", "total": {"$sum": 1}}},{"$sort": {"total": -1}}
]results = collection.aggregate(pipeline)
for doc in results:print(doc)

五、使用MongoEngine进行ODM操作

MongoEngine是一个基于MongoDB的对象文档映射器(ODM),类似于Django ORM,适用于需要更高抽象层次的项目。

5.1 安装MongoEngine

pip install mongoengine

5.2 定义文档模型

from mongoengine import Document, StringField, IntField, connect# 连接到MongoDB
connect('mydatabase')class User(Document):name = StringField(required=True)age = IntField(required=True)email = StringField(unique=True)# 创建文档
user = User(name="孙七", age=27, email="sunqi@example.com")
user.save()# 查询文档
user = User.objects(name="孙七").first()
print(user.email)

5.3 执行CRUD操作

# 更新
user.age = 28
user.save()# 删除
user.delete()# 查询所有
users = User.objects()
for u in users:print(u.name, u.age, u.email)

六、最佳实践

​连接管理:使用连接池和上下文管理器来管理MongoDB连接,确保资源合理利用。

from pymongo import MongoClientwith MongoClient('mongodb://localhost:27017/') as client:db = client['mydatabase']# 执行操作

​索引优化:根据查询需求创建合适的索引,避免全表扫描,提高查询性能。

​数据验证:使用MongoEngine等ODM框架进行数据验证,确保数据一致性。

​安全性

  • 使用认证机制保护MongoDB实例。
  • 避免在代码中硬编码敏感信息,使用环境变量或配置文件管理凭证。
  • ​错误处理:捕获并处理可能的异常(如使用pymongo.errors.PyMongoError ),确保应用的健壮性。

性能优化:对于大规模数据插入,可以使用 insert_many 的 ordered=False 参数来提高性能。

​合理使用事务:事务适用于需要原子性的多文档操作,但不宜滥用,以免影响性能。

七、总结

使用Python存储数据到MongoDB非常灵活且高效。通过pymongo库,可以执行各种CRUD操作,并利用其丰富的功能满足不同的需求。对于需要更高抽象层次的项目,MongoEngine提供了便捷的ODM支持。在实际应用中,结合最佳实践,可以构建高性能、可维护的数据存储解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/70811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法教程:岛的最大面积

算法教程:岛的最大面积 我们将首先讨论问题和解决方案,然后使用可视化工具(上一篇博客中进行了介绍)来更好地理解搜索过程。 问题描述 我们将要演练的具体问题是问题 Leetcode:岛屿的最大面积。在 Leetcode 上找到的直接问题描述是: 给你一个 m x n 二进制矩阵网格。岛…

Scrapy:隧道代理中移除 Proxy-Authorization 的原理解析

隧道代理中移除 Proxy-Authorization 的原理解析 背景 在 Scrapy 的 HTTP 下载处理中&#xff0c;当使用隧道代理&#xff08;TunnelingAgent&#xff09;时&#xff0c;会移除请求头中的 Proxy-Authorization。这个操作看似简单&#xff0c;但背后有着重要的安全考虑和技术原…

大中型虚拟化园区网络设计

《大中型虚拟化园区网络设计》属于博主的“园区网”专栏&#xff0c;若想成为HCIE&#xff0c;对于园区网相关的知识需要非常了解&#xff0c;更多关于园区网的内容博主会更新在“园区网”专栏里&#xff0c;请持续关注&#xff01; 一.前言 华为云园区网络解决方案(简称Cloud…

sklearn中的决策树-分类树:剪枝参数

剪枝参数 在不加限制的情况下&#xff0c;一棵决策树会生长到衡量不纯度的指标最优&#xff0c;或者没有更多的特征可用为止。这样的决策树 往往会过拟合。为了让决策树有更好的泛化性&#xff0c;我们要对决策树进行剪枝。剪枝策略对决策树的影响巨大&#xff0c;正确的剪枝策…

几个api

几个api 原型链 可以阅读此文 Function instanceof Object // true Object instanceof Function // true Object.prototype.isPrototypeOf(Function) // true Function.prototype.isPrototypeOf(Object) // true Object.__proto__ Function.prototype // true Function.pro…

【Azure 架构师学习笔记】- Azure Databricks (12) -- Medallion Architecture简介

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (11) – UC搭建 前言 使用ADB 或者数据湖&#xff0c;基本上绕不开一个架构“Medallion”&#xff0c; 它使得数据管理更为简单有效。ADB 通过…

Android手机部署DeepSeek

1.概述 android手机端部署deepseek一般需要安装termux,ollama,deepseek三个大的步骤 原因分析&#xff1a;deepseek等大模型需要类似ollama的工具去运行。ollama有mac window和linux版本&#xff0c;无Android版本&#xff1b;termux是一个模拟linux环境的Android app&#x…

计算机科学技术领域的内卷现状与应对措施分析

计算机科学技术领域的内卷现状与应对措施分析 李升伟 整理 ### 计算机科学技术领域的内卷现状与应对措施分析 #### 一、内卷现状分析 1. **教育与升学内卷** 计算机科学与技术相关专业&#xff08;如计算机科学与技术、人工智能、大数据等&#xff09;已成为考研竞争最…

python-leetcode 45.二叉树转换为链表

题目&#xff1a; 给定二叉树的根节点root,请将它展开为一个单链表&#xff1a; 展开后的单链表应该使用同样的TreeNode,其中right子指针指向链表中的下一个节点&#xff0c;而左子指针始终为空 展开后的单链表应该与二叉树先序遍历顺序相同 方法一&#xff1a;二叉树的前序…

【leetcode hot 100 15】三数之和

一、两数之和的扩展 class Solution {public List<List<Integer>> threeSum(int[] nums) {// 将得到的结果存入Set中&#xff0c;保证不重复Set<List<Integer>> set new HashSet<>();// 模拟两数之和&#xff0c;作为第一个循环中的内容for(in…

设备健康管理系统在制造业的深度应用探索

引言 在制造业的数字化转型浪潮中&#xff0c;设备健康管理系统正逐渐成为企业提升竞争力的关键利器。随着工业 4.0 和智能制造概念的不断深入&#xff0c;制造业对设备的高效、稳定运行提出了更高要求。设备健康管理系统借助先进的传感器技术、物联网&#xff08;IoT&#xf…

HTTPS 与 HTTP 的区别在哪?

HTTP与HTTPS作为互联网数据传输的核心协议&#xff0c;其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者的通信流程、安全机制及核心差异。 一、HTTP的通信机制 先来看看HTTP是什么吧。 HTTP基于TCP/IP协议栈&#xff0c;采用经典客户端-服务…

为什么要将PDF转换为CSV?CSV是Excel吗?

在企业和数据管理的日常工作中&#xff0c;PDF文件和CSV文件承担着各自的任务。PDF通常用于传输和展示静态的文档&#xff0c;而CSV因其简洁、易操作的特性&#xff0c;广泛应用于数据存储和交换。如果需要从PDF中提取、分析或处理数据&#xff0c;转换为CSV格式可能是一个高效…

【JAVAEE】多线程

【JAVAEE】多线程 一、进程1.1 进程的定义1.2 进程和线程的联系 二、线程2.1 JConsole工具2.2 创建线程2.2.1 Thread类&#xff0c;start&#xff08;&#xff09;&#xff0c;run&#xff08;&#xff09;2.2.2 继承Thread类2.2.3 实现Runnable接口2.2.4 匿名内部类2.2.5 使用…

手机打电话时如何识别对方按下的DTMF按键的字符-安卓AI电话机器人

手机打电话时如何识别对方按下的DTMF按键的字符 --安卓AI电话机器人 一、前言 前面的篇章中&#xff0c;使用蓝牙电话拦截手机通话的声音&#xff0c;并对数据加工&#xff0c;这个功能出来也有一段时间了。前段时间有试用的用户咨询说&#xff1a;有没有办法在手机上&#xff…

【Go】十八、http 调用服务的编写

http接口框架的搭建 这个http接口框架的搭建参考之前的全量搭建&#xff0c;这里是快速搭建的模式&#xff1a; 直接对已有的http模块进行复制修改&#xff0c;主要修改点在于 proto部分与api、router 部分&#xff0c;剩余的要针对进行修改模块名称。 接口的具体编写 在 a…

WiseFlow本地搭建实录---保姆教程

今天从零开始搭建了Wiseflow的本地环境搭建&#xff0c;目前使用的都是免费的API&#xff0c;我建议大家可以一起尝试一下搭建自己的关键信息的数据库&#xff0c;我是windows的环境&#xff0c;但是其他的应该也差不多&#xff0c;踩了很多坑&#xff0c;希望这篇文章能帮大家…

数的计算(蓝桥云课)

题目描述 输入一个自然数 n (n≤1000)n (n≤1000)&#xff0c;我们对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自然数,但该自然数不能超过原数的一半; 加上数后,继续按此规则进行处理,直到不能再加自然数为止。 问总共可以产生多少个数。 输入描述 输…

知识库功能测试难点

图表交互功能测试难点 知识库图表类型多&#xff0c;每种图表交互功能不同。像柱状图&#xff0c;可能有点击柱子查看详细数据、鼠标悬停显示数据提示等交互&#xff1b;折线图除了这些&#xff0c;还可能支持缩放查看不同时间段数据。多种交互操作在不同图表间存在差异&#x…

【人工智能】数据挖掘与应用题库(201-300)

1、在LetNet5网络中,卷积核的大小是? 答案:5*5 2、LeNet5网络参数的数量约为? 答案:6万 3、AlexNet与LeNet5相比,使用了哪些机制来改进模型的训练过程? 答案: 数据增广Dropout抑制过拟合ReLU激活函数CUDA加速神经网络训练4、VGGNet使用的卷积核的大小是? 答案:…