Как написать запрос для поиска записей и группировки их в 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 (например: коллекция идентификаторов категории для данной сделки). Так что именно вы хотите получить из результатов поиска?

Другие вопросы по тегам