2010-01-17 7 views
5

J'ai installé Sphinx et Thinking Sphinx pour ruby ​​on rails 2.3.2.Penser Sphinx et acts_as_taggable_on plugin

Lorsque je recherche sans conditions, la recherche fonctionne bien. Maintenant, ce que je voudrais faire est 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, ça n'apportera qu'une seule annonce, cela n'a rien à voir avec ce à quoi je m'attends. J'ai beaucoup d'annonces, donc je m'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 ce n'est pas la recherche correctement.

Quelqu'un peut-il me donner une idée de ce qui se passe?

Merci, Brian

Répondre

11

Penser Sphinx s'appuie sur des associations dans le modèle. Dans les situations courantes, il suffit de mettre la définition d'index below dans vos associations.

Avec acts_as_taggable_on plug-in que vous n'avez pas les associations des TAG dans le fichier de modèle et lorsque vous écrivez

index tags.name,: as =>: balises

TS l'interprète comme:

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

(regardez sql_query dans development.sphinx.conf, dans mon cas). Je suppose que vous avez un nom d'attribut dans l'annonce de modèle et ne pas générer d'erreur lors de la reconstruction de l'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 que cela fonctionne simplement ajouter des associations liées tag dans votre modèle avant de 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'" 

En define_index méthode:

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

Contrôleur:

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

Une possibilité est que vous devez déclarer le type de tag_ids que: 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 tags pour effectuer une 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 côté, vous voudrez peut-être désinfectez/supprimer les caractères de contrôle-sphynx de la requête fournie par l'utilisateur avant En l'utilisant). Pour le débogage, j'entrerais dans la console et je réduirais le plus possible votre requête (éliminez les arguments de pagination, même la requête (juste ""), etc.).

6

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é.

+0

Merci, ça a bien fonctionné. –

Questions connexes