先用一個python指令碼構造一些資料,然後來示範如何使用
#coding=utf-8'''Created on 2015-12-28@author: kwsy'''import pymongoclient = pymongo.MongoClient("localhost", 27017)db = client.testaggregatecoll = db.teachert1 = {'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 pymongoclient = pymongo.MongoClient("localhost", 27017)db = client.testaggregatecoll = 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就賦值為$levelprint(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)