Я столкнулся с камнем преткновения с расширенными ActiveRecord и / или SQL-запросами, которые имеют отношение к тегам, ранжированию, вы называете это.Я надеюсь, что вы, гуру MySQL или Rails 3, можете помочь мне решить эту проблему.
Я заранее извиняюсь за длинный пост:)
Сначала приведу фрагмент, описывающий мою модель данных
Модель данных
AggregateData - модель содержит набор атрибутов данных ( provider_datas ), которые поступают от разных поставщиков данных, и имеет вычисленный балл атрибут, используемый для ранжирования
class AggregateData < ActiveRecord::Base
# has a pre-populated integer attribute 'score'
has_many :provider_datas
# find profiles with top 10 score for specified tag
# this is mainly used to determine top 10 scores for later comparison
# Since this is grouped by score, the actual number of profiles
# that have these score may be larger
def self.find_top_10_by_tag(tag)
joins(:provider_data_tags) \
.where(:provider_data_tags=>{:tag_id => tag.id}) \
.group('aggregate_data.score') \
.order('aggregate_data.score DESC') \
.limit(10)
end
# simple ranking algorithm,
# tells you how many AggregateDatas have better score than this one
def ranking
self.connection.select_value("SELECT COUNT(*) + 1 AS ranking \
FROM aggregate_datas \
WHERE aggregate_datas.score > \
(SELECT aggregate_datas.score FROM aggregate_data \
WHERE aggregate_datas.id = #{self.id})").to_i
end
end
ProviderData содержит различные атрибуты данных, поступающие от конкретного поставщика данных, который представляет этот экземпляр ProviderData , и, что наиболее важно, имеет множество теги , связанные с ним через * provider_data_tags * таблица сопоставления многие-ко-многим
class ProviderData < ActiveRecord::Base
belongs_to :aggregate_data
has_many :provider_data_tags
has_many :tags, :through => :provider_data_tags
end
Tag - это простая модель, содержащая атрибут name и many_to_manyсвязь с ProviderData .Обратите внимание на функцию поиска, чтобы получить все теги, связанные с предоставленными AggregateData
class Tag < ActiveRecord::Base
has_many :provider_data_tags
has_many :provider_datas, :through => :provider_data_tags
def self.find_by_aggregate_data(ag_data)
joins(:provider_datas).where(:provider_datas =>{:aggregate_data_id => ag_data.id})
end
end
Проблема: 10 лучших тегов для указанного AggregateData
Итак, в моей модели данных AggregateData имеет балл , и вы можете найти, какие теги, связанные с этим AggregateData , используют область или функцию Tag.find_by_aggregate_data выше
Мне нужно получить ТОП-10 тегов за AggregateData .
Что это означает, что мне нужно получить подмножество всех тегов, связанных с AggregateData , для которого оценка этого AggregateData входит в топ-10 оценок всех AggregateDatas , связанный с этим конкретным тегом.
Так что, если у этого AggregateData есть теги "java" , "ruby" , "javascript" , "html" , "css" , а данные AggregateData имеют самый высокий балл из всех AggregateDatas с тегом "ruby" и наибольшим результатом из всех AggregateDatas с тегом "javascript" , но не самым высоким показателем для "java" или "html" или "css" , тогда эта функция / область действия / запрос будет возвращать теги "ruby" и "javascript"
В этом решении предпочтительно использовать нотацию ActiveRecord / AREL, но я открыт для предложений SQL, которые я могу адаптировать к AR самостоятельно.