Плагин Thinking Sphinx и acts_as_taggable_on - PullRequest
5 голосов
/ 17 января 2010

Я установил Sphinx и Thinking Sphinx для ruby ​​на рельсах 2.3.2.

При поиске без условий поиск работает нормально. Теперь я хотел бы фильтровать по тегам, поэтому, поскольку я использую плагин act_as_taggable_on, моя модель объявлений выглядит следующим образом:

class Announcement < ActiveRecord::Base

  acts_as_taggable_on :tags,:category

  define_index do
    indexes title, :as => :title, :sortable => true
    indexes description, :as => :description, :sortable => true
    indexes tags.name, :as => :tags
    indexes category.name, :as => :category

    has category(:id), :as => :category_ids
    has tags(:id), :as => :tag_ids
  end

По какой-то причине, когда я запускаю следующую команду, она выдаст только одно объявление, которое не имеет ничего общего с тем, что я ожидаю. У меня много объявлений, поэтому я ожидал много результатов.

Announcement.search params[:announcement][:search].to_s, :with => {:tag_ids => 1}, :page => params[:page], :per_page => 10

Полагаю, что-то не так, и поиск выполняется неправильно.

Может кто-нибудь подсказать мне, что происходит?

Спасибо, Brian

Ответы [ 3 ]

11 голосов
/ 04 февраля 2010

Мышление Сфинкс опирается на ассоциации в модели. В обычных ситуациях вам нужно только поставить определение индекса ниже вашей ассоциации.

С плагином acts_as_taggable_on у вас нет связанных с тегами ассоциаций в файле модели и при написании

indexes tags.name,: as =>: tags

TS интерпретирует это как:

CAST(`announcements`.`name` AS CHAR) AS `tags`

(посмотрите на sql_query в development.sphinx.conf, в моем случае). Я полагаю, что у вас есть имя атрибута в объявлении модели и вы не столкнетесь с ошибкой при перестроении индекса.

Но мы ожидаем:

CAST(GROUP_CONCAT(DISTINCT IFNULL(`tags`.`name`, '0') SEPARATOR ' ') AS CHAR) AS `tags`

и

LEFT OUTER JOIN `taggings` ON (`announcements`.`id` = `taggings`.`taggable_id`)  
LEFT OUTER JOIN `tags` ON (`tags`.`id` = `taggings`.`tag_id`) AND taggings.taggable_type = 'Announcement'

Чтобы все заработало, просто добавьте ассоциации, связанные с тегами, в свою модель, прежде чем перестраивать индекс:

class Announcement < ActiveRecord::Base

  acts_as_taggable_on :tags,:category

  has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "ActsAsTaggableOn::Tagging",
            :conditions => "taggings.taggable_type = 'Announcement'"
  #for context-dependent tags:
  has_many :category_tags, :through => :taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag",
          :conditions => "taggings.context = 'categories'"

В define_index Метод:

indexes category_tags(:name), :as => :tags
has category_tags(:id), :as => :tag_ids, :facet => true

В контроллере:

@announcement_facets = Announcement.facets params[:search], :with => {:tag_ids => [...]} 
@announcements = @announcement_facets.for.paginate( :page => params[:page], :per_page => 10 )
6 голосов
/ 08 августа 2011

Я обнаружил, что просто определяя индекс таким образом:

Class Thing < ActiveRecord::Base    

acts_as_taggable

     define_index do
        ..other indexing...
        indexes taggings.tag.name, :as => :tags
     end
end

работал нормально.

2 голосов
/ 20 января 2010

Возможно, вам нужно объявить тип для tag_ids: multi, потому что TS может запутаться (я только что обнаружил это здесь http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q=yanowitz#14d4c1503f5959a9).

Но почему бы не использовать имена тегов для поиска? Например.,

Announcement.search params[:announcement][:search].to_s, :conditions => {:tags => "my_tag"}, :page => params[:page], :per_page => 10

Или, если вам нужно найти несколько тегов:

Announcement.search( "#{params[:announcement][:search].to_s} (@tags my_tag | @tags your_tag)", :page => params[:page], :per_page => 10 )

(кроме этого, вы можете очистить / удалить sphinx-control-символы из предоставленного пользователем запроса перед его использованием).

Для отладки я бы зашел в консоль и максимально сократил ваш запрос (исключив аргументы разбиения на страницы, даже запрос (просто сделайте "") и т.

...