Penser le plugin Sphinx et acts_as_taggable_on
-
21-09-2019 - |
Question
J'ai installé Sphinx et Thinking Sphinx pour le rubis sur des rails 2.3.2.
Quand je recherche sans conditions de recherche fonctionne bien. Maintenant, ce que je voudrais faire est le filtre par des balises, donc, comme j'utilise le plugin acts_as_taggable_on, mon modèle d'annonce ressemble à ceci:
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
Pour une raison quelconque, quand je lance la commande suivante, il apportera une seule annonce, qui n'a rien à voir avec ce que je pense. J'ai beaucoup d'annonces, donc je me attendais beaucoup de résultats à la place.
Announcement.search params[:announcement][:search].to_s, :with => {:tag_ids => 1}, :page => params[:page], :per_page => 10
Je suppose que quelque chose ne va pas, et il ne recherche correctement.
Quelqu'un peut-il donner mon moindre idée de ce qui se passe?
Merci, Brian
La solution
Thinking Sphinx repose sur les associations dans le modèle. Dans les situations courantes que vous suffit de mettre la définition index ci-dessous vos associations.
acts_as_taggable_on plug-in vous ne disposez pas d'associations liées tag dans le fichier modèle et lorsque vous écrivez
index tags.name,: as =>: balises
TS interprète comme:
CAST(`announcements`.`name` AS CHAR) AS `tags`
(regardez sql_query en development.sphinx.conf, dans mon cas). Je suppose que vous avez le nom d'attribut dans le modèle d'annonce et ne pas exécuter en erreur lors de la reconstruction index.
Mais nous nous attendons à:
CAST(GROUP_CONCAT(DISTINCT IFNULL(`tags`.`name`, '0') SEPARATOR ' ') AS CHAR) AS `tags`
et
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'
Pour faire avancer les choses de travail ajouter simplement des associations liées tag dans votre modèle avant Reconstruire l'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'"
define_index méthode:
indexes category_tags(:name), :as => :tags
has category_tags(:id), :as => :tag_ids, :facet => true
Dans le contrôleur:
@announcement_facets = Announcement.facets params[:search], :with => {:tag_ids => [...]}
@announcements = @announcement_facets.for.paginate( :page => params[:page], :per_page => 10 )
Autres conseils
Je trouve que la simple définition de l'indice ainsi:
Class Thing < ActiveRecord::Base
acts_as_taggable
define_index do
..other indexing...
indexes taggings.tag.name, :as => :tags
end
end
a bien fonctionné.
Il est possible que vous devez déclarer le type de tag_ids comme: multi parce que TS peut se confondre (je viens de découvrir ce ici http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q = yanowitz # 14d4c1503f5959a9 ).
Mais pourquoi ne pas utiliser les noms de balises pour la recherche? Par exemple.
Announcement.search params[:announcement][:search].to_s, :conditions => {:tags => "my_tag"}, :page => params[:page], :per_page => 10
Ou, si vous devez rechercher plusieurs tags:
Announcement.search( "#{params[:announcement][:search].to_s} (@tags my_tag | @tags your_tag)", :page => params[:page], :per_page => 10 )
(comme à part, vous pouvez désinfecter / supprimer sphynx-caractères de contrôle de la requête fournie par l'utilisateur avant de l'utiliser).
Pour le débogage, je voudrais aller dans la console et la bande votre requête autant que possible (éliminer les arguments de pagination, même la requête (le faire ""), etc.).