【Python】使用pymongo访问MongoDB的(增/删/改/查)基本操作

1. 环境。

Python:3.6.1
Python IDE:pycharm
系统:win7

2. 简单示例

import pymongo

# mongodb服务的地址和端口号
mongo_url = "127.0.0.1:27017"

# 连接到mongodb,如果参数不填,默认为“localhost:27017”
client = pymongo.MongoClient(mongo_url)

#连接到数据库myDatabase
DATABASE = "myDatabase"
db = client[DATABASE]

#连接到集合(表):myDatabase.myCollection
COLLECTION = "myCollection"
db_coll = db[COLLECTION ]

# 在表myCollection中寻找date字段等于2017-08-29的记录,并将结果按照age从大到小排序
queryArgs = {'date':'2017-08-29'}
search_res = db_coll.find(queryArgs).sort('age',-1)
for record in search_res:
      print(f"_id = {record['_id']}, name = {record['name']}, age = {record['age']}")

3. 要点

  • 针对读操作,进行数据统计,尽量使用多线程,节省时间,只是要注意线程数量,会大量吃内存

4. mongoDB的数据类型

  • MongoDB支持许多数据类型,如下:

    • 字符串 - 用于存储数据的最常用的数据类型。MongoDB中的字符串必须为UTF-8。
    • 整型 - 用于存储数值。 整数可以是32位或64位,具体取决于服务器。
    • 布尔类型 - 用于存储布尔值(true / false)值。
    • 双精度浮点数 - 用于存储浮点值。
    • 最小/最大键 - 用于将值与最小和最大BSON元素进行比较。
    • 数组 - 用于将数组或列表或多个值存储到一个键中。
    • 时间戳 - ctimestamp,当文档被修改或添加时,可以方便地进行录制。
    • 对象 - 用于嵌入式文档。
    • 对象 - 用于嵌入式文档。
    • Null - 用于存储Null值。
    • 符号 - 该数据类型与字符串相同; 但是,通常保留用于使用特定符号类型的语言。
    • 日期 - 用于以UNIX时间格式存储当前日期或时间。您可以通过创建日期对象并将日,月,年的 - 日期进行指定自己需要的日期时间。
    • 对象ID - 用于存储文档的ID。
    • 二进制数据 - 用于存储二进制数据。
    • 代码 - 用于将JavaScript代码存储到文档中。
    • 正则表达式 - 用于存储正则表达式。
  • 不支持的数据类型:

    • python中的集合(set)

5. 对表(集合collection)的操作

import pymongo

# mongodb服务的地址和端口号
mongo_url = "127.0.0.1:27017"

# 连接到mongodb,如果参数不填,默认为“localhost:27017”
client = pymongo.MongoClient(mongo_url)
#连接到数据库myDatabase
DATABASE = "amazon"
db = client[DATABASE]

#连接到集合(表):myDatabase.myCollection
COLLECTION = "galance20170801"
db_coll = db[COLLECTION]

5.1. 查找记录:find

  • (5.1.1)指定返回哪些字段
# 示例一:所有字段
# select * from galance20170801
searchRes = db_coll.find()
# 或者searchRes = db_coll.find({}) 
# 示例二:用字典指定要显示的哪几个字段
# 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'}
  • (5.1.2)指定查询条件
    • (5.1.2.1). 比较:=,!=,>, <, >=, <=
$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}
  • (5.1.2.2). 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}
  • (5.1.2.3). 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}
  • (5.1.2.4). 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}
  • (5.1.2.5). 字段是否存在
# 示例一:字段不存在
# 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}
  • (5.1.2.6). 正则表达式匹配:$regex(SQL:like)
# 示例一:关键字key包含audio子串
# where key like "%audio%"
queryArgs = {'key':{'$regex':'.*audio.*'}}
# 结果:{'_id': 'B01M19FGTZ', 'date': '2017-08-01', 'key': 'pro audio', 'sales': 1}
  • (5.1.2.7). 数组中必须包含元素:$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']}})
  • (5.1.2.8). 按数组大小查询
    • 两个思路:
    • 第一个思路:使用$where(具有很大的灵活性,但是速度会慢一些)
# priceLst是一个数组, 目标是查询 len(priceLst) < 3 
db.getCollection("20180306").find({$where: "this.priceLst.length < 3"})
# 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}})
  • (5.1.3)指定查询条件
    • (5.1.3.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)
  • (5.1.3.2). 排序:sort
# 示例二:按sales降序,rank升序
# select _id,key,sale,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}
  • (5.1.3.3). 统计:count
# 示例三:统计匹配记录总数
# select count(*) from galance20170801 where key = 'speakers'
queryArgs = {'key':'speakers'}
searchResNum = db_coll.find(queryArgs).count()
# 结果:
# 106

5.2. 添加记录

5.2.1. 单条插入

# 示例一:指定 _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')}

5.2.2. 批量插入

# 更高效,但要注意如果指定_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'), ObjectId('59ad3ba851ad3e1104a4de6f'), ObjectId('59ad3ba851ad3e1104a4de70'), ObjectId('59ad3ba851ad3e1104a4de71'), ObjectId('59ad3ba851ad3e1104a4de72'), ObjectId('59ad3ba851ad3e1104a4de73'), ObjectId('59ad3ba851ad3e1104a4de74'), ObjectId('59ad3ba851ad3e1104a4de75'), ObjectId('59ad3ba851ad3e1104a4de76')]

5.3. 修改记录

# 根据筛选条件_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

在这里插入图片描述

5.4. 删除记录

5.4.1. 删除一条记录

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

5.4.2. 批量删除

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

原文作者:Kosmoo
文章来源:https://blog.csdn.net/zwq912318834/article/details/77689568

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值