2010-01-17 6 views
5

Instalé Sphinx y Thinking Sphinx para ruby ​​on rails 2.3.2.Thinking Sphinx y el plugin acts_as_taggable_on

Cuando busco sin condiciones la búsqueda funciona bien. Ahora, lo que me gustaría hacer es filtrar por etiquetas, por lo que, como yo estoy usando el plugin acts_as_taggable_on, mi modelo de anuncio es el siguiente:

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 

Por alguna razón, cuando ejecuto el comando siguiente, traerá un solo anuncio, que no tiene nada que ver con lo que espero. Tengo muchos anuncios, así que esperaba muchos resultados.

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

supongo que algo está mal, y no es buscar correctamente.

¿Alguien puede darme una idea de lo que está pasando?

Gracias, Brian

Respuesta

11

Thinking Sphinx depende de las asociaciones en el modelo. En situaciones comunes, solo tiene que poner la definición del índice below sus asociaciones.

Con acts_as_taggable_on no tienen asociaciones de plug-específica de TAG en el archivo de modelo y cuando se escribe

índices tags.name,: => como: etiquetas

TS interpreta como:

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

(mira sql_query en development.sphinx.conf, en mi caso). Supongo que tiene el nombre del atributo en el anuncio del modelo y no se encuentra con el error al reconstruir el índice.

Pero se espera:

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

y:

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' 

para hacer las cosas de trabajo sólo tiene que añadir asociaciones específica de TAG en su modelo antes de reconstruir el índice:

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étodo:

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

En el regulador:

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

Una posibilidad es que tiene que declarar el tipo de tag_ids como: multi debido TS puede confundir (acabo de descubrir esto aquí http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q=yanowitz#14d4c1503f5959a9).

¿Por qué no utilizar los nombres de las etiquetas para buscar? Por ejemplo,

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

O, si es necesario buscar para varias variables:

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

(como un lado, es posible que desee desinfectar/eliminar de control de Sphinx-caracteres de la consulta proporcionada por el usuario antes de usándolo).

Para la depuración, me gustaría ir a la consola y eliminar su consulta tanto como sea posible (elimine los argumentos de paginación, incluso la consulta (simplemente haga ""), etc.).

6

me encontré con que simplemente definir el índice de este modo:

Class Thing < ActiveRecord::Base  

acts_as_taggable 

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

funcionó bien.

+0

Gracias, funcionó muy bien. –

Cuestiones relacionadas