Как написать запрос для поиска записей и группировки их в ruby on rails с помощью мышления sphinix
У меня есть модель Deal и одна модель Category, имеющая отображение многих на многие (has_many: through, так как я сохраняю некоторые связанные данные).
Также у меня есть модель города, которая также имеет много-много картографирования с моделью сделки (снова через has_many)
Категория модель не имеет отношения к модели города.
Теперь, чтобы искать предложения, основанные на ключевых словах (Ключевые слова означают, я проиндексировал некоторые столбцы, такие как название сделки, описание и т. Д.)
@deals = Deal.search(params[:keywords],:per_page => 20, :page => params[:page])
Вопрос:
Теперь мне нужно сгруппировать эти сделки по категориям, в основном в первой категории 4 сделки, во второй категории 7 сделок и т. Д., Если указан city_id.
@deals = @city.deals.search(params[:keywords],:per_page => 20, :page => params[:page])
PS: Вы можете придумать что-то вроде этого: Конечный пользователь введет "Выбрать Лондон" в качестве местоположения, а затем введите "веселье" в качестве ключевого слова, а затем мне нужно поискать в базе данных, чтобы проверить предложения Лондона, имеющие ключевое слово "веселье", и сгруппировать их. основанный на различных категориях. Я надеюсь, что смогу объяснить вопрос.
РЕДАКТИРОВАТЬ
Некоторые проблемы с индексацией: rake think_sphinx: перестроить --trace ** Вызвать think_sphinx: перестроить (first_time) ** Вызвать think_sphinx:app_env (first_time) ** Выполнить think_sphinx: app_env ** Выполнить think_sphinx: перестроить ** index_ first_time_) ** Вызвать think_sphinx: app_env ** Выполнить think_sphinx: index Генерация конфигурации для /Users/me/projects/deals/config/development.sphinx.conf рейка прервана!
Cannot automatically map attribute category_ids in Deal to an
equivalent Sphinx type (integer, float, boolean, datetime, string as ordinal).
You could try to explicitly convert the column's value in your define_index
block:
has "CAST(column AS INT)", :type => :integer, :as => :column
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/attribute.rb:334:in `translated_type_from_database'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/attribute.rb:170:in `type'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/attribute.rb:139:in `include_as_association?'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/attribute.rb:107:in `to_select_sql'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/source/sql.rb:69:in `block in sql_select_clause'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/source/sql.rb:69:in `collect'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/source/sql.rb:69:in `sql_select_clause'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/source/sql.rb:19:in `to_sql'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/source.rb:117:in `set_source_sql'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/source.rb:51:in `to_riddle_for_core'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/index.rb:114:in `block in to_riddle_for_core'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/index.rb:113:in `each'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/index.rb:113:in `each_with_index'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/index.rb:113:in `to_riddle_for_core'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/index.rb:83:in `to_riddle'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/active_record.rb:245:in `block in to_riddle'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/active_record.rb:244:in `collect'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/active_record.rb:244:in `to_riddle'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/configuration.rb:164:in `block in generate'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/configuration.rb:161:in `each'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/configuration.rb:161:in `generate'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/configuration.rb:177:in `build'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/tasks.rb:78:in `block (2 levels) in <top (required)>'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:205:in `call'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:205:in `block in execute'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:200:in `each'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:200:in `execute'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain'
/Users/me/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:144:in `invoke'
/Users/me/.rvm/gems/ruby-1.9.2-p290/gems/thinking-sphinx-2.0.5/lib/thinking_sphinx/tasks.rb:95:in `block (2 levels) in <top (required)>'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:205:in `call'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:205:in `block in execute'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:200:in `each'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:200:in `execute'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain'
/Users/me/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/task.rb:144:in `invoke'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:112:in `invoke_task'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:90:in `block (2 levels) in top_level'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:90:in `each'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:90:in `block in top_level'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:129:in `standard_exception_handling'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:84:in `top_level'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:62:in `block in run'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:129:in `standard_exception_handling'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/lib/rake/application.rb:59:in `run'
/Users/me/.rvm/gems/ruby-1.9.2-p290@global/gems/rake-0.9.2/bin/rake:32:in `<top (required)>'
/Users/me/.rvm/gems/ruby-1.9.2-p290/bin/rake:19:in `load'
/Users/me/.rvm/gems/ruby-1.9.2-p290/bin/rake:19:in `<main>'
Tasks: TOP => thinking_sphinx:index
2 ответа
Я предположил, что у вас есть модель сделки, как
class Deal < ActiveRecord::Base
has_many :category_deals
has_many :categories, :through => :category_deals
has_many :city_deals
has_many :cities, :through => :city_deals
define_index do
indexes :name
has category_deals.category_id, :as => :category_ids
has city_deals.city_id, :as => :city_ids
end
end
Итак, вы хотите выполнить поиск по городу и данной категории или категориям (1,3,2) для данного города с категориями ASC:
Deal.search(params[:keywords], :with => {:category_ids => [1,3,2], :city_ids => params[:city_id]}, :order => "category_ids ASC", :per_page => 20, :page => params[:page])
Я не совсем уверен, что вы после этого - но давайте уточним несколько вещей, в частности, какие результаты должны быть возвращены, а затем порядок результатов.
Во-первых, чтобы ограничить результаты поиска определенным городом, вам понадобятся идентификаторы города в качестве атрибута в определении индекса сделки (если говорить о том, что - вам будет полезно, если вы сможете предоставить существующий блок define_index в сделке):
has cities.id, :as => :city_ids
Затем для сортировки звучит так, как будто вы хотите, чтобы результаты поиска были сгруппированы по категориям, но это сложно, поскольку сделка может принадлежать более чем одной категории. Вы не можете сортировать по атрибуту MVA (например: коллекция идентификаторов категории для данной сделки). Так что именно вы хотите получить из результатов поиска?