2010-01-17 7 views
5

Ich habe Sphinx und Thinking Sphinx für Ruby auf Schienen installiert 2.3.2.Thinking Sphinx und acts_as_taggable_on Plugin

Wenn ich ohne Bedingungen Suche suche funktioniert ok. Nun, was ich möchte ist durch Tags Filter tun, so, wie ich das acts_as_taggable_on Plugin bin mit, mein Announcement Modell wie folgt aussieht:

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 

Aus irgendeinem Grund, wenn ich den folgenden Befehl ausführen, es wird nur eine Ankündigung bringen, die nichts mit dem zu tun hat, was ich erwarte. Ich habe viele Ankündigungen, daher habe ich viele Ergebnisse erwartet.

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

Ich denke, etwas nicht stimmt, und es ist nicht richtig suchen.

Kann mir jemand einen Hinweis geben, was vor sich geht?

Danke, Brian

Antwort

11

Denken Sphinx beruht auf Assoziationen im Modell. In allgemeinen Situationen müssen Sie nur die Indexdefinition below Ihre Assoziationen setzen.

Mit acts_as_taggable_on Plug-In nicht Tag bezogenen Vereinigungen in Modelldatei haben und wenn Sie schreiben

Indizes tags.name,: as =>: umbauten

TS interpretiert sie mag:

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

(bei sql_query in development.sphinx.conf sehen, in meinem Fall). Ich nehme an, dass Sie Attributnamen in Modellankündigung haben und beim Neuerstellen des Indexes keine Fehler auftreten.

Aber wir erwarten:

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

und:

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' 

Dinge zum Laufen zu bringen Tag bezogenen Vereinigungen in Ihrem Modell nur hinzufügen, bevor Sie Index neu erstellen:

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 methode:

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) 
2

Eine Möglichkeit ist, dass Sie den Typ für tag_ids wie erklären müssen: multi weil TS verwirrt kann (ich dies hier http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q=yanowitz#14d4c1503f5959a9 gerade entdeckt).

Aber warum nicht die Tag-Namen verwenden, um zu suchen? ZB

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

Oder, wenn Sie für mehrere Tags suchen müssen:

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

(als beiseite, du Sphinx-control-Zeichen sanieren/entfernen aus der vom Benutzer bereitgestellte Abfrage sollte vor es benutzen).

Zum Debuggen, würde ich in die Konsole gehen und Ihre Abfrage so weit wie möglich abziehen (Eliminierung Paginierungsargumente, sogar die Abfrage (nur tun ""), etc.).

6

fand ich, dass der Index so einfach zu definieren:

Class Thing < ActiveRecord::Base  

acts_as_taggable 

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

hat gut funktioniert.

+0

Danke, das hat super funktioniert. –