Denken Sphinx und acts_as_taggable_on Plugin
-
21-09-2019 - |
Frage
Ich installierte Sphinx und Denken Sphinx für Ruby on Rails 2.3.2.
Wenn ich ohne Bedingungen suchen Suche funktioniert ok. Nun, was ich möchte tun Filter durch Tags, so, wie ich das acts_as_taggable_on Plugin bin mit, mein Announcement Modell sieht wie folgt aus:
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, wird es nur eine Ankündigung bringen, die nichts mit dem zu tun hat, was ich erwarte. Ich habe viele Ankündigungen bekommen, so dass ich stattdessen eine Menge Ergebnisse erwartet.
Announcement.search params[:announcement][:search].to_s, :with => {:tag_ids => 1}, :page => params[:page], :per_page => 10
ich denke, etwas falsch ist, und es ist nicht richtig suchen.
Kann jemand meine Ahnung von dem, was ist los?
Danke, Brian
Lösung
Denken Sphinx beruht auf Assoziationen in Modell. In alltäglichen Situationen haben Sie nur Indexdefinition unter Ihre Assoziationen zu setzen.
Mit acts_as_taggable_on Plug-In nicht-Tag bezogene Verbände in Modelldatei hat und wenn Sie schreiben
Indizes tags.name,: as => tags:
TS interpretiert es wie:
CAST(`announcements`.`name` AS CHAR) AS `tags`
(Blick auf sql_query in development.sphinx.conf, in meinem Fall). Ich nehme an, dass Sie Attributnamen in Modell-Mitteilung haben und nicht in die Irre führen, wenn Index neu erstellen.
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 bringen Tag bezogenen Vereinigungen in Ihrem Modell nur hinzufügen, bevor Sie Index neu zu 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'"
define_index Methode:
indexes category_tags(:name), :as => :tags
has category_tags(:id), :as => :tag_ids, :facet => true
Controller:
@announcement_facets = Announcement.facets params[:search], :with => {:tag_ids => [...]}
@announcements = @announcement_facets.for.paginate( :page => params[:page], :per_page => 10 )
Andere Tipps
fand ich, dass einfach die Definition des Index also:
Class Thing < ActiveRecord::Base
acts_as_taggable
define_index do
..other indexing...
indexes taggings.tag.name, :as => :tags
end
end
hat gut funktioniert.
Eine Möglichkeit ist, dass Sie den Typ für tag_ids wie erklären müssen: multi weil TS verwirren lassen kann (ich gerade entdeckt, diese hier http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q = Yanowitz # 14d4c1503f5959a9 ).
Aber warum nicht den Tag-Namen verwenden, um zu suchen? Z.B.
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:
Announcement.search( "#{params[:announcement][:search].to_s} (@tags my_tag | @tags your_tag)", :page => params[:page], :per_page => 10 )
(wie beiseite, Sie zu sanieren / Entfernen Sphinx-control-Zeichen aus der vom Benutzer bereitgestellte Abfrage, bevor Sie es möchten).
Für das Debuggen, würde ich in die Konsole gehen und Streifen nach unten Ihre Anfrage so weit wie möglich (beseitigen Paginierung Argumente, auch die Abfrage (nur tun, „“), usw.).