MongoDB是使用C ++编写的领先的开源N0SQL数据库。本教程将使读者更好地了解将MongoDB集成到Python应用程序中所需的MongoDB概念。
SQL与NoSQL的区别
【MongoDB和Python简介】SQL数据库在定义和处理数据时使用结构化查询语言(SQL)。使用SQL时, 我们需要一个关系数据库管理系统(RDBMS)服务器, 例如SQL Server, MySQL服务器或MS Access。 RDBMS中的数据存储在称为表的数据库对象中。表是相关数据条目的集合, 由列和行组成。
NoSQL数据库具有用于非结构化数据的动态架构。在NoSQL中, 数据以几种方式存储:可以是面向列的, 面向文档的, 基于图的或组织为键值存储。 NoSQL数据库具有以下优点:
- 无需先定义其结构即可创建文档
- 每个文档可以有自己独特的结构
- 语法因数据库而异
- 大量结构化, 半结构化和非结构化数据
- 易于使用且灵活的面向对象编程
- 它是水平可扩展的
以下是NoSQL数据库的不同类型:
- 文档数据库将每个键与称为文档的复杂数据结构配对。文档是一组键值对。 MongoDB是文档存储数据库的示例。一组MongoDB文档被称为集合。这等效于RDBMS表。
- 图形存储用于存储有关数据网络的信息, 例如社交关系。 Graph商店包括Neo4J和Giraph。
- 键值存储数据库将数据库中的每个项目及其值存储为键。键值存储的示例是Riak和Berkeley DB。一些键值存储(例如Redis)允许每个值具有一种类型(例如整数), 从而增加了功能。
- 诸如Cassandra和HBase之类的宽列存储针对大型数据集的查询进行了优化, 并将数据列而不是行存储在一起。
为了全面了解MongoDB中使用的术语, 我们将它们与RDBMS中的等效术语进行比较。
RDBMS | MongoDB |
---|---|
Database | Database |
Table | Collection |
Row | Document |
Column | Field |
Primary Key | Primary Key |
表联接 | Embedded Documents |
为了开始使用MongoDB, 我们首先必须安装它。安装说明可在官方的MongoDB文档中找到。要在Ubuntu上运行快速安装, 请运行以下命令:
sudo apt更新sudo apt install -y mongodb
完成此操作后, 我们将通过在终端上运行以下命令来检查服务和数据库:
sudo systemctl状态mongodb
● mongodb.service - An object/document-oriented database
Loaded: loaded (/lib/systemd/system/mongodb.service;
enabled;
vendor preset:
Active: active (running) since Thu 2018-09-20 13:14:02 EAT;
23h ago
Docs: man:mongod(1)
Main PID: 11446 (mongod)
Tasks: 27 (limit: 4915)
CGroup: /system.slice/mongodb.service
└─11446 /usr/bin/mongod --unixSocketPrefix=/run/mongodb --config /etcSep 20 13:14:02 derrick systemd[1]: Started An object/document-oriented database
lines 1-10/10 (END)
上面的消息表示一切都很好, 我们已经准备开始使用MongoDB。
现在我们已经安装了MongoDB, 我们需要一种在Python代码中与其进行交互的方法。官方的Python MongoDB驱动程序称为PyMongo。我们可以使用pip安装它, 如下所示:
pip安装pymongo
我们可以从终端与MongoDB进行交互, 但是出于本教程的目的, 我们将在Jupyter Notebook中运行所有代码。
与MongoClient建立连接
我们需要做的第一件事是导入pymongo。导入应该运行没有任何错误, 以表示我们已经完成了正确的安装。
import pymongo
在MongoDB中建立连接需要我们为运行中的MongoDB实例创建一个MongoClient。
from pymongo import MongoClient
client = MongoClient()
上面的代码将连接到默认的主机和端口, 但是我们可以指定主机和端口, 如下所示:
client = MongoClient("localhost", 27017)
MongoDB还具有URI格式来执行此操作。
client = MongoClient('mongodb://localhost:27017/')
创建数据库
要在MongoDB中创建数据库, 我们使用MongoClient实例并指定数据库名称。如果MongoDB不存在, 它将创建一个数据库并连接到该数据库。
db = client['srcminidb']
重要的是要注意, 数据库和集合是在MongoDB中延迟创建的。这意味着集合和数据库是在第一个文档插入集合和数据库后创建的。
MongoDB中的数据
MongoDB中的数据使用JSON样式的文档表示和存储。在PyMongo中, 我们使用字典来表示文档。让我们在下面显示一个PyMongo文档的示例:
article = {"author": "Derrick Mwiti", "about": "Introduction to MongoDB and Python", "tags":
["mongodb", "python", "pymongo"]}
插入文件
要将文档插入到集合中, 我们使用insert_one()方法。如前所述, 集合类似于RDBMS中的表, 而文档类似于行。
articles = db.articles
result = articles.insert_one(article)
插入文档后, 会生成一个特殊的键_id, 它对于此文档而言是唯一的。我们可以打印文档ID, 如下所示:
print("First article key is: {}".format(result.inserted_id))
First article key is: 5ba5c05e2e8ca029163417f8
插入第一个文档后, 将创建articles集合。我们可以使用list_collection_names方法进行确认。
db.list_collection_names()
['articles', 'user']
我们可以使用insert_many()方法将多个文档插入到集合中, 如下所示。
article1 = {"author": "Emmanuel Kens", "about": "Knn and Python", "tags":
["Knn", "pymongo"]}
article2 = {"author": "Daniel Kimeli", "about": "Web Development and Python", "tags":
["web", "design", "HTML"]}
new_articles = articles.insert_many([article1, article2])
print("The new article IDs are {}".format(new_articles.inserted_ids))
The new article IDs are [ObjectId('5ba5c0c52e8ca029163417fa'), ObjectId('5ba5c0c52e8ca029163417fb')]
使用find_one()检索单个文档
find_one()返回与查询匹配的单个文档;如果不存在, 则不返回任何文档。此方法返回遇到的第一个匹配项。当我们调用下面的方法时, 我们得到了插入到集合中的第一篇文章。
print(articles.find_one())
{'_id': ObjectId('5ba5c0b52e8ca029163417f9'), 'author': 'Derrick Mwiti', 'about': 'Introduction to MongoDB and Python', 'tags': ['mongodb', 'python', 'pymongo']}
查找集合中的所有文档
MongoDB还允许我们使用find方法检索集合中的所有文档。
for article in articles.find():
print(article)
{'_id': ObjectId('5ba5c0b52e8ca029163417f9'), 'author': 'Derrick Mwiti', 'about': 'Introduction to MongoDB and Python', 'tags': ['mongodb', 'python', 'pymongo']}
{'_id': ObjectId('5ba5c0c52e8ca029163417fa'), 'author': 'Emmanuel Kens', 'about': 'Knn and Python', 'tags': ['Knn', 'pymongo']}
{'_id': ObjectId('5ba5c0c52e8ca029163417fb'), 'author': 'Daniel Kimeli', 'about': 'Web Development and Python', 'tags': ['web', 'design', 'HTML']}
在构建Web应用程序时, 我们通常会从URL获取文档ID, 然后尝试从MongoDB集合中检索它们。为了实现这一点, 我们首先必须将获得的字符串ID转换为ObjectId。
from bson.objectid import ObjectId
def get(post_id):
document = client.db.collection.find_one({'_id': ObjectId(post_id)})
仅返回某些字段
有时我们可能不想返回文档中的所有字段。让我们展示我们将获取特定字段。在我们的例子中, 我们使用0指定不应获取_id, 并使用1指定应获取作者和about。 MongoDB不允许我们两次指定零。例如, 将标签指定为0以下将产生错误。我们不允许在同一对象中同时指定0和1值(除非其中一个字段是_id字段)。当我们指定一个值为0的字段时, 所有其他字段的值为1。
for article in articles.find({}, { "_id": 0, "author": 1, "about": 1}):
print(article)
{'author': 'Derrick Mwiti', 'about': 'Introduction to MongoDB and Python'}
{'author': 'Emmanuel Kens', 'about': 'Knn and Python'}
{'author': 'Daniel Kimeli', 'about': 'Web Development and Python'}
结果排序
我们可以使用sort()方法对结果进行升序或降序排序。默认顺序是升序。我们使用1表示升序, 使用-1表示降序。
doc = articles.find().sort("author", -1)for x in doc:
print(x)
{'_id': ObjectId('5ba5c0c52e8ca029163417fa'), 'author': 'Emmanuel Kens', 'about': 'Knn and Python', 'tags': ['Knn', 'pymongo']}
{'_id': ObjectId('5ba5c0b52e8ca029163417f9'), 'author': 'Derrick Mwiti', 'about': 'Introduction to MongoDB and Python', 'tags': ['mongodb', 'python', 'pymongo']}
{'_id': ObjectId('5ba5c0c52e8ca029163417fb'), 'author': 'Daniel Kimeli', 'about': 'Web Development and Python', 'tags': ['web', 'design', 'HTML']}
更新文件
我们使用update_one()方法更新文档。此函数采用的第一个参数是定义要更新的文档的查询对象。如果该方法找到多个文档, 则只会更新第一个文档。让我们在Derrick撰写的文章中更新作者的姓名。
query = { "author": "Derrick Mwiti" }
new_author = { "$set": { "author": "John David" } }articles.update_one(query, new_author)for article in articles.find():
print(article)
{'_id': ObjectId('5ba5c0b52e8ca029163417f9'), 'author': 'John David', 'about': 'Introduction to MongoDB and Python', 'tags': ['mongodb', 'python', 'pymongo']}
{'_id': ObjectId('5ba5c0c52e8ca029163417fa'), 'author': 'Emmanuel Kens', 'about': 'Knn and Python', 'tags': ['Knn', 'pymongo']}
{'_id': ObjectId('5ba5c0c52e8ca029163417fb'), 'author': 'Daniel Kimeli', 'about': 'Web Development and Python', 'tags': ['web', 'design', 'HTML']}
限制结果
MongoDB使我们能够使用limit方法来限制查询的结果。在下面的查询中, 我们将结果限制为一个记录。
limited_result = articles.find().limit(1)
for x in limited_result:
print(x)
{'_id': ObjectId('5ba5c0b52e8ca029163417f9'), 'author': 'John David', 'about': 'Introduction to MongoDB and Python', 'tags': ['mongodb', 'python', 'pymongo']}
MongoDB删除文件
我们使用delete_one()方法删除MongoDB中的文档。此方法的第一个参数是我们要删除的文档的查询对象。如果此方法找到多个文档, 它将仅删除找到的第一个文档。让我们删除ID为5ba4cbe42e8ca029163417ce的文章。
db.articles.delete_one({"_id":ObjectId("5ba4d00e2e8ca029163417d4")})
<
pymongo.results.DeleteResult at 0x7f3acae72ec8>
删除许多文件
为了删除许多文档, 我们使用delete_many()方法。传递空查询对象将删除所有文档。
delete_articles = articles.delete_many({})
print(delete_articles.deleted_count, " articles deleted.")
3articles deleted.
删除集合
在MongoDB中, 我们可以使用drop()方法删除集合。
articles.drop()
我们可以确认该集合已被删除, 因为当我们调用list_collection_names时, 会得到一个空列表。
db.list_collection_names()
[]
在本教程中, 我们不可能遍历所有MongoDB方法。我建议读者访问PyMongo和MongoDB的官方文档以了解更多信息。
MongoDB对象文档映射器(ODM)
在SQL中, 我们有对象关系映射器(ORM)映射器, 可在使用SQL时提供抽象。 MongoDB具有类似于对象文档映射器(ODM)的功能。 MongoEngine是一个在PyMongo之上提供高级抽象的库。运行以下命令以使用pip安装它。
pip安装否则
我们还可以尝试许多其他的MongoDB ODM, 并选择最佳的使用方式。其他MongoDB ODM的示例包括ming, minimongo和mongokit。
导入mongoengine之后, 我们使用connect函数并指定数据库, 端口和主机, 以便与MongoDB实例建立连接。
from mongoengine import *
connect('srcminidb', host='localhost', port=27017)
MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True, read_preference=Primary())
定义我们的文件
假设我们正在开发一个社交网站, 它将允许用户发布消息。这意味着我们需要一个用户和一个注释文档。就像我们使用带有ORM的关系数据库一样, 我们定义用户将拥有的字段和数据类型。我们通过对mongoengine的Document类进行子类化来创建文档。 required = True表示创建用户时必须指定此字段。否则, 将引发异常。
class User(Document):
email = StringField(required=True)
first_name = StringField(max_length=30)
last_name = StringField(max_length=30)
现在让我们展示如何创建一个posts文档并引用用户文档。 ReferenceField使我们能够在mongoengine中从一个文档引用另一个文档。
class Post(Document):
title = StringField(max_length=120, required=True)
author = ReferenceField(User)
保存文件
要将文档保存到数据库, 请调用save()方法。如果文档在数据库中不存在, 则将创建该文档。如果已经存在, 则更改将自动进行更新。
user = User(email="connect@derrickmwiti.com", first_name="Derrick", last_name="Mwiti")
user.save()
<
User: User object>
访问刚刚创建的对象与其他ORM非常相似
print(user.id, user.email, user.first_name, user.last_name)
5ba5c3bf2e8ca029163417fc connect@derrickmwiti.com Derrick Mwiti
总结在本教程中, 我们学习了如何在Python中使用MongoDB。我们还引入了mongoengine, 这是一个对象文档映射器, 使我们可以更轻松地在Python中与MongoDB进行交互。另外, 我们介绍了如何使用pymongo和mongoengine创建和操作文档。你可以通过访问MongoDB, pymomgo和mongoengine的官方文档了解更多信息。
如果你想了解有关在Python中操作数据的更多信息, 请参加srcmini的” 在Python中导入数据” (第1部分)课程。
推荐阅读
- Python中的JSON数据处理
- TensorFlow初学者教程
- Python中的决策树分类
- 读取Excel文件并将其导入R
- 歌词分析(使用带有R的机器学习进行预测分析)
- R Apply系列教程
- Win 8系统下PDF文件不显示缩略图怎样处理
- Win8账户密码输错导致无法退出安全模式该如何处理
- Win8/Win 8杀毒软件评测结果:小红伞/卡巴/比特梵德满分排列首