2010-08-05 62 views
3

我有一堆帖子裏面有分類標籤。 我想知道每個類別被使用了多少次。散列值遞增值

我正在使用mongodb導軌,但我不認爲我需要從db中獲取類別的出現,所以mongo部分應該沒有關係。

這是我迄今爲止

 
@recent_posts = current_user.recent_posts #returns the 10 most recent posts 
@categories_hash = {'tech' => 0, 'world' => 0, 'entertainment' => 0, 'sports' => 0} 
    @recent_posts do |cat| 
     cat.categories.each do |addCat| 
     @categories_hash.increment(addCat) #obviously this is where I'm having problems 
     end 
    end 
end 

後的結構

{"_id" : ObjectId("idnumber"), "created_at" : "Tue Aug 03...", "categories" :["world", "sports"], "message" : "the text of the post", "poster_id" : ObjectId("idOfUserPoster"), "voters" : []}

我願意就怎麼回事獲得類別的數量的建議,但我會希望最終得到選民的人數,所以在我看來,最好的辦法是增加categories_hash,然後添加elections.length,但是一次只能做一件事,我只是想弄清楚如何增加值在散列。

回答

1

如果您使用的是mongodb,則使用map/reduce操作可以優化標記使用情況。 Mongodb支持使用JavaScript代碼的map/reduce操作。在數據庫服務器上執行Map/Reduce運行,即您的應用程序不必檢索和分析每個文檔(這對於大型集合來說不會很好地擴展)。

作爲示例,下面是我在博客中用於聚合標籤用法(用於在側邊欄中構建標籤雲)的博客中使用的貼圖和縮小函數。在文章收集文件有一個名爲「標籤」鍵,其在每一個用標籤擁有一個字符串數組(標籤)

地圖功能只是發出1來算吧:

function() { 
    if (this.tags) { 
    this.tags.forEach(function (tag) { 
     emit(tag, 1); 
    }); 
    } 
} 

reduce函數總結了罪狀:

function (key, values) { 
    var total = 0; 
    values.forEach(function (v) { 
    total += v; 
    }); 
    return total; 
} 

結果,數據庫返回了每一個標籤和它的使用次數爲價值的關鍵散列。例如:

{ 'rails' => 5, 'ruby' => 12, 'linux' => 3 } 
+0

嗯,我一直在試圖學習和使用map/reduce,我認爲他們可能是一個更簡單的方法來做到這一點與紅寶石,但我會給你的方式一槍,並報告回來。 – pedalpete 2010-08-05 01:41:49

+0

在Ruby中確實比較容易做到,但效率也不高,儘管它對於小型站點來說可能足夠了。我發佈了另一個與您的原始代碼的變體的答案。 – Zargony 2010-08-05 01:50:32

7

如果你不熟悉的map/reduce,你不關心擴大,這不是優雅的地圖/減少,但應該對小網站就足夠了:

@categories_hash = Hash.new(0) 
current_user.recent_posts.each do |post| 
    post.categories.each do |category| 
    @categories_hash[category] += 1 
    end 
end 
+3

如果將第一行更改爲「@categories_hash = Hash.new(0)」,或者像原始問題中那樣對其進行初始化,則還可以刪除「@categories_hash [category] ​​|| = 0」。 – 2010-08-05 02:19:40

+0

你是對的,謝謝。我總是忘記哈希默認值。編輯... – Zargony 2010-08-05 02:32:55