2011-05-08 7 views
2

Ruby on Rails를 사용하고 있습니다. 나는 가장 인기있는 주문 라인을 어떻게 계산합니까? (또는 비슷한 주문/주문 라인 db 배열)

class Order 
    has_many :order_lines 
end 

class OrderLines 
    belongs_to :order 
    belongs_to :product 
end 

class Product 
    has_many :order_lines 
end 

가 (크게 내 진짜 모델 단순화!) 즉, 정상적인 주문/주문 라인의 배열에 맞게 모델의 몇 가지를 가지고

그것은 가장 인기있는 개별 제품을 해결하기 위해 매우 간단의 주문을 통해 하지만 루비 - 푸 (ruby-fu)가 주문한 제품 중 가장 인기있는 조합을 계산하는 데 사용할 수있는 마법의 마술은 무엇일까?

답변

0

팁 digitalross에 감사드립니다. 나는 외부 솔루션 아이디어를 따라 다음과 같은 작업을 수행했습니다. 카운터를 저장하는 대신 개별 order_combos 레코드를 보관하므로 제안과 약간 다릅니다. 따라서 날짜순으로 쿼리 할 수도 있습니다. 지난주 가장 인기있는 톱 10 주문.

주문 항목 목록을 쉼표로 구분 된 문자열로 변환하는 순서대로 메소드를 만들었습니다.

def to_s 
    order_lines.sort.map { |ol| ol.id }.join(",") 
end 

그런 다음 필터를 추가하여 주문할 때마다 콤보가 만들어집니다.

after_save :create_order_combo 

def create_order_combo 
    oc = OrderCombo.create(:user => user, :combo => self.to_s) 
end 

마지막으로 내 OrderCombo 클래스는 다음과 같습니다. 또한 캐시 된 버전의 메서드가 포함되어 있습니다.

class OrderCombo 

    belongs_to :user 

    scope :by_user, lambda{ |user| where(:user_id => user.id) } 

    def self.top_n_orders_by_user(user,count=10) 
    OrderCombo.by_user(user).count(:group => :combo).sort { |a,b| a[1] <=> b[1] }.reverse[0..count-1] 
    end 

    def self.cached_top_orders_by_user(user,count=10) 
    Rails.cache.fetch("order_combo_#{user.id.to_s}_#{count.to_s}", :expiry => 10.minutes) { OrderCombo.top_n_orders_by_user(user, count) } 
    end 
end 

누군가 주문한 항목 중 더 많은 항목을 주문하면 인기가 높아지지 않기 때문에 완벽하지는 않습니다.

0

나의 제안

건배, 그램 배열 각 주문에 대한 Product.id 번호 을 만드는 것입니다 그리고 당신은 자연의 규모를 고려할 필요가

h = Hash.new(0) 
# for each a 
    h[a.sort.hash] += 1 

에 해당 할 당신의 수술과 얼마나 많이 당신이 결과를 대략 기꺼이합니다.

외부 솔루션

해시하여 "조합"모델과 인덱스 테이블을 만든 다음 각 주문은 카운터 필드를 증가 할 수있다. 다른 필드는 해시 값이 참조한 조합을 정확하게 기록합니다.

인 - 메모리 솔루션

지난 100 개 주문을보고 당신이 그것을 필요로 할 때 메모리에 주문 인기를 다시 계산. Hash#sort은 인기있는 해시 목록을 제공합니다. 순서 조합이 계산되는 것을 기억한 복합 객체를 만들거나 해시 값을 찾기 위해 원본 데이터를 스캔 할 수 있습니다.

관련 문제