确保:

(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爬虫开发实战》

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐