当前位置:   article > 正文

Mongdb篇三。 用Python代码实现Mongdb数据库的增删查改、集合管道示例,超详细,全部用实例print大法演示功能通俗易懂。学pymongo库看一篇就够_pycharm操作mongodb数据库

pycharm操作mongodb数据库

⭐ 简介:大家好,我是zy阿二,我是一名对知识充满渴望的自由职业者。
☘️ 最近我沉溺于Python的学习中。你所看到的是我的学习笔记。
❤️ 如果对你有帮助,请关注我,让我们共同进步。有不足之处请留言指正!

系列文章传送门,建议循序渐进的学习:

1. MongoDB入门安装 & 用Pycharm可视化链接MongoDB。入门篇

2. 用Pycharm熟悉Mongodb命令,增删改查基本操作。基础篇

3. 用pymongo库实现Python对MongoDB的深度操作。毕业篇【本文】

1. 先看下 MongoDB 命令和 pymongo语句的区别:

作用MongoDBpymongo
写入一行insertOne({})insert_one({})
写入多行insertMany([{},{}],{}])insert_many([{},{},{}])
查询单一结果findOne({})find_one({})
查询全部结果find({})find({})
聚合管道查询aggregate({})aggregate({})
删除一行deleteOne({})delete_one({})
删除多行deleteMany({})delete_many({})
修改一行数据updateOne({},{$:{}})update_one({},{$:{}})
修改多行数据updateMany({},{$:{}})update_many({},{$:{}})

pymongo中所有命令结构和Mongodb语句几乎是一样的。
区别1. 显而易见的不同是MongoDB命令的大写字母改成了下划线加小写。
区别2. pymongo中key、运算符、修改器、逻辑判断符都必须加引号。(即:类型必须是str)
区别3. 在MongoDB语句中删除一个表的数据需要写db.testcoll.deleteMany({}) 而在Python中由于事先创建了collection对象,所以在执行命令时只需要写 collection对象名.delete_many({})


阅读正文前, 先安装,导入pymongo库
pip install pymongo
import pymongo


一、Python -> Pymongo -> MongoDB

✅1. 连接MongoDB,pymongo.MongoClien()

import pymongo
# 写法1,连接本机MongoDB
client = pymongo.MongoClient(host='localhost', port=27017)  
    
# 写法2,效果相同
client = pymongo.MongoClient("mongodb://localhost:27017/") 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

附:client.list_database_names() 返回一个列表,包含当前所有数据库名字。


✅2. 连接数据库(database)& 集合(collection)

# 写法1。选择一个数据库,再连其中的集合
db = client.数据库名  # 需要手动提前创建好数据库
coll = db.集合名  # 集合不需要提前创建

#  写法2。 此写法是避免和Python关键词冲突,  效果相同。
db = client['数据库名']
coll = db['集合名']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

附:db.list_collection_names() 返回一个数据库中集合的名字。


✅3. 检查数据库、集合是否存在

# 先做判断、再用一行代码直接连接集合,去掉中间环节。
if "数据库名" in client.list_database_names() and "集合名" in client.list_database_names():
	coll =client['数据库名']['集合名']
  • 1
  • 2
  • 3

附: 返回一个列表,包含所有集合的名字。coll.find() 返回集合中的所有文档。


增:


✅4.0 写入一行数据,insert_one({})

coll =client['数据库名']['集合名']
# insert_one() 方法插入数据
result= coll.insert_one({'name':'张三','age':20,'like':['看电视','玩手机','读书'],})
# 返回:result = <pymongo.results.InsertOneResult object at 0x000001A67ABFB010>
# 是不可迭代对象,无法用for遍历
  • 1
  • 2
  • 3
  • 4
  • 5

附:print(result.inserted_id)方法可以得到上次写入数据的_id


✅4.1 写入多行数据,insert_many([])

many = [
    {"name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {"name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {"name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {"name": "赵飞机", "en": "zfj", "age": 12, 'like': ['打游戏', '玩手机', '跳舞']},
    {"name": "周白鸡", "en": "zbj", "age": 15, 'like': ['逛街', '玩手机', '睡觉']},
    {"name": "郭娃子", "en": "gwz", "age": 20, 'like': ['看电视', '玩手机', '弹琴']}
]
result = coll.insert_many(many)  
# 打印被插入文档的  _id 值列表:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

附:print(result.inserted_ids)方法返回InsertManyResult对象,包含_id的列表

返回的数据结构:
[ObjectId(‘63241ee9bd28e97660c51bba’),ObjectId(‘63241ee9bd28e97660c51bbb’)…]

✅4.2 写入时自定义 _id

请记住_id的值必须是唯一的。不建议自定义_id

coll.insert_one({'_id':1,"name": "张三", "en": "zhangsan"})
  • 1


删:


✅5.0 删除,delete_one({}),delete_many({}),

# 删除文档中的第一行数据。 {} 必须写,格式就这样。
coll.delete_one({})
# 删除全部
coll.delete_many({})
  • 1
  • 2
  • 3
  • 4

✅5.1 多条件判断删除

# 加条件删除,{}内写条件。 删除一行 age = 10 的文档
coll.delete_one({'age': 10})
# 删除所有 age = 10 的文档
coll.delete_many({'age': 10})

# 删除所有age=20,name=郭娃子的所有数据
coll.delete_many({'age': 20, 'name': "郭娃子"})

# 删除所有age > 11 或者 _id < 2
coll.delete_many({'$or': [{'age': {'$lt': 11}, '_id': {'$gt': 2}}]})

# 用正则表达式删除en列中开头字母是z的所有行
coll.delete_many({'en': {'$regex': '^z'}})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

注:更多运算符,在文章末尾有表格详细描述

✅5.2 去重(删除重复,保留一项)

在mongodb中去重是一件比较麻烦的事情,没有一个可以直接去重的方法。所以最好在写入数据的时候,用update在条件中加入判断保证唯一再写入。

# distinct可以得到指定列中的唯一值,即从重复内容中提取不重复的内容
# 返回list,在通过遍历每一个值去判断数量,再删掉多余的
# 如下示例代码,取 name列中的唯一值,遍历每一个值,判断数量,再删掉数量大于2的数据,保留一行

# 获取name列所有的唯一值,返回list,并遍历
for i in coll.distinct('name'): 
	 # 统计i出现的次数
	count = coll.count_documents({'name': i})
	# 判断如果i 出现的次数大于1,那么
	if count > 1: 
		# 那么就循环 count-1次
		for i in range(count-1): 
			# 执行删除 i的操作
    		coll.delete_one({'name': i}) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14


查:


✅6.0 查询,返回一行。find_one()

# 返回的第一个匹配项。字典类型。包含_id开头的所有数据
result = coll.find_one()
print(result)
  • 1
  • 2
  • 3


✅6.1 查询,返回多行。find()

# 返回的集合中的全部数据。可迭代对象。需要用for遍历。
for i in coll.find():
	print(i)
  • 1
  • 2
  • 3


✅6.2 条件筛选返回的字段

以find()为示例,find_one()的格式是相同的。在上一篇文章中我有详细介绍过MongoDB语句的格式。在用Python时,同样遵循这个格式。

# 第一个{} 写条件。为空也要写一个空的{}
# 第二个{} 写需要显示的列名,"_id": 0 表示不返回_id的值,默认为1。"name": 1, "age": 1代表返回name和age列的数据
for i in coll.find({},{ "_id": 0, "name": 1, "age": 1 }):
  print(i)
 

# 先写一组演示数据
coll.insert_many([
    {"name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {"name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {"name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {"name": "赵飞机", "en": "zfj", "age": 12, 'like': ['打游戏', '玩手机', '跳舞']},
    {"name": "周白鸡", "en": "zbj", "age": 15, 'like': ['逛街', '玩手机', '睡觉']},
    {"name": "郭娃子", "en": "gwz", "age": 20, 'like': ['看电视', '玩手机', '弹琴']}
])
# 只like列,like列的value在MongoDB中的数据类型为:Array
# 在Python中like列的value的类型为:list
# 当我们需要like中的某一个索引的数据时,需要用Python方法取索引。
for i in coll.find({}, {"_id": 0, "like": 1}):
    print(i)
    print(i['like'][0]) 

# 或者使用聚合管道查询中的 $unwind 方法,可以把数组拆分出来。
for i in coll.aggregate([{'$unwind': {'path': "$like"}}]):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25


✅6.3 查询子集的方法

# 先写一组演示数据,我们需要查询张狗子like的b的value
many = [
    {'_id': 1, "name": "张狗子", 'like': {'a': '打游戏', 'b': '玩手机', 'c': '看书'}},
    {'_id': 2, "name": "李拐八", 'like': {'a': '看电视', 'b': '玩手机', 'c': '跑步'}},
    {'_id': 3, "name": "王九蛋", 'like': {'a': '羊了个羊', 'b': '玩手机', 'c': '放风筝'}},
]

# 用  .   来链接
print(coll.find_one({'name': '张狗子'}, {'_id': 0, 'like.b': 1}))
print(coll.find_one({'name': '张狗子'}, {'_id': 0, 'like.b': 1})['like']['b'])

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11


✅6.4 增加条件筛选返回的字段

# 先写一组演示数据,注:如果您当前文档中已有相同_id的数据时,写入如下示例数据时会报错。
coll.insert_many([
    {'_id': 1, "name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {'_id': 2, "name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {'_id': 3, "name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {'_id': 4, "name": "赵飞机", "en": "zfj", "age": 12, 'like': ['打游戏', '玩手机', '跳舞']},
    {'_id': 5, "name": "周白鸡", "en": "zbj", "age": 15, 'like': ['逛街', '玩手机', '睡觉']},
    {'_id': 6, "name": "郭娃子", "en": "gwz", "age": 20, 'like': ['看电视', '玩手机', '弹琴']}
])
# 查询 2 < _id < 5 的文档数据,但是排除like列
for i in coll.find({'_id': {'$gt': 2, '$lt': 5}}, {"like": 0}):
    print(i)

print('-' * 50)  # 打印分割线

# 返回_id中包含3 或者 4 的文档数据,但是排除like列
for i in coll.find({'_id': {'$in': [3, 4]}}, {"like": 0}):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
# 第一个{}, 空代表无筛选条件
# 第二个{},返回不包含like列的其他内容
# limit=5 ,表示最多返回5行数据
# sort=[("age", 1)],表示按age列数据升序排序 -1 代表降序
for i in coll.find({}, {"like": 0}, limit=5, sort=[("age", 1)]):
    print(i)
    
# 第二种写法,效果是相同的。
for i in coll.find(projection={"like": 0}).limit(5).sort("age", 1):
    print(i)

# 第三种写法, 按age升序查询最近3条文档数据.  推荐写法.
# sort("age",-1) 为降序, 默认不写就是升序. 
for i in coll.find({}, {"like": 0}).limit(5).sort("age"):
    print(i)
    
# skip(2)忽略前2行数据从第三行开始查询,limit(2)返回最多2行数据
for i in coll.find({}).skip(2).limit(2):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19


✅6.5 统计行数

# 不带条件的统计总行数方法
print(coll.estimated_document_count())

# 带条件的统计行数方法
print(coll.count_documents({'name': {'$ne': ''}}))
  • 1
  • 2
  • 3
  • 4
  • 5


✅6.6 查重 coll.distinct()

# 先写一组演示数据
coll.insert_many([
    {"name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {"name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {"name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {"name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {"name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {"name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
])
# 按 name 列返回不重复的value。类型list
print(coll.distinct('name'))

# 多条件用 and 、 or 连接
print(coll.distinct('name' and 'en'))

# distinct方法只能查重,无法删除重复
# distinct返回的是一个list,所以通过for循环即可去重
for i in coll.distinct('name'):
    print(coll.delete_one({'name': i}))

# 通过gruop函数对 age 相同的分组,再对组内有重复name的数据进行删除
for i in coll.aggregate([{'$group': {'_id': "$age", }}]).distinct('name'):
    print(coll.delete_one({'好友ID': i}))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23


改 :


✅7.0 修改字段,update_one({},{$:{}}),update_many({},{$:{}})

update_one({},{$:{}}) 修改一行数据
update_many({},{$:{}}) 同时修改多行数据
第一个{} 写条件, 第二个{$:{}} 写修改器+修改的内容。

修改器作用
$set修改列值
$inc递增
$rename重命名列
$unset删除列
# 先写一组演示数据,注:如果您当前文档中已有相同_id的数据时,写入如下示例数据时会报错。
coll.insert_many([
    {'_id': 1, "name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {'_id': 2, "name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {'_id': 3, "name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {'_id': 4, "name": "赵飞机", "en": "zfj", "age": 12, 'like': ['打游戏', '玩手机', '跳舞']},
    {'_id': 5, "name": "周白鸡", "en": "zbj", "age": 15, 'like': ['逛街', '玩手机', '睡觉']},
    {'_id': 6, "name": "郭娃子", "en": "gwz", "age": 20, 'like': ['看电视', '玩手机', '弹琴']}
])

# 将age < 20 的所有数据,再原数据的基础上 +5
coll.update_many({'age': {'$lt': 20}}, {'$inc': {'age': 5}})


# 将age > 18 的所有数据,再原数据的基础上增加一列note,并写入value'长大了'
coll.update_many({'age': {'$gt': 18}}, {'$set': {'note': '长大了'}})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16


✅7.1 修改like列中的字段

  1. 先用查询方法得到like列的数据
  2. 再通过Python自带方法处理list , 将 ‘玩手机’ 改成 ‘好好学习’
  3. 再将修改后的结果用update方法重新修改到like列中
# 先写一组演示数据,注:如果您当前文档中已有相同_id的数据时,写入如下示例数据时会报错。
coll.insert_many([
    {'_id': 1, "name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {'_id': 2, "name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {'_id': 3, "name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {'_id': 4, "name": "赵飞机", "en": "zfj", "age": 12, 'like': ['打游戏', '玩手机', '跳舞']},
    {'_id': 5, "name": "周白鸡", "en": "zbj", "age": 15, 'like': ['逛街', '玩手机', '睡觉']},
    {'_id': 6, "name": "郭娃子", "en": "gwz", "age": 20, 'like': ['看电视', '玩手机', '弹琴']}
])

# 主要是处理数据的过程套的有点多.
# i 返回的是一个 dict 包含了 "_id" 和 "like" 2个key
# 所以 i['like'] 才是我们需要修改的value 

for i in coll.find({}, {'like'}):
    if '玩手机' in i['like']:
        i['like'][i['like'].index('玩手机')] = '好好学习'
        coll.update_one({'_id': i['_id']}, {'$set': {'like': i["like"]}})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18


✅7.2 判断唯一再写入

在上面我们提到了,使用MongoDB删除重复数据是一件麻烦的事情。所以在写入前做判断是非常有必要的。

# 用 update_one 代替 intsert_one ,在写入数据时做判断后,再写入。
# upsert=True 数据库中没有时,就执行插入
coll.update_one({'name':'xxx',{'$setOnInsert':{'name':'xxx'}}},upsert=True})
  • 1
  • 2
  • 3


✅8.0 集合管道查询 aggregate([{}])

管道命令操作符
命令作用
$match匹配特定条件的文档
$project提取需要的字段
$group按有相同值的列分组
$unwind对数组类型拆分并逐一返回
$srot排序,1正序,-1倒序
$limit限制最大返回行
$skip需要忽略前几行

每个管道操作符都会接受一连串文档,前一个操作符转换后的文档传递给下一个操作符,最后一个操作符的结果集返回给客户端;另外,不同的管道操作符可以按照任何顺序组合在一起使用,而且可以重复使用多次;下面介绍下各个管道操作符。

1. $match 筛选操作符

$match 可以使用常规的查询操作符,例如$gt$in等,但是不能使用地理空间操作符
$match 应该放在管道的最前位置,一是可以快速将不需要的文档过滤掉;二是可以使用集合已有的索引;

# 先写一组演示数据,注:如果您当前文档中已有相同_id的数据时,写入如下示例数据时会报错。
coll.insert_many([
    {'_id': 1, "name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {'_id': 2, "name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {'_id': 3, "name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {'_id': 4, "name": "赵飞机", "en": "zfj", "age": 12, 'like': ['打游戏', '玩手机', '跳舞']},
    {'_id': 5, "name": "周白鸡", "en": "zbj", "age": 15, 'like': ['逛街', '玩手机', '睡觉']},
    {'_id': 6, "name": "郭娃子", "en": "gwz", "age": 20, 'like': ['看电视', '玩手机', '弹琴']}
])

# 1. 条件过滤。 查询满足age < 16 的数据
for i in coll.aggregate([{'$match': {"age": {'$lt': 16}}}]):
    print(i)

# 2. 双管道过滤。 第一个管道返回满足age < 16的子文档 
# 2.1 在第一个管道的子文档中再筛选名字中包含张 或 李 的文档
for i in coll.aggregate([{'$match': {"age": {'$lt': 16}}}, {'$match': {'name': {'$regex': '[张李]'}}}]):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2. $project 筛选操作符

$project可以从子文档提取字段、可以重命名字段、可以对字段使用表达式操作等;

#  第一个管道依旧是返回满足age < 16的子文档 ,
#  在第一个管道的子文档中设置只返回name列的文档
for i in coll.aggregate([{'$match': {"age": {'$lt': 16}}}, {'$project': {'name': 1, '_id': 0}}]):
    print(i)


#  返回显示name列,并额外新增一列note,不改变原有数据
for i in coll.aggregate([{'$project': {'note': '备注', 'name': 1}}]):
    print(i)


# 先来一组示例数据
coll.insert_many([
    {'name': '张狗子', 'en': 'zgd', 'score': 10, 'score2': 10},
    {'name': '李拐八', 'en': 'lgb', 'score': 11, 'score2': 10},
    {'name': '王九蛋', 'en': 'wjd', 'score': 9, 'score2': 10},
    {'name': '赵飞机', 'en': 'zfj', 'score': 12, 'score2': 10},
    {'name': '周白鸡', 'en': 'zbj', 'score': 15, 'score2': 10},
    {'name': '郭爸爸', 'en': 'gwz', 'score': 20, 'score2': 10},
])
# 将文档原数据中的score 和 score2 相加,返回新的一列 totalscore (不改变原文档)
for i in coll.aggregate([{'$project': {'totalPay': {'$add': ['$score', '$score2']}}}]):
    print(i)

# 字符串数据中相加,返回新的一列 nameplus(不改变原文档)
for i in coll.aggregate([{'$project': {'nameplus': {'$concat': ['$name', '$en']}}}]):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3. $group 分组操作符

$group对有相同数据的字段进行分组

# 一组示例数据
coll.insert_many([
    {'gender': '男', 'name': '张狗子', 'en': 'zgd', 'score': 10},
    {'gender': '男', 'name': '李拐八', 'en': 'lgb', 'score': 11},
    {'gender': '女', 'name': '王九蛋', 'en': 'wjd', 'score': 9},
    {'gender': '男', 'name': '赵飞机', 'en': 'zfj', 'score': 12},
    {'gender': '女', 'name': '周白鸡', 'en': 'zbj', 'score': 15},
    {'gender': '男', 'name': '郭爸爸', 'en': 'gwz', 'score': 20},
])
# 分组,将文档数据按gender分成男女两组,并计算他们的平均score,显示为新列scoreavg
for i in coll.aggregate(
        [{'$group': {'_id': "$gender", 'scoreavg': {'$avg': '$score'}}}]):
    print(i)

# 分组,将文档数据按gender分成男女两组,并将她们的name插入到新列namelist中返回
for i in coll.aggregate(
        [{'$group': {'_id': "$gender", 'namelist': {'$push': '$name'}}}]):
    print(i)


# 分组,将文档数据按gender分成男女两组,并按返回对应gender的name数量。
for i in coll.aggregate([{'$group': {'_id': '$gender', 'name': {'$push': '$$ROOT'}}}]):
    print(i)


# 当我们想要知道总行数时,就可以将所有的数据分成一组然后统计某一列的总数。
for i in coll.aggregate([{'$group': {'_id': 'null', 'name': {'$sum': 1}}}]):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

$$ROOT方法可以将查询的文档结果放入一个数组中,包含对应行的全部信息。
注意 ROOT必须大写否则会报错。

# 当你需要每个分组中成员的完整数据时。
for i in coll.aggregate([{'$group': {'_id': '$gender', 'name': {'$push': '$$ROOT'}}}]):
    print(i)
  • 1
  • 2
  • 3

4. $sort 排序
$limit 限制最大行
$skip 忽略行

# 一组示例代码
coll.insert_many([
    {'gender': '男', 'name': '张狗子', 'en': 'zgd', 'score': 10},
    {'gender': '男', 'name': '李拐八', 'en': 'lgb', 'score': 11},
    {'gender': '女', 'name': '王九蛋', 'en': 'wjd', 'score': 9},
    {'gender': '男', 'name': '赵飞机', 'en': 'zfj', 'score': 12},
    {'gender': '女', 'name': '周白鸡', 'en': 'zbj', 'score': 15},
    {'gender': '男', 'name': '郭爸爸', 'en': 'gwz', 'score': 20},
])
# 按 score 降序返回结果。 不写或者写 1 为升序
for i in coll.aggregate([{'$sort': {'score': -1}}]):
    print(i)


# 分组统计男女的成员数量存入counter列,并按counter升序排序
for i in coll.aggregate([{'$group': {'_id': "$gender", 'counter': {'$sum': 1}}}, {'$sort': {'counter': 1}}]):
    print(i)

# 查询score不等于0的所有数据,并且忽略前2条,并最大返回2条。
# 注意,按从左到右的顺序执行每一个管道命令的,如果你写{'$limit': 2},{'$skip': 2}那么永远不会有结果,因为你限制了最大输出2条,然后再限制了忽略前2条,所以不会有结果。
for i in coll.aggregate([{'$match': {'score': {'$ne': 0}}}, {'$skip': 2},{'$limit': 2}]):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

5. $unwindt 拆分数组

# 先写一组演示数据
coll.insert_many([
    {"name": "张狗子", "en": "zgd", "age": 10, 'like': ['打游戏', '玩手机', '看书']},
    {"name": "李拐八", "en": "lgb", "age": 11, 'like': ['看电视', '玩手机', '画画']},
    {"name": "王九蛋", "en": "wjd", "age": 9, 'like': ['刷抖音', '玩手机', '唱歌']},
    {"name": "赵飞机", "en": "zfj", "age": 12, 'like': ['打游戏', '玩手机', '跳舞']},
    {"name": "周白鸡", "en": "zbj", "age": 15, 'like': ['逛街', '玩手机', '睡觉']},
    {"name": "郭娃子", "en": "gwz", "age": 20, 'like': ['看电视', '玩手机', '弹琴']}
])

# $unwind 方法,可以把文档数据是数组的内容逐一拆分返回。
for i in coll.aggregate([{'$unwind': {'path': "$like"}}]):
    print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

6. 使用聚合方法去重


  • 1
'
运行

条件运算符

逻辑判断符格式注释
$or$or:[ { key: value} , { key: value } ]满足多个条件中的一个
$and$and:[ { key: value } , { key: value } ]同时满足多个条件,不过{key:value,key:value}的格式也是and逻辑
$not$not { key: value }反向匹配,否定逻辑
$nor$nor{ key: value }nor = not or,反向匹配多个条件中的某一个
运算符格式作用
{ key: value }(冒号)等于
$ltkey:{ $lt: value }小于
$lte key:{ $lte: value }小于等于
$gtkey:{ $gt: value }大于
$gtekey:{ $gte: value }大于等于
$nekey:{ $ne: value }不等于
$inkey:{ $in: [1,10]}包含
$nin key:{ $nin: [1,10]}不包含
$existskey:{ $exists: bool}是否存在,bool,{$exists:true}
$regex key: {$regex:‘.*?’}匹配正则表达式
$type key: {$type:int}判断数据类型
$add$add: [$key1, $key2]加,将key1 + key2
$subtract$subtract: [$key1, $key2]减,返回key1 - key2
$multiply$multiply: [$key1, $key2]乘,返回key1 × key2
$divide$divide: [$key1, $key2]除,返回key1 ÷ key2
$avg{$avg: $key}平均值,返回key列的平均值
$mod key: {$mod:[2,0]}取余,返回key列value ÷ 2 = 0 的文档
$min$min: $key最小值,返回key列中的最小值
$max$max: $key最大值,返回key列中的最大值
$pushkey1:{$push: key2}插入,将key2的值插入到key1中返回list

日期表达式$year$month$hour等等,需要注意的是只能对日期类型的字段进行日期操作;
字符串表达式$substr截取字符串、$concat连接、$toLower转小写

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/878432
推荐阅读
相关标签
  

闽ICP备14008679号