Thinking Sphinx and act_as_taggable_on plugin

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

When searching without conditions, the search works fine. Now, what I would like to do is filter by tags, so since I use the act_as_taggable_on plugin, my ad model looks like this:

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 

For some reason, when I run the following command, it will only display one declaration, which has nothing to do with what I expect. I have a lot of ads, so I expected great results.

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

I assume that something is wrong and it is not working correctly.

Can someone let me know what is going on?

Thanks Brian

+5
ruby-on-rails sphinx thinking-sphinx
source share
3 answers

Sphinx thinking is based on associations in the model. In normal situations, you only need to establish the definition of your associations.

With the act_as_taggable_on plugin, you do not have any tag associations in the model file and when writing

indexes tags.name ,: as =>: tags

TS interprets this as:

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

(look at sql_query in the development.sphinx.conf file, in my case). I believe that you have an attribute name in the model declaration and does not start when an error occurs while restoring the 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 the job done, just add the tag associations to your model before rebuilding the 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 :

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

In the controller:

 @announcement_facets = Announcement.facets params[:search], :with => {:tag_ids => [...]} @announcements = @announcement_facets.for.paginate( :page => params[:page], :per_page => 10 ) 
+11
source share

I found that simply defining the index in this way:

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

worked fine.

+6
source share

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

But why not use tag names for your search? For example.

 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 an aside, you may want to sanitize / remove sphinx control characters from a user-provided request before using it).

For debugging, I would go to the console and break up your request as much as possible (exclude pagination arguments, even the request (just do ""), etc.).

+2
source share

All Articles