MongoDB和Python简介

MongoDB是使用C ++编写的领先的开源N0SQL数据库。本教程将使读者更好地了解将MongoDB集成到Python应用程序中所需的MongoDB概念。
SQL与NoSQL的区别
【MongoDB和Python简介】SQL数据库在定义和处理数据时使用结构化查询语言(SQL)。使用SQL时, 我们需要一个关系数据库管理系统(RDBMS)服务器, 例如SQL Server, MySQL服务器或MS Access。 RDBMS中的数据存储在称为表的数据库对象中。表是相关数据条目的集合, 由列和行组成。
NoSQL数据库具有用于非结构化数据的动态架构。在NoSQL中, 数据以几种方式存储:可以是面向列的, 面向文档的, 基于图的或组织为键值存储。 NoSQL数据库具有以下优点:

  • 无需先定义其结构即可创建文档
  • 每个文档可以有自己独特的结构
  • 语法因数据库而异
  • 大量结构化, 半结构化和非结构化数据
  • 易于使用且灵活的面向对象编程
  • 它是水平可扩展的
NoSQL数据库类型
以下是NoSQL数据库的不同类型:
  • 文档数据库将每个键与称为文档的复杂数据结构配对。文档是一组键值对。 MongoDB是文档存储数据库的示例。一组MongoDB文档被称为集合。这等效于RDBMS表。
  • 图形存储用于存储有关数据网络的信息, 例如社交关系。 Graph商店包括Neo4J和Giraph。
  • 键值存储数据库将数据库中的每个项目及其值存储为键。键值存储的示例是Riak和Berkeley DB。一些键值存储(例如Redis)允许每个值具有一种类型(例如整数), 从而增加了功能。
  • 诸如Cassandra和HBase之类的宽列存储针对大型数据集的查询进行了优化, 并将数据列而不是行存储在一起。
比较MongoDB和RDBMS
为了全面了解MongoDB中使用的术语, 我们将它们与RDBMS中的等效术语进行比较。
RDBMS MongoDB
Database Database
Table Collection
Row Document
Column Field
Primary Key Primary Key
表联接 Embedded Documents
MongoDB和Python
为了开始使用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部分)课程。

    推荐阅读