Thinking Sphinx and acts_as_taggable_on plugin

前端 未结 3 779
长情又很酷
长情又很酷 2020-12-13 22:42

I installed Sphinx and Thinking Sphinx for ruby on rails 2.3.2.

When I search without conditions search works ok. Now, what I\'d like to do is filter by tags, so, as

相关标签:
3条回答
  • 2020-12-13 23:19

    Thinking Sphinx relies on associations in model. In common situations you only have to put index definition below your associations.

    With acts_as_taggable_on plug-in you don't have tag-related associations in model file and when you write

    indexes tags.name, :as => :tags

    TS interprets it like:

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

    (look at sql_query in development.sphinx.conf, in my case). I suppose that you have attribute name in model Announcement and don't run into error when rebuild index.

    But we expect:

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

    and:

    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'
    

    To get things working just add tag-related associations in your model before you rebuild index:

    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'"
    

    In define_index method:

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

    In controller:

    @announcement_facets = Announcement.facets params[:search], :with => {:tag_ids => [...]} 
    @announcements = @announcement_facets.for.paginate( :page => params[:page], :per_page => 10 )
    
    0 讨论(0)
  • 2020-12-13 23:19

    One possibility is that you need to declare the type for tag_ids as :multi because TS can get confused (I just discovered this here http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q=yanowitz#14d4c1503f5959a9).

    But why not use the tag names to search? E.g.,

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

    Or, if you need to search for multiple tags:

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

    (as aside, you may want to sanitize/remove sphinx-control-characters from the user-provided query before using it).

    For debugging, I would go into console and strip down your query as much as possible (eliminate pagination arguments, even the query (just do ""), etc.).

    0 讨论(0)
  • 2020-12-13 23:35

    I found that simply defining the index thus:

    Class Thing < ActiveRecord::Base    
    
    acts_as_taggable
    
         define_index do
            ..other indexing...
            indexes taggings.tag.name, :as => :tags
         end
    end
    

    worked fine.

    0 讨论(0)
提交回复
热议问题