先用一个python脚本构造一些数据,然后来演示如何使用
#coding=utf-8
'''
Created on 2015-12-28
@author: kwsy
'''
import pymongo
client = pymongo.MongoClient("localhost", 27017)
db = client.testaggregate
coll = db.teacher
t1 = {'name':'li','level':3,'salary':10000,'stus':[{'name':'liA','class':'语文','socre':100},
{'name':'liA','class':'数学','socre':98},
{'name':'liB','class':'语文','socre':95},
{'name':'liB','class':'数学','socre':99}
]}
t2 = {'name':'liu','level':2,'salary':15000,'stus':[{'name':'liuA','class':'语文','socre':80},
{'name':'liuA','class':'数学','socre':60},
{'name':'liuB','class':'语文','socre':96},
{'name':'liuB','class':'数学','socre':90}
]}
t3 = {'name':'he','level':5,'salary':20000,'stus':[{'name':'heA','class':'语文','socre':96},
{'name':'heA','class':'数学','socre':80},
{'name':'heB','class':'语文','socre':94},
{'name':'heB','class':'数学','socre':66}
]}
t4 = {'name':'black','level':5,'salary':25000,'stus':[{'name':'blackA','class':'语文','socre':95},
{'name':'blackA','class':'数学','socre':86},
{'name':'blackB','class':'语文','socre':66},
{'name':'blackB','class':'数学','socre':80}
]}
coll.insert_one(t1)
coll.insert_one(t2)
coll.insert_one(t3)
coll.insert_one(t4)
下面的脚本演示如何使用
#coding=utf-8
'''
Created on 2015-12-28
将学生的成绩作为内嵌文档放到老师的信息文档中不是一种好的做法
在这个脚本里这样做,只是为了更形象的解释聚合的功能和效果
@author: kwsy
'''
import pymongo
client = pymongo.MongoClient("localhost", 27017)
db = client.testaggregate
coll = db.teacher
#统计所有老师的工资总和,统计的是有老师,所以_id 为空
print(u'统计所有老师的工资总和')
data = coll.aggregate([{'$group':{'_id':'','count':{'$sum':1},'total_salary':{'$sum':'$salary'},'avg':{'$avg':"$salary"}}}])
data = list(data)
print(data[0])
#按照老师的级别统计工资和,以老师级别统计,_id就赋值为$level
print(u'统计不同级别的工资和')
data = list(coll.aggregate([{'$group':{'_id':'$level','count':{'$sum':1},'total_salary':{'$sum':'$salary'},'avg':{'$avg':"$salary"}}}]))
for t in data:
print(t)
#下面的语句等效于 find({'name':'black'})
pipeline = [{'$match':{'name':'black'}}]
data = list(coll.aggregate(pipeline))
print(data[0])
#使用了$unwind 使得内嵌文档升级到上一级
pipeline = [{'$match':{'name':'black'}},{'$unwind':'$stus'}]
data = list(coll.aggregate(pipeline))
for t in data:
print(t)
# 升级后又进行了一次match筛选,只筛选分数大于80的内嵌文档
pipeline = [{'$match':{'name':'black'}},{'$unwind':'$stus'},{'$match':{'stus.socre':{'$gt':80}}}]
data = list(coll.aggregate(pipeline))
for t in data:
print(t)
#保持原来的内嵌形式不变
print(u'保持原来的内嵌形式不变')
pipeline = [{'$match':{'name':'black'}},{'$unwind':'$stus'},
{'$match':{'stus.socre':{'$gt':80}}},{'$group':{'_id':'$_id','level':{'$first':'$level'},'stus':{'$push':'$stus'}}}]
data = list(coll.aggregate(pipeline))
for t in data:
print(t)
#所有学生的语文成绩
print(u'所有学生的语文成绩')
pipeline = [{'$unwind':'$stus'},{'$match':{'stus.class':'语文'}}]
data = list(coll.aggregate(pipeline))
for t in data:
print(t)
#所有学生的语文成绩排序取前三个
print(u'所有学生的语文成绩排序取前三个')
pipeline = [{'$unwind':'$stus'},{'$match':{'stus.class':'语文'}},{'$sort':{'stus.socre':-1}},{'$limit': 3 }]
data = list(coll.aggregate(pipeline))
for t in data:
print(t)
#某个老师的学生中语文成绩最大值
print(u'某个老师的学生中语文成绩最大值')
pipeline = [{'$match':{'name':'black'}},{'$unwind':'$stus'},
{'$match':{'stus.class':'语文'}},{'$sort':{'stus.socre':-1}},{'$limit': 1 }]
data = list(coll.aggregate(pipeline))
for t in data:
print(t)