PyMongo学习之路

最近在学习 python 的数据库存储,PyMongo 是 MongoDB 官方推荐的 python 数据库,因此想要将学习内容整理一下。

在此之前,请确保已经安装了 python 和 MongoDB。

python 的下载地址:

https://www.python.org/downloads/

MongoDB 的安装方法:

http://api.mongodb.com/python/current/installation.html

另外,MongoDB 官方推出了 MongoDB 的可视化工具 MongoDB Compass:

https://www.mongodb.com/download-center/compass?jmp=docs

下面直接进入正题

连接 Mongo 客户端

开始之前,首先要在 python shell 中导入 pymongo,并且在默认主机和默认端口运行一个 MongoDB 实例

#在 python shell 下导入 pymongo
>>> import pymongo

在命令行模式下启动 MongoDB

>>> mongod

出现提示在  27017 端口等待连接就启动成功了

连接的第一步就是创建一个运行 mongod 实例的 mongo 客户端 ,创建客户端可以明确指定主机和端口,也可以直接使用默认主机和端口。

>>> from pymongo import MongoClient
#使用默认主机和端口
>>> client = MongoClient()
#使用指定主机和端口的方法创建客户端实例
>>> client = MongoClient('localhost', 27017)
#使用 MongoDB NRI 格式指定主机和端口的方法创建客户端实例
>>> client = MongoClient('mongodb://localhost:27017/')

创建后 mongo 服务器端就会提示连接主机和端口表示连接成功。

存储数据

一个 mongoDB 的实例可以有多个独立的数据库,你可以用属性和字典两种不同的风格访问数据库

#以属性风格访问(attribute style access)
>>> db = client.test_database
#以字典风格访问(dictionary style access)
>>> db = client['test-database']

数据库创建成功后,就要在数据库中创建集合。集合是存储在 MongoDB 中的一组文件,你可以将集合近似看成关系型数据库中的表。同样可以使用两种方式创建集合。

#using attribute style access
>>> collection = db.test_collection
#using dictionary style access
>>> collection = db['test-collection']

注意:上面的创建数据库和集合命令并没有实际操作 MongoDB 服务器,只有当加入了文件才是真正创建了数据库和集合。

所以以上两个操作 MongoDB 服务器并不会有什么响应。

MongoDB 中的数据是以 JSON 风格的文件存储的,在 PyMongo 中使用字典来表示文件

>>> post = {"author": "Mike",
...         "text": "My first blog post!",
...         "tags": ["mongodb", "python", "pymongo"]}

接下来就可以使用 insert_one() 方法将文件存入到集合

>>> post_id = collection.insert_one(post)

这时 MongoDB 服务器就提示 received client metadata from 主机:端口,就表示一个数据文件已经存入到 MongoDB 服务器中。

并且这个文件会自动加上一个在这个集合中唯一的 "_id"  值,insert_one() 返回一个  InsertOneResult 的实例。

集合中加入文件后于是这个集合和数据库就在服务器中创建了,可以用 数据库.collection_names() 方法和 客户端.database_names() 方法查看某个数据库中有哪些集合以及某个客户拥有哪些数据库。

可以看出,MongoDB 是以集合来存储数据的,客户端,数据库,集合的结构关系大致是这样的:

数据查询

find_one () 方法返回符合查询的单个文件,或者返回符合查询的多个文件的第一个文件。返回类型是字典

可以看到 "_id" 就是自动加入到这个文件的。 

也可以在 find_one() 中加入索引条件

可以看到查到了刚刚存到 collection 集合中的文件。之所以和前面 find_one() 方法查询到的不一样,是因为我之前做实验的时候就在 collection 中插入了一个文件,find_one() 由于没有查询条件,就自动查询到 collection 集合中的第一个文件。

值得注意的是,如果没有匹配到符合条件的文件,就返回 None,什么也不发生。

我们也可以通过 ObjectId 查询

>>> post_id
ObjectId(...)
>>> collection.find_one({"_id": post_id})
{u'_id': ObjectId('...'),
 u'author': u'Mike',
 u'date': datetime.datetime(...),
 u'tags': [u'mongodb', u'python', u'pymongo'],
 u'text': u'My first blog post!'}

也可以使用 insert_many() 方法。通过给他的第一个参数传入一个列表,就可以将列表中的每个文件插入到集合中。

>>> new_posts = [{"author": "Mike",
...               "text": "Another post!",
...               "tags": ["bulk", "insert"]},
...              {"author": "Eliot",
...               "title": "MongoDB is fun",
...               "text": "and pretty easy too!"}]

使用 insert_many() 方法插入列表中的多个文件。 

可以看到 insert_many() 返回一个  InsertManyResult 实例,并且插入的每个文件都有各自的 "_id" 值。

find() 方法可以获得查询匹配到的多个文件。他返回一个 Cursor 实例,这个实例允许我们在所有匹配到的文件上迭代。

和 find_one() 一样,可以给 find() 传递参数限定查询条件

count()  方法可以返回一次查询匹配的文件数。

因此可以查看一个集合中有多少个文件(documents)以及一次特定查询匹配的文件数。

MongoDB 支持多种类型的高级查询。可以指定特定范围内的查询,例如查询包含 tags 属性的文件

"$exists" 是一个范围查询的操作符。如果还有年龄属性的话,当然可以查询出年龄大于某个值或者小于某个值的那些文件(documents) 。另外还可以使用 sort() 方法对得到的结果进行排序。

更多的高级范围查询条件可以查阅:https://docs.mongodb.com/manual/reference/operator/query/

添加索引

添加索引可以加快特定的查询 ,还能给查询和存储文件添加一些其他的功能。

例如可以给键创建一个唯一索引,阻止那些和这个键对应的值相同的文件插入。

首先我们需要创建索引

可以看到现在有两个索引了,其中一个就是 "_id" 上的索引是 MongoDB 自动创建的,还有一个 "user_id" 上的索引就是我们创建的。

现在创建一些用户配置文件

>>> user_profiles = [
...     {'user_id': 211, 'name': 'Luke'},
...     {'user_id': 212, 'name': 'Ziltoid'}]
>>> result = db.profiles.insert_many(user_profiles)

索引现在阻止集合中和 "user_id" 值相同的文件的插入。

>>> new_profile = {'user_id': 213, 'name': 'Drew'}
>>> duplicate_profile = {'user_id': 212, 'name': 'Tommy'}
>>> result = db.profiles.insert_one(new_profile)  # This is fine.
>>> result = db.profiles.insert_one(duplicate_profile)
Traceback (most recent call last):
DuplicateKeyError: E11000 duplicate key error index: test_database.profiles.$user_id_1 dup key: { : 212 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值