2012-05-30 110 views
1

我正在尋找對mongodb執行求和查詢的最有效方法。在mongodb上彙總大量數據

目前我們插入包含各種信息和文檔創建時間的日期時間戳的文檔。

我們需要總結這些數據被視爲在以下幾個方面:通過一天的時間在每個月的日到今年月1-28/31 文件

文檔1-24 文件1-12 按年分類的文檔

這個總結的數據將經常被訪問,因爲我們害怕大量的數據扔到mongo將有經常總結這些數據的問題。

我們認爲或許當一個文件被插入到mongo中,我們有另一個文件包含我們在插入時增加的這些計數。這樣,我們可以迅速提取計數,而不會將每個請求的數據相加。我們擔心的是,這可能不是在mongo中執行此類操作的最有效方式。

有關完成此操作的最佳方法的任何想法?我的開發團隊和我自己對mongodb都是新手,我們希望確保我們不會陷入性能陷阱,並且會累加大量數據。

+0

你似乎有一個可行的解決方案,以及它是否是在* *最有效的方式,它當然應該處理好「求和龐大」的問題。聽起來,低效率的唯一真正潛力是,如果您要添加文檔的速度足夠快,打開,修改和保存「總計」文檔成爲一項重大成本。爲什麼不實施你想出來的東西然後測試? –

+0

這就是我們可能會用到的。不知道是否有更好的方式來處理這種情況 –

+0

此選項將每次讀取訪問成本歸結爲「打開文檔,讀取文檔」。 (在添加「打開文檔,讀取文檔,寫入文檔」到您的添加成本中)。作爲一個對mongodb毫無經驗的人說話,我懷疑這個代價是如此之高。如果它*太高,真正的答案就是採用相同的計劃,但找到可以更快訪問的地方來存儲它。 –

回答

1

Aggregation Framework非常適合這種類型的查詢。
我在下面爲你做了一些例子。

首先,讓我們填充一些文件:

db.myDocumentCollection.insert({ 「日期」,新的日期(01/01/2012' ), 「主題」:「我的標題1 「}); db.myDocumentCollection.insert({「date」:new Date('01/02/2012'),「topic」:「My Title 2」}); db.myDocumentCollection.insert({「date」:new Date('01/02/2012'), 「topic」:「My Title 3」}); db.myDocumentCollection.insert({「date」:new Date('01/02/2012'),「topic」:「My Title 4」}); db.myDocumentCollection.insert({「date」:new Date('01/04/2012'), 「topic」:「My Title 5」}); db.myDocumentCollection.insert({「date」:new Date('01/05/2012'),「topic」:「My Title 6」}); db.myDocumentCollection.insert({「date」:new Date('01/07/2013'), 「topic」:「My Title 7」}); db.myDocumentCollection.insert({「date」:new Date('01/07/2013'),「topic」:「My Title 8」}); db.myDocumentCollection.insert({「date」:new Date('02/07/2013'), 「topic」:「My Title 9」}); db.myDocumentCollection。插入({「date」:new Date('02/08/2013'),「topic」:「My Title 10」});

歸還文件數量由全日期分組

db.myDocumentCollection.group(
{ 
    $keyf : function(doc) { 
     return { "date" : doc.date.getDate()+"/"+doc.date.getMonth()+"/"+doc.date.getFullYear() }; 
    }, 
    initial: {count:0}, 
    reduce: function(obj, prev) { prev.count++; } 
}) 

輸出的每月的一天爲2013年

分組文件

[ 
     { 
       "date" : "1/0/2012", 
       "count" : 1 
     }, 
     { 
       "date" : "2/0/2012", 
       "count" : 3 
     }, 
     { 
       "date" : "4/0/2012", 
       "count" : 1 
     }, 
     { 
       "date" : "5/0/2012", 
       "count" : 1 
     }, 
     { 
       "date" : "7/0/2013", 
       "count" : 2 
     }, 
     { 
       "date" : "7/1/2013", 
       "count" : 1 
     }, 
     { 
       "date" : "8/1/2013", 
       "count" : 1 
     } 
] 

返回數

這可能與您想要執行的查詢類型更相關。
在這裏,我們使用cond僅指定在2013年1月1日之後對文檔進行分組。
您可以在此處使用$gte$lte來執行日期範圍。

db.myDocumentCollection.group(
{ 
    $keyf : function(doc) { 
     return { "date" : doc.date.getDate()+"/"+doc.date.getMonth()}; 
    }, 
    cond: {"date" : {"$gte": new Date('01/01/2013')}}, 
    initial: {count:0}, 
    reduce: function(obj, prev) { prev.count++; } 
}) 

輸出

[ 
     { 
       "date" : "7/0", 
       "count" : 2 
     }, 
     { 
       "date" : "7/1", 
       "count" : 1 
     }, 
     { 
       "date" : "8/1", 
       "count" : 1 
     } 
] 
+0

......直到我發佈我的答案,我才意識到這個問題在五月份被問到了! – Alex