2011-02-11 95 views
7

我有一個大數據集,我想爲用戶清理。該數據從數據庫設置看起來是這樣的:Ruby/Rails - 如何聚合數組中的查詢結果?

ID | project_id | thread_id | action_type |description 
1 | 10   | 30  | comment | yada yada yada yada yada 
1 | 10   | 30  | comment | xxx 
1 | 10   | 30  | comment | yada 313133 
1 | 10   | 33  | comment | fdsdfsdfsdfsdfs 
1 | 10   | 33  | comment | yada yada yada yada yada 
1 | 10   |   | attachment | fddgaasddsadasdsadsa 
1 | 10   |   | attachment | xcvcvxcvxcvxxcvcvxxcv 

現在,當我輸出如上上述,我在同樣的順序查看它,問題是,它是很重複。例如,對於PROJECT_ID 10 & THREAD_ID 30你看:

10 - 30 - yada yada yada yada yada 
10 - 30 - xxxxx 
10 - 30 - yada yada yada yada yada 

我想什麼來學習如何在Ruby中做的,是一些如何創建一個PROJECT_ID和thread_id,則下一個數組,aggreate描述,所以不是輸出是:

10 - 30 
- yada yada yada yada yada 
- xxxxx 
- yada yada yada yada yada 

有關從哪裏開始的建議?這個要求對我來說是新的,所以我會很感激你對你正在考慮解決問題的最好方法的想法。希望這可以通過ruby而不是sql來完成,因爲活動提要可能會隨着事件類型和複雜。

感謝

+0

對於SQL方法使用GROUP BY。對於Ruby方法,使用Enumerable#group_by。檢查文檔。 – tokland 2011-02-11 23:15:19

+1

這些數據採用何種形式?它是ActiveRecord對象還是JSON對象或其他東西? – 2011-02-11 23:16:25

回答

10

使用group_by​​在Ruby或右SQL。在Ruby:

sets = DataSet.all.group_by{ |data| [data.project_id, "-", data.thread_id].join(" ") } 

然後你會得到散列這樣的:

{ "10 - 30" => [#DataSet1, #DataSet2 ...], "10 - 33" => [#DataSet7, #DataSet11 ...] 

您可以在視圖解析:

<% sets.each do |range, datas| %> 
    <p><%= range %>:</p> 
    <% datas.each do |data| %> 
    <p><%= data.description %></p> 
    <% end %> 
<% end %> 

UPD爲each_with_index

<% sets.each_with_index do |datas, index| %> 
    <p><%= datas[0] %>:</p> 
    <% datas[1].each do |data| %> 
    <p><%= data.description %></p> 
    # some stuff with *last* 
    <%= "This is the last one" if data == datas[1].last %> 
    <% end %> 
<% end %> 
0

我遵循使用Enumeratorgroup_by方法的簡單指南。 - 正在操作的數據集應該很小並且是固定的,並且保證隨時間保持恆定。

如:

Fixed data-set: Zip codes, city names  
Dynamic but small data-set: User's hobbies  
Dynamic but paginated data-set: First page of latest orders. 

在我看來您的活動資訊表可以隨時間快速增長。 Activity.all將所有活動加載到內存中。執行此調用會導致內存和網絡成本過高。在沒有條件和分頁的情況下執行all呼叫絕不是一個好主意。如果您當前正在對結果集進行分頁,則當結果集跨越多個頁面時,當前的解決方案將不起作用。您必須使用order子句才能獲得正確的結果集。

這是我會做什麼:

在你的控制器:

# order by ensures that ordering happens at the DB 
# pagination and conditions ensures that data set is small 
activities = Activity.paginate(:order => "project_id, thread_id", :page => #pn) 
@activity_groups = activities.group_by{|a| "#{a.project_id} - #{a.thread_id}"} 

現在,您可以在視圖中使用@activity_groups通過fl00r的建議。