[英]Matching algorithm in Ruby on Rails
在我的Rails項目中,我需要將Profiles與一組特定條件匹配。 我當前的設置是每個配置文件都有一組評估,其中最新的評估是活動的。 每個評估由一組屬性組成,這些屬性的值可以從0到4。我想創建一個自定義的“過濾器評估”(名稱空間是我的代碼中的ProfessionProfile),並找到所有最新評估更好或相等的Profiles (每個屬性的值較高或相等)比過濾條件高。
我當前的解決方案有效,但是向服務器發出了大量請求,因此花費了大量時間,我想在單個請求中執行此操作。 使用FYI PostgreSQL。
當前解決方案:
filter_controller.rb:
def filter_by_profession(profiles)
hits = []
profession = ProfessionProfile.find(params[:profession])
Profile.find_each do |p|
if p.has_better_values(profession)
hits << p
end
end
profiles = profiles.where(id: hits.map(&:id))
end
profile.rb:
def has_better_values(profession_profile)
latest_evaluation = property_evaluations.order(:created_at).first
if latest_evaluation.present?
latest_evaluation.property_values.each do |value|
profession_value = profession_profile.property_values.where(property_id: value.property_id)
return false if profession_value.present? && value.value < profession_value.take!.value
end
return true
else
return false
end
end
我沒有嘗試執行以下解決方案,但是即使我應該有一個匹配項,它也始終返回一個空集。
def filter_by_profession(profiles)
profession_profile = ProfessionProfile.find(params[:profession])
profiles = profiles.joins(:property_values)
profession_profile.property_values.find_each do |property_value|
profiles = profiles
.where("property_values.property_id = ?", property_value.property_id)
.where("property_values.value >= ? ", property_value.value)
end
profiles
end
任何提示或幫助,將不勝感激!
我終於設法使它工作了。 該解決方案不是很好,但是它很快並且可以很好地創建兩個服務器查詢。 我最終對數組使用了&運算符,該運算符返回兩個數組的交集。 我還向PropertyEvaluations添加了一個布爾屬性,以避免需要為每個Profile( Profile.each.property_evaluations.order(:created_at)
)查找最新的PropertyEvaluation,這將需要大量的服務器通信。
在profile.rb中:
def self.matches_profession(profession_profile)
property_values = profession_profile.property_values.pluck(:property_id, :value)
ids = Profile.ids
property_values.each do |p|
ids = ids & PropertyEvaluation.where(current: true)
.joins(:property_values)
.where("property_values.property_id = ?", p[0])
.where("property_values.value >= ?", p[1]).pluck(:profile_id)
end
Profile.where(id: ids)
end
我首先轉換為ID數組的原因是Rails中的merge()函數返回一個數組,因此它僅可用於獲取兩個ActiveRecord的交集,而在我的情況下,我需要至少相交11。
如果有人要提出“ railerier”解決方案,請分享!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.