MongoDB聚合统计数组内的某个字段的个数并排序
开门见山的说
最近使用mongodb来作为后端数据库,flask来做api服务器,Mongoengine来做ORM,结果遇到挺多的麻烦,归根结底是自己对于mongodb的不够了解导致的,故做个笔记
- 数据类型样式
{
"_id" : ObjectId("5e5a32fe2a89d7c2fc05b9fc"),
"user" : "1",
"score" : 100,
"class" : "A",
}
{
"_id" : ObjectId("5e5a33092a89d7c2fc05ba07"),
"user" : "2",
"score" : 100,
"class" : "A",
}
{
"_id" : ObjectId("5e5a33092a89d7c2fc05ba07"),
"user" : "3",
"score" : 90,
"class" : "B",
}
- $match:过滤数据,返回符合条件的数据
def aggregate():
# 构造过滤条件
match_dic = {"$match": {'class': {'$ne': ''}}}
# 通过Mongoengine的模型获取到文档对象
result = Model._get_collection().aggregate([match_dic])
for one in result:
print(one)
- $group:将过滤后的数据进行分组
def aggregate_match_group(self):
match_dic = {"$match": {'class': {'$ne': ''}}}
# 以分数score来分组,并且统计该分数下共有多少个数
group_dic = {"$group": {
'_id': "$score",
'num': {'$sum': 1}
}}
result = Model._get_collection().aggregate([match_dic, group_dic])
for one in result:
print(one)
- 分组后获取某个字段的总和
def aggregate_match_group(self):
match_dic = {"$match": {'class': {'$ne': ''}}}
# 以分数score来分组,并且统计该分数下的总和
group_dic = {"$group": {
'_id': "$score",
'num': {'$sum': '$score'}
}}
result = Model._get_collection().aggregate([match_dic, group_dic])
for one in result:
print(one)
- 多条件分组,并统计数量
def aggregate_match_group(self):
# 为空表示所有都进行分组
match_dict = {"$match": {}}
# 以分数score来分组,并且统计该分数下的总和
group_dic = {"$group":{"_id":{"年龄":"$age","性别":"$gender"},"人数":{"$sum":1}}}
result = Model._get_collection().aggregate([match_dic, group_dic])
for one in result:
print(one)
{'_id': {'年龄': '100', '性别': '女'}, '人数': 2}
{'_id': {'年龄': '100', '性别': '男'}, '人数': 2}
- 对结果进行排序
def aggregate_match_group(self):
match_dic = {"$match": {'class': {'$ne': ''}}}
# 以分数score来分组,并且统计该分数下的总和
group_dic = {"$group": {
'_id': "$score",
'num': {'$sum': '$score'}
}}
sort_dic = {
"$sort": {
'num': -1
}
}
result = Model._get_collection().aggregate([match_dic, group_dic, sort_dic])
for one in result:
print(one)
管道操作符
常用管道 含义
$group 将collection中的document分组,可用于统计结果
$match 过滤数据,只输出符合结果的文档
$project 修改输入文档的结构(例如重命名,增加、删除字段,创建结算结果等)
$sort 将结果进行排序后输出
$limit 限制管道输出的结果个数
$skip 跳过制定数量的结果,并且返回剩下的结果
$unwind 将数组类型的字段进行拆分
表达式操作符
常用表达式 含义
$sum 计算总和,{$sum: 1}表示返回总和×1的值(即总和的数量),使用{$sum: '$制定字段'}也能直接获取制定字段的值的总和
$avg 平均值
$min min
$max max
$push 将结果文档中插入值到一个数组中
$first 根据文档的排序获取第一个文档数据
$last 同理,获取最后一个数据