python使用pymongo读写mongodb

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q383965374/article/details/86015728

转载请注明出处:python使用pymongo读写mongodb

准备工作

在开始之前,请确保已经安装好了MongoDB并启动了其服务,并且安装好了Python的PyMongo库。

PyMongo介绍

Python 要连接 MongoDB 需要 MongoDB 驱动,这里我们使用 PyMongo 驱动来连接。

官方文档
http://api.mongodb.com/python/current/api/pymongo/collection.html

pip 安装

pip 是一个通用的 Python 包管理工具,提供了对 Python 包的查找、下载、安装、卸载的功能。

安装 pymongo:

$ python3 -m pip3 install pymongo

也可以指定安装的版本:

$ python3 -m pip3 install pymongo==3.5.1

更新 pymongo 命令:

$ python3 -m pip3 install --upgrade pymongo

easy_install 安装

旧版的 Python 可以使用 easy_install 来安装,easy_install 也是 Python 包管理工具。

$ python -m easy_install pymongo

更新 pymongo 命令:

$ python -m easy_install -U pymongo

测试 PyMongo

接下来我们可以创建一个测试文件 demo_test_mongodb.py,代码如下:

demo_test_mongodb.py 文件代码:

#!/usr/bin/python3
 
import pymongo

执行以上代码文件,如果没有出现错误,表示安装成功。

连接MongoDB

连接MongoDB时,我们需要使用PyMongo库里面的MongoClient。一般来说,传入MongoDB的IP及端口即可,其中第一个参数为地址host,第二个参数为端口port(如果不给它传递参数,默认是27017):

没有权限auth认证的连接方式

import pymongo
client = pymongo.MongoClient(host='localhost', port=27017)

这样就可以创建MongoDB的连接对象了。
另外,MongoClient的第一个参数host还可以直接传入MongoDB的连接字符串,它以mongodb开头,例如:

client = MongoClient('mongodb://localhost:27017/')

这也可以达到同样的连接效果。

需要auth权限认证的连接方式

需要注意mongodb数据库本身的版本
mongodb3.0之前的加密方式为MONGODB-CR
示例如下:

from pymongo import MongoClient
client = MongoClient('example.com',
                     username='user',
                      password='password',
                      authMechanism='MONGODB-CR')

uri = "mongodb://user:[email protected]/?authSource=the_database&authMechanism=MONGODB-CR"
client = MongoClient(uri)

如果不指定加密方式,PyMongo 会自动使用MONGODB-CR方式连接3.0之前的mongodb服务和使用SCRAM-SHA-1方式连接3.0到3.6的mongodb服务端,使用 SCRAM-SHA-1 or SCRAM-SHA-256连接mongodb4.0的服务端。

使用代码如下:

uri = "mongodb://user:[email protected]/default_db?authSource=admin"
client = MongoClient(uri)

更多权限相关的连接和加密方式参考:
http://api.mongodb.com/python/current/examples/authentication.html

指定数据库

MongoDB中可以建立多个数据库,接下来我们需要指定操作哪个数据库。这里我们以test数据库为例来说明,下一步需要在程序中指定要使用的数据库:

db = client.test

这里调用client的test属性即可返回test数据库。当然,我们也可以这样指定:

db = client['test']

这两种方式是等价的。

指定集合

MongoDB的每个数据库又包含许多集合(collection),它们类似于关系型数据库中的表。
下一步需要指定要操作的集合,这里指定一个集合名称为students。与指定数据库类似,指定集合也有两种方式:

collection = db.students
collection = db['students']

这样我们便声明了一个Collection对象。

添加记录

单条插入

# 示例一:指定 _id,如果重复,会产生异常
ID = 'firstRecord'
insertDate = '2017-08-28'
count = 10
insert_record = {'_id':ID, 'endDate': insertDate, 'count': count}
insert_res = db_coll.insert_one(insert_record)
print(f"insert_id={insert_res.inserted_id}: {insert_record}")
# 结果:insert_id=firstRecord: {'_id': 'firstRecord', 'endDate': '2017-08-28', 'count': 10}


# 示例二:不指定 _id,自动生成
insertDate = '2017-10-10'
count = 20
insert_record = {'endDate': insertDate, 'count': count}
insert_res = db_coll.insert_one(insert_record)
print(f"insert_id={insert_res.inserted_id}: {insert_record}")
# 结果:insert_id=59ad356d51ad3e2314c0d3b2: {'endDate': '2017-10-10', 'count': 20, '_id': ObjectId('59ad356d51ad3e2314c0d3b2')}

批量插入

# 更高效,但要注意如果指定_id,一定不能重复
# ordered = True,遇到错误 break, 并且抛出异常
# ordered = False,遇到错误 continue, 循环结束后抛出异常
insertRecords = [{'i':i, 'date':'2017-10-10'} for i in range(10)]
insertBulk = db_coll.insert_many(insertRecords, ordered = True)
print(f"insert_ids={insertBulk.inserted_ids}")
# 结果:insert_ids=[ObjectId('59ad3ba851ad3e1104a4de6d'), ObjectId('59ad3ba851ad3e1104a4de6e'), O

查找记录:find

指定返回哪些字段

# 示例一:所有字段
# select * from galance20170801
searchRes = db_coll.find()
# 或者searchRes = db_coll.find({}) 
familys=[]
for x in searchRes:
     familys.append(x)
     print(f"userId={x['userId']} " f"dealed={x['dealed']}")
return familys


# 示例二:用字典指定要显示的哪几个字段
# select _id,key from galance20170801
queryArgs = {}
projectionFields = {'_id':True, 'key':True}  # 用字典指定
searchRes = db_coll.find(queryArgs, projection = projectionFields)
# 结果{'_id': 'B01EYCLJ04', 'key': 'pro audio'}


# 示例三:用字典指定去掉哪些字段
queryArgs = {}
projectionFields = {'_id':False, 'key':False}  # 用字典指定
searchRes = db_coll.find(queryArgs, projection = projectionFields)
# 结果{'activity': False, 'avgStar': 4.3,  'color': 'Yellow & Black', 'date': '2017-08-01'}


# 示例四:用列表指定要显示哪几个字段
# select _id,key,date from galance20170801
queryArgs = {}
projectionFields = ['key','date']  # 用列表指定,结果中一定会返回_id这个字段
searchRes = db_coll.find(queryArgs, projection = projectionFields)
# 结果{'_id': 'B01EYCLJ04', 'date': '2017-08-01', 'key': 'pro audio'}

指定查询条件

比较:=,!=,>, <, >=, <=
$ne:不等于(not equal)
$gt:大于(greater than)
$lt:小于(less than)
$lte:小于等于(less than equal)
$gte:大于等于(greater than equal)

# 示例一:相等
# select _id,key,sales,date from galance20170801 where key = 'TV & Video'
queryArgs = {'key':'TV & Video'}
projectionFields = ['key','sales','date']
searchRes = db_coll.find(queryArgs, projection = projectionFields)
# 结果:{'_id': '0750699973', 'date': '2017-08-01', 'key': 'TV & Video', 'sales': 0}


# 示例二:不相等
# select _id,key,sales,date from galance20170801 where sales != 0
queryArgs = {'sales':{'$ne':0}}
projectionFields = ['key','sales','date']
searchRes = db_coll.find(queryArgs, projection = projectionFields)
# 结果:{'_id': 'B01M996469', 'date': '2017-08-01', 'key': 'stereos', 'sales': 2}

# 示例三:大于 
# where sales > 100
queryArgs = {'sales':{'$gt':100}}
# 结果:{'_id': 'B010OYASRG', 'date': '2017-08-01', 'key': 'Sound Bar', 'sales': 124}

# 示例四:小于 
# where sales < 100
queryArgs = {'sales':{'$lt':100}}
# 结果:{'_id': 'B011798DKQ', 'date': '2017-08-01', 'key': 'pro audio', 'sales': 0}

# 示例五:指定范围 
# where sales > 50 and sales < 100
queryArgs = {'sales':{'$gt':50, '$lt':100}}
# 结果:{'_id': 'B008D2IHES', 'date': '2017-08-01', 'key': 'Sound Bar', 'sales': 66}

# 示例六:指定范围,大于等于,小于等于 
# where sales >= 50 and sales <= 100
queryArgs = {'sales':{'$gte':50, '$lte':100}}
# 结果:{'_id': 'B01M6DHW26', 'date': '2017-08-01', 'key': 'radios', 'sales': 50}

and

# 示例一:不同字段,并列条件 
# where date = '2017-08-01' and sales = 100
queryArgs = {'date':'2017-08-01', 'sales':100}
# 结果:{'_id': 'B01BW2YYYC', 'date': '2017-08-01', 'key': 'Video', 'sales': 100}

# 示例二:相同字段,并列条件 
# where sales >= 50 and sales <= 100
# 正确:queryArgs = {'sales':{'$gte':50, '$lte':100}}
# 错误:queryArgs = {'sales':{'$gt':50}, 'sales':{'$lt':100}}
# 结果:{'_id': 'B01M6DHW26', 'date': '2017-08-01', 'key': 'radios', 'sales': 50}

##or

# 示例一:不同字段,或条件 
# where date = '2017-08-01' or sales = 100
queryArgs = {'$or':[{'date':'2017-08-01'}, {'sales':100}]}
# 结果:{'_id': 'B01EYCLJ04', 'date': '2017-08-01', 'key': 'pro audio', 'sales': 0}

# 示例二:相同字段,或条件 
# where sales = 100 or sales = 120
queryArgs = {'$or':[{'sales':100}, {'sales':120}]}
# 结果:
#    {'_id': 'B00X5RV14Y', 'date': '2017-08-01', 'key': 'Chargers', 'sales': 120}
#    {'_id': 'B0728GGX6Y', 'date': '2017-08-01', 'key': 'Glasses', 'sales': 100}

in,not in,all

# 示例一:in 
# where sales in (100,120)
# 这个地方一定要注意,不能用List,只能用元组,因为是不可变的
# 如果用了 {'$in': [100,120]},就会出现异常:TypeError: unhashable type: 'list'
queryArgs = {'sales':{'$in': (100,120)}}
# 结果:
#    {'_id': 'B00X5RV14Y', 'date': '2017-08-01', 'key': 'Chargers', 'sales': 120}
#    {'_id': 'B0728GGX6Y', 'date': '2017-08-01', 'key': 'Glasses', 'sales': 100}

# 示例二:not in 
# where sales not in (100,120)
queryArgs = {'sales':{'$nin':(100,120)}}
# 结果:{'_id': 'B01EYCLJ04', 'date': '2017-08-01', 'key': 'pro audio', 'sales': 0}

# 示例三:匹配条件内所有值 all 
# where sales = 100 and sales = 120
queryArgs = {'sales':{'$all':[100,120]}}  # 必须同时满足
# 结果:无结果

# 示例四:匹配条件内所有值 all  
# where sales = 100 and sales = 100
queryArgs = {'sales':{'$all':[100,100]}}  # 必须同时满足
# 结果:{'_id': 'B01BW2YYYC', 'date': '2017-08-01', 'key': 'Video', 'sales': 100}

字段是否存在

# 示例一:字段不存在
# where rank2 is null
queryArgs = {'rank2':None}
projectionFields = ['key','sales','date', 'rank2']
searchRes = db_coll.find(queryArgs, projection = projectionFields)
# 结果:{'_id': 'B00ACOKQTY', 'date': '2017-08-01', 'key': '3D TVs', 'sales': 0}

# mongodb中的命令
db.categoryAsinSrc.find({'isClawered': true, 'avgCost': {$exists: false}})

# 示例二:字段存在
# where rank2 is not null
queryArgs = {'rank2':{'$ne':None}}
projectionFields = ['key','sales','date','rank2']
searchRes = db_coll.find(queryArgs, projection = projectionFields).limit(100)
# 结果:{'_id': 'B014I8SX4Y', 'date': '2017-08-01', 'key': '3D TVs', 'rank2': 4.0, 'sales': 0}

正则表达式匹配:$regex(SQL:like)

# 示例一:关键字key包含audio子串
# where key like "%audio%"
queryArgs = {'key':{'$regex':'.*audio.*'}}
# 结果:{'_id': 'B01M19FGTZ', 'date': '2017-08-01', 'key': 'pro audio', 'sales': 1}

数组中必须包含元素:$all

# 查询记录,linkNameLst是一个数组,指定linkNameLst字段必须包含 'Electronics, Computers & Office' 这个元素。
db.getCollection("2018-01-24").find({'linkNameLst': {'$all': ['Electronics, Computers & Office']}})

# 查询记录,linkNameLst是一个数组,指定linkNameLst字段必须同时包含 'Wearable Technology' 和 'Electronics, Computers & Office' 这两个元素。
db.getCollection("2018-01-24").find({'linkNameLst': {'$all': ['Wearable Technology', 'Electronics, Computers & Office']}})

按数组大小查询

两个思路:
第一个思路:使用$where(具有很大的灵活性,但是速度会慢一些)

# priceLst是一个数组, 目标是查询 len(priceLst) < 3 
db.getCollection("20180306").find({$where: "this.priceLst.length < 3"})

关于$where,请参考官方文档:http://docs.mongodb.org/manual/reference/operator/query/where/。

第二个思路:判断数组中的某个指定索引的元素是否存在(会比较高效)
例如:如果要求 len(priceLst) < 3:就意味着 num[ 2 ]不存在

# priceLst是一个数组, 目标是查询 len(priceLst) < 3 
db.getCollection("20180306").find({'priceLst.2': {$exists: 0}})

例如:如果要求 len(priceLst) > 3:就意味着 num[ 3 ]存在

# priceLst是一个数组, 目标是查询 len(priceLst) > 3 
db.getCollection("20180306").find({'priceLst.3': {$exists: 1}})

限定数量:limit

# 示例一:按sales降序排列,取前100
# select top 100 _id,key,sales form galance20170801 where key = 'speakers' order by sales desc
queryArgs = {'key':'speakers'}
projectionFields = ['key','sales']
searchRes = db_coll.find(queryArgs, projection = projectionFields)
topSearchRes = searchRes.sort('sales',pymongo.DESCENDING).limit(100)

排序:sort

# 示例二:按sales降序,rank升序
# select _id,key,date,rank from galance20170801 where key = 'speakers' order by sales desc,rank
queryArgs = {'key':'speakers'}
projectionFields = ['key','sales','rank']
searchRes = db_coll.find(queryArgs, projection = projectionFields)
# sortedSearchRes = searchRes.sort('sales',pymongo.DESCENDING) # 单个字段
sortedSearchRes = searchRes.sort([('sales', pymongo.DESCENDING),('rank', pymongo.ASCENDING)]) # 多个字段
# 结果:
# {'_id': 'B000289DC6', 'key': 'speakers', 'rank': 3.0, 'sales': 120}
# {'_id': 'B001VRJ5D4', 'key': 'speakers', 'rank': 5.0, 'sales': 120}

统计:count

# 示例三:统计匹配记录总数
# select count(*) from galance20170801 where key = 'speakers'
queryArgs = {'key':'speakers'}
searchResNum = db_coll.find(queryArgs).count()
# 结果:
# 106

修改记录

# 根据筛选条件_id,更新这条记录。如果找不到符合条件的记录,就插入这条记录(upsert = True)
updateFilter = {'_id': item['_id']}
updateRes = db_coll.update_one(filter = updateFilter,
                               update = {'$set': dict(item)},
                               upsert = True)
print(f"updateRes = matched:{updateRes.matched_count}, modified = {updateRes.modified_count}")


# 根据筛选条件,更新部分字段:i是原有字段,isUpdated是新增字段
filterArgs = {'date':'2017-10-10'}
updateArgs = {'$set':{'isUpdated':True, 'i':100}}
updateRes = db_coll.update_many(filter = filterArgs, update = updateArgs)
print(f"updateRes: matched_count={updateRes.matched_count}, "
      f"modified_count={updateRes.modified_count} modified_ids={updateRes.upserted_id}")
# 结果:updateRes: matched_count=8, modified_count=8 modified_ids=None

删除记录

删除一条记录

# 示例一:和查询使用的条件一样
queryArgs = {'endDate':'2017-08-28'}
delRecord = db_coll.delete_one(queryArgs)
print(f"delRecord={delRecord.deleted_count}")
# 结果:delRecord=1

批量删除

# 示例二:和查询使用的条件一样
queryArgs = {'i':{'$gt':5, '$lt':8}}
# db_coll.delete_many({})  # 清空数据库
delRecord = db_coll.delete_many(queryArgs)
print(f"delRecord={delRecord.deleted_count}")
# 结果:delRecord=2

转载请注明出处:python使用pymongo读写mongodb

参考链接:
http://www.runoob.com/python3/python-mongodb.html
https://juejin.im/post/5addbd0e518825671f2f62ee
https://blog.csdn.net/zwq912318834/article/details/77689568

猜你喜欢

转载自blog.csdn.net/q383965374/article/details/86015728
今日推荐