2012-10-29 41 views
2

我目前使用Python來構建我的許多結果而不是MongoDB本身。我試圖讓我的腦袋聚集在一起,但我掙扎了一下。這是我目前正在做的事情的一個例子,這可能會更好地被MongoDB處理。如何在這個例子中使用Mongodb Aggregation?

我有一個程序集和一個集的集合。每個程序都有與之相關的劇集列表(DBRefs)。 (劇集存儲在他們自己的收藏中,因爲節目和劇集都非常複雜和深入,因此嵌入是不切實際的)。每集有一個持續時間(浮動)。如果我想找到一個程序的平均發作持續期時,我這樣做:

episodes = list(db.Episodes.find({'Program':DBRef('Programs',ObjectId(...))})) 
durations = set(e['Duration'] for e in episodes if e['Duration'] > 0) 
avg_mins = int(sum(durations)/len(durations)/60 

這是當一個程序有超過1000集相當緩慢。有什麼辦法可以在MongoDB中完成嗎?

這是Mongo shell格式的一些示例數據。有三集屬於同一個節目。我如何計算該節目的平均劇集持續時間?

> db.Episodes.find({ 
    '_Program':DBRef('Programs',ObjectId('4ec634fbf4c4005664000313'))}, 
    {'_Program':1,'Duration':1}).limit(3) 

{ 
    "_id" : ObjectId("506c15cbf4c4005f9c40f830"), 
    "Duration" : 1643.856, 
    "_Program" : DBRef("Programs", ObjectId("4ec634fbf4c4005664000313")) 
} 
{ 
    "_id" : ObjectId("506c15d3f4c4005f9c40f8cf"), 
    "Duration" : 1598.088, 
    "_Program" : DBRef("Programs", ObjectId("4ec634fbf4c4005664000313")) 
} 
{ 
    "_id" : ObjectId("506c15caf4c4005f9c40f80e"), 
    "_Program" : DBRef("Programs", ObjectId("4ec634fbf4c4005664000313")), 
    "Duration" : 1667.04 
} 
+0

你是怎麼試圖做w /聚合框架?看起來你想要通過programId對劇集進行分組,並找到只匹配持續時間> 0的平均持續時間? –

+0

我認爲你是對的,但我並不真正理解語法。謹慎地爲我拼出來? – MFB

+0

你可以以shell格式顯示你的數據庫的樣本和所需的輸出嗎?有人可能能夠幫助你組建一個自動對焦查詢。 – cirrus

回答

6

我想明白了,相比之下,將它全部引入Python是相當快的。

p = db.Programs.find_one({'Title':'...'}) 

pipe = [ 
     {'$match':{'_Program':DBRef('Programs',p['_id']),'Duration':{'$gt':0}}}, 
     {'$group':{'_id':'$_Program', 'AverageDuration':{'$avg':'$Duration'}}} 
     ] 

eps = db.Episodes.aggregate(pipeline=pipe) 

print eps['result'] 
+0

當我嘗試做類似的事情時出現以下錯誤: aggregate()爲關鍵字參數'pipeline'獲取了多個值 任何指針? – qre0ct

相關問題