【Python爬虫学习笔记8-2】MongoDB数据库操作详解
上一篇学习笔记8-1中介绍了MySQL和MongoDB的安装、启动和配置,本节我们接着学习有关MongoDB的一些概念、基本操作和在python中的使用。
MongoDB常用概念
为更好地了解MongoDB地概念,下表以SQL术语进行对照说明。
MongoDB术语 | SQL术语 | 说明 |
database | database | 数据库 |
collection | table | 数据集合/表 |
document | row | 数据记录文档/行 |
field | column | 数据域/字段 |
index | index | 索引 |
joins | table | 表连接,MongoDB不支持 |
primary key | primary key | 主键,MongoDB会自动定义一个_id为主键字段 |
MongoDB三元素
在MongoDB中有数据库、集合和文档三元素。
文档(document):即关系型数据库中的一行,是JSON对象地扩展形式,由键值对构成。
一个文档:
{“username”:”UnikFox”,”city”:”Guangzhou”}
集合(collection):即关系型数据库中的一张表,可以存储多个结构类型的文档。
一个集合:
{“username”:”UnikFox”,”city”:”Guangzhou”}
{“username”:”UnikFox”,”country”:”China”}
{“title”:”Python”,”date”:”2018/9”}
MongoDB基本操作命令
在MongoDB中,和MySQL一样有许多的命令,这里先简单地了解几个基本的操作命令,更多的使用会在python化MongoDB操作中提及,另外也可以下参考资料http://www.runoob.com/mongodb/mongodb-tutorial.html
1.db——查看当前所使用的数据库
> db
test
2.show dbs——查看所有的数据库
> show dbs
Test 0.000GB
admin 0.000GB
config 0.000GB
local 0.000GB
3.use <数据库名>——切换数据库,若不存在,则在内存中新建一个(但此时并不真实存在,需要插入数据后才写入数据库系统)
> use LALa
switched to db LALa> show dbs
Test 0.000GB
admin 0.000GB
config 0.000GB
local 0.000GB
4.db.dropDatabase()——删除当前所使用的数据库
> use Test
switched to db Test> db.dropDatabase()
{ "dropped" : "Test", "ok" : 1 }
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
5.db.<集合名>.insert(value)——添加一个文档到指定的集合中
> use Test
switched to db Test> db.info.insert({"username":"Uni","city":"Guangzhou"})
WriteResult({ "nInserted" : 1 })
6.db.<集合名>.find()——从指定的集合中查找数据
> db.info.find()
{ "_id" : ObjectId("5ba73f632c43d991ec8ea178"), "username" : "Uni", "city" : "Guangzhou" }
Python化MongoDB
和MySQL的python化操作一样,使用python操作MongoDB也需要一个中间件——pymongo。我们可以使用pip命令来安装:
pip install pymongo
1.连接MongoDB,并指定数据库和集合
和pymysql的用法类似,起初都需要创建连接对象,所不同的是:在MySQL中创建时传入了数据库参数,而mongoDB中创建时只需要传入IP及端口号即可,数据库在后续可以自由切换。
##连接MongoDB,并设置所访问的数据库和集合 import pymongo # 获取连接mongodb的对象 client = pymongo.MongoClient(host="localhost", port=27017) # 获取数据库对象 db = client.citylist #或通过键来获取:db = client['citylist'] # 获取数据库中的集合 collection = db.city #或通过键来获取:collection = db['city']
2.增删改查基本操作
在pymongo中,对增删改查这四种操作都提供了’单元操作’和’多元操作’两种方式。’单元操作’即操作的对象为一个文档,而’多元操作’的对象为多个文档。接下来我们通过一些示例来了解其用法。
(1)插入数据——<collection>.insert(object) 或 <collection>.insert_many(objects_list)
这两个方法都可以直接使用,且返回值为所插入数据的_id值或_id的集合列表。
# 插入数据 row1 = { 'city': 'ShenZhen', 'province': 'GuangDong' } row2 = { 'city': 'ZhongShan', 'province': 'GuangDong' } row3 = { 'city': 'WuHan', 'province': 'HuBei' } # 插入一条数据 result = collection.insert(row1) print(result) #5ba7762da78f5e3c1457db12 # 插入多条数据 results = collection.insert_many([row2,row3]) print(results) #<pymongo.results.InsertManyResult object at 0x0000020E7530CE88>
(2)删除数据——<collection>.delete_one(condition_dict) 或 <collection>.delete_many(condition_dict)
这两个方法传入的参数是一个条件过滤字典,用于筛选所要删除的数据,其返回值为一个DeleteResult类型,同时还可以使用deleted_count属性获取删除的数据条数。
#删除数据 # 删除一条’province’为’HuBei’的数据 result = collection.delete_one({"province":"HuBei"}) print(result) #<pymongo.results.DeleteResult object at 0x000002292EA8CE88> print(result.deleted_count) #1 # 删除所有’province’为’GuangDong’的数据 results = collection.delete_many({"province":"GuangDong"}) print(results) #<pymongo.results.DeleteResult object at 0x000002292EAC1188> print(results.deleted_count) #2
(3)更新数据——<collection>.update_one(condition_dict,{‘$set’:{key_value}}) 或 <collection>.update_many(condition_dict,{‘$set’:{key_value}})
更新方法中的第一个参数为条件过滤字典,用于筛选所要更新的数据,第二个参数为待更新的键值字段字典,这两个方法的返回值均为UpdateResult类型,我们可以调用其matched_count和modified_count属性分别来获得匹配的数据条目和影响的数据条目。
# 更新数据 # 将一条'province'为'GuangDong'的数据'city'字段值更新为'GuangZhou' result = collection.update_one({"province":"GuangDong"},{"$set":{"city":"GuangZhou"}}) print(result) #<pymongo.results.UpdateResult object at 0x000001E892F461C8> print(result.matched_count,result.modified_count) #1 1 # 将所有'province'为'GuangDong'的数据'city'字段值更新为'GuangDong_cities' results = collection.update_many({"province": "GuangDong"}, {"$set": {"city": "GuangDong_cities"}}) print(results) #<pymongo.results.UpdateResult object at 0x00000221AC1B60C8> print(results.matched_count, results.modified_count)#2 2
(4)查找数据——<collection>.find_one(condition_dict) 或 <collection>.find(condition_dict)
同删除和更新一样,其需传入一个用于筛选的条件过滤字典,方法的返回值是所查询到的文档的字典数据或数据的迭代器,因此我们可以通过键来获取相应的字段数据。此外我们还可以对返回值调用count()方法来获取查询到的条目数。
# 查找数据 # 查询一条'city'字段为'WuHan'的数据 result = collection.find_one({"city":"WuHan"}) print(type(result)) #<class 'dict'> print(result) #{'_id': ObjectId('5ba77fb3a78f5e39643a476e'), 'city': 'WuHan', 'province': 'HuBei'} print(result['province']) #HuBei # 查询collection中所有数据 cursor = collection.find() print(type(cursor)) #<class 'pymongo.cursor.Cursor'> print(cursor) #<pymongo.cursor.Cursor object at 0x000001DE4C39CA90> print(cursor.count()) #3 for x in cursor: print(x) """ Output: {'_id': ObjectId('5ba77fb2a78f5e39643a476c'), 'city': 'ShenZhen', 'province': 'GuangDong'} {'_id': ObjectId('5ba77fb3a78f5e39643a476d'), 'city': 'ZhongShan', 'province': 'GuangDong'} {'_id': ObjectId('5ba77fb3a78f5e39643a476e'), 'city': 'WuHan', 'province': 'HuBei'} """
3.其他使用
(1)比较符号和功能符号
在上述的条件过滤字典中,我们都是使用’等于‘关系,而实际上我们常常需要根据’不等‘关系来筛选数据,因此在MongoDB中提供了如下常用的比较符号和一些辅助的功能符号。
比较符号:
符号 | 含义 | 示例 |
$lt | 小于 | {‘price’:{‘$lt’:12}} |
$gt | 大于 | {‘price’:{‘$gt’:12}} |
$lte | 小于等于 | {‘price’:{‘$lte’:12}} |
$gte | 大于等于 | {‘price’:{‘$gte’:12}} |
$ne | 不等于 | {‘price’:{‘$ne’:12}} |
$in | 在范围内 | {‘price’:{‘$in’:[10,20]}} |
$nin | 不在范围内 | {‘price’:{‘$nin’:[10,20]}} |
功能符号:
符号 | 含义 | 示例 | 说明 |
$regex | 匹配正则表达式 | {‘city’:{‘$regex’:’C.*’}} | 字段city以C开头 |
$exists | 属性是否存在 | {‘city’:{‘$exists’:True}} | 属性city存在 |
$type | 类型判断 | {‘city’:{‘$type’:’String’}} | 字段city类型为String |
$mod | 模操作 | {‘number’:{‘$mod’:[2,1]}} | number字段模2余1 |
$text | 文本查询 | {‘$text’:{‘$search’:’Hello’}} | text类型的属性中包含Hello字符串 |
$where | 高级条件查询 | {‘$where’:’obj.grade1>obj.grade2’} | 自身的grade1大于grade2 |
(2)排序
在查询后的结果中,我们可以使用sort(field,<排序规则>)方法来排序,其中第一个参数field为排序关键字,第二个参数指明排序规则为升序(pymongo.ASCENDING)还是降序(pymongo.DESCENDING)
cursor = collection.find().sort('city',pymongo.ASCENDING)
print([result['city'] for result in cursor ])
#['ShenZhen', 'WuHan', 'ZhongShan']
(3)偏移
对于查询后的结果我们也可以使用skip(count)来实现偏移获取,即忽略前count条数据;同时我们还可以使用limit(count)来限制获取数据的条目数
cursor = collection.find().sort('city',pymongo.ASCENDING).skip(1)
print([result['city'] for result in cursor ])
#['WuHan', 'ZhongShan']
cursor = collection.find().sort('city',pymongo.ASCENDING).skip(1).limit(1)
print([result['city'] for result in cursor ])
#['WuHan']