我很有趣,如果有這種情況下特別的東西,但我的鏡頭將是以下。
首先,我沒有看到這裏可以應用多態關聯。你只有一本書可以屬於的對象(用戶)。據我所知,多態是用於連接書籍的幾個dif。對象(例如,用戶,庫,架等)(編輯 - 問題的初始文字提到多態關聯,現在它不)
第二,我不相信有一種方法來緩存計數器在這裏,只要「發佈者#1」是變化的輸入參數,而不是一組預定義和已知的發佈者(少數常量)。
第三,我假設單個發佈者的書籍數量相對有限。因此,即使您的桌子上有數百萬本書,每個發佈商的書籍數量也應該達到數百個。
然後,您可以先查詢所有發佈商的書籍ID,例如,
book_ids = Book.where(:publisher => "Publisher #1").pluck(:id)
,然後查詢中擁有頂級用戶的ID表:
Owns.select("user_id, book_id, count(book_id) as total_owns").where(book_id: book_ids).group(:user_id).order(total_owns: :desc).limit(25)
免責聲明 - 我沒有嘗試聲明中軌控制檯,因爲我沒有定義你的對象。我基於ActiveRecord中的羣組電話docs
編輯。爲了使事情更有效率,您可以嘗試以下操作:
0)爲防萬一,請確保您在兩個外鍵的Owns表上都有索引。
1)使用pluck進行第二個查詢,也不要創建Own對象,儘管由於限制(25)不應該有很大的差異。像這樣:
users_ids = Owns.where(book_id: book_ids).group(:user_id).order("count(*) DESC").limit(25).pluck("user_id")
請參閱this question作爲參考。
2)裝載在一個後續查詢中的所有結果的用戶,而不是N次查詢爲每個用戶
top_users = User.where(:id => users_ids)
3)嘗試在第一階接合用戶表:
owns_res = Owns.includes(:user).select("user_id, book_id, count(book_id) as total_owns").where(book_id: book_ids).group(:user_id).order("total_owns DESC").limit(25)
然後用owns_res 。第一。用戶
這看起來更像是'has_and_belongs_to_many:books'寫在'has_many:books,through:...'方式。也就是說,如果引入where子句(存儲值計算所有書籍,而不是與該發佈者匹配的書籍),則不能使用'counter_cache'。我認爲你應該改變你的問題,專注於通過計數匹配條件的對象進行排序。 – Leito
我對counter_cache的想法很多,實際上我確定,我認爲下面的解決方案實際上是可行的。 – user3141095