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

Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top