确保:
(1)安装了MongDB,并启动了服务。没有安装的话,可以参考https://blog.csdn.net/liujingliuxingjiang/article/details/122068753?spm=1001.2014.3001.5501
(2)安装了python和pip
1.安装pymongo
pip install pymongo
2.连接MongoDB
使用pymongo库中的MongoClient,需要传入ip和端口。
import pymongo
client = pymongo.MongoClient(host='localhost',port=27017)
这样就创建好了MongoDB的连接对象。
host和port还可以这样写:
client = pymongo.MongoClient('mongodb://localhost:27017/')
3.指定数据库
指定操作的数据库,我这里先在mongodb中创建了一个数据库mytest,这里就指定这个mytest数据库。
db = client.mytest
也可以写成;
db = client['mytest']
4.指定集合
每个数据库中可以有多个集合,操作的时候需要指定具体是哪个集合。
这里我指定的是预先创建好的集合book。
collection = db.book
也可以写成
collection = db['book']
5.插入数据
这里向book集合中插入数据:
book_info = {
'_id':'1',
'book_name':'数据结构'
}
插入的数据是类似json对象,键值对。其中,每一条数据都有一个_id属性,如果不显示指明该属性,插入数据的时候MongoDB会自动生成一个唯一值赋值给_id属性。
上面的book_info中显示指明了_id。
执行插入操作,使用collection的insert_one()或insert_many()。
5.1 insert_one()
一次插入一条数据,执行成功后返回InsertOneResult对象,我们可以调用insered_id属性获取_id的值。
result = collection.insert_one(book_info)
print(result)
print(result.inserted_id)
执行结果:
<pymongo.results.InsertOneResult object at 0x000001E8C87A12C8>
1
5.2 insert_many()
一次插入多条数据,数据以列表的形式传入参数。执行成功后返回InsertmanyResult对象,我们可以调用insered_ids属性获取_id的值。
book_info1 = {
'_id':'2',
'book_name':'C++编程'
}
book_info2 = {
'_id':'3',
'book_name':'Python编程'
}
result = collection.insert_many([book_info1,book_info2])
print(result)
print(result.inserted_ids)
执行结果;
<pymongo.results.InsertManyResult object at 0x0000027AD6E10688>
[‘2’, ‘3’]
6.查询
查询数据,可以使用find_one()或find()。
6.1 find_one()
find_one()查询得到的是单个结果,是一个字典类型。这里用book_name属性查询的,也可以使用其他属性查询。
result = collection.find_one({'book_name':'C++编程'})
print(type(result))
print(result)
执行结果:
<class ‘dict’>
{’_id’: ‘2’, ‘book_name’: ‘C++编程’}
如果查询不到返回None。如下:
result = collection.find_one({'book_name':'Java编程'})
print(type(result))
print(result)
<class ‘NoneType’>
None
如果不加查询条件,默认返回了第一条。
result = collection.find_one({})
print(type(result))
print(result)
<class ‘dict’>
{’_id’: ‘1’, ‘book_name’: ‘数据结构’}
6.2 find()
查询多条数据,返回的是一个生成器对象。
这里查询名字为“C++编程”的书:
result = collection.find({'book_name':'C++编程'})
print(result)
for r in result:
print(r)
执行结果:
<pymongo.cursor.Cursor object at 0x0000029D1A414C50>
{’_id’: ‘2’, ‘book_name’: ‘C++编程’}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’}
不加条件,返回所有的数据:
result = collection.find({})
print(result)
for r in result:
print(r)
<pymongo.cursor.Cursor object at 0x00000194A2F03C50>
{’_id’: ‘1’, ‘book_name’: ‘数据结构’}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’}
6.3 查询条件
6.3.1 功能符号
大于:$gt
小于:$lt
大于等于:$gte
小于等于:$lte
不等于:$ne
在范围:$in
不在范围:$nin
正则匹配查询:$regex
属性是否存在:$exists
类型判断:$type
数字模操作:$mod
文字查询:$text
高级条件查询:$where
6.3.2 应用举例
(1)小于
查询_id的值小于’3’的数据
result = collection.find({'_id':{'$lt':'3'}})
print(result)
for r in result:
print(r)
注意3要加引号,因为之前插入_id的时候是带了引号的
执行结果:
<pymongo.cursor.Cursor object at 0x000001D38A346CC0>
{’_id’: ‘1’, ‘book_name’: ‘数据结构’}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’}
(2)在范围内
这里试一下范围用字符型
result = collection.find({'_id':{'$in':['2','4']}})
得到的结果是2和4的,没有3的
{’_id’: ‘2’, ‘book_name’: ‘C++编程’}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’}
为了查看一下整数的情况,新增了一项price,值为整数:
result = collection.find({'price':{'$in':[10,50]}})
得到结果
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
看来是一个[]内是一个元素集合,并不是区间。
(3)正则匹配
匹配book_name以C开头的。
result = collection.find({'book_name':{'$regex':'^C.*'}})
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’, ‘price’: 25}
(4)判断类型
匹配price类型是int的数据
result = collection.find({'price':{'$type':'int'}})
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’, ‘price’: 25}
7.计数
使用estimated_document_count()方法,统计符合条件的查询结果有多少条数据。
之前版本支持count()方法,新的版本不支持了,换成estimated_document_count()了。
result = collection.estimated_document_count()
如果带条件,使用count_documents()
result = collection.count_documents({'price':{'$nin':[10,50]}})
8.排序
使用sort()方法,参数为(排序字段,升序/降序标志)。
升序:
result = collection.find({'price':{'$in':[10,20,50]}}).sort('price',pymongo.ASCENDING)
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
降序
result = collection.find({'price':{'$in':[10,20,50]}}).sort('price',pymongo.DESCENDING)
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
9.偏移
使用skip()方法,参数是一个整数n,表示获取从n+1条开始的数据
比如n=1,就是获取第2条开始的数据。
使用skip前:
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
使用skip后:
result = collection.find({'price':{'$in':[10,20,50]}}).skip(1)
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
10.限制条数
使用limit()方法,参数是一个整数n,表示或取前n条数据
result = collection.find({'price':{'$in':[10,20,50]}}).limit(2)
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
还可以和skip联合使用。
result = collection.find({'price':{'$in':[10,20,50]}}).skip(1).limit(1)
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
11.更新
使用update_one()和update_many()方法。需要指定更新的条件和更新后的数据。
返回的结果是UpdateResult类型,可以调用它的matched_count和modified_count属性,获取匹配的数据条数和影响的数据条数。
更新前:
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 50}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’, ‘price’: 25}
(1)单条更新
例1:更新_id为2的数据,price更新为45
result = collection.update_one({'_id':'2'},{'$set':{'price':45}})
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 10}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 45}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’, ‘price’: 25}
例2:更新_id为1,2,3的数据,price更新为45
result = collection.update_one({'_id':{'$in':['1','2','3']}},{'$set':{'price':45}})
print(result.matched_count,result.modified_count)
可以看到只匹配和影响了1条数据,也就是第一条。实际应该是匹配3条,但是这里只有是1条,因为是单条更新。
1 1
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 45}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 45}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 20}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’, ‘price’: 25}
(2)多条更新
例2:更新_id为1,2,3的数据,price更新为30
result = collection.update_many({'_id':{'$in':['1','2','3']}},{'$set':{'price':30}})
print(result.matched_count,result.modified_count)
这里看到匹配和影响了3条
3 3
{’_id’: ‘1’, ‘book_name’: ‘数据结构’, ‘price’: 30}
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 30}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 30}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’, ‘price’: 25}
12.删除
使用delete_one()和delete_many()方法,参数是条件。
删除_id是1的数据。
result = collection.delete_one({'_id':'1'})
{’_id’: ‘2’, ‘book_name’: ‘C++编程’, ‘price’: 30}
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 30}
{’_id’: ‘4’, ‘book_name’: ‘C++编程’, ‘price’: 25}
删除_id是2,4的数据
result = collection.delete_many({'_id':{'$in':['2','4']}})
{’_id’: ‘3’, ‘book_name’: ‘Python编程’, ‘price’: 30}
13.其他方法
以上就是pymongo常用的操作数据库的方法,还有一些组合方法。
find_one_and_delete(),find_one_and_replace()等等。
—————————————————————————————————————————————————————
参考书籍:
崔庆才-《python3爬虫开发实战》