Pensando Esfinge y acts_as_taggable_on plug-in
-
21-09-2019 - |
Pregunta
He instalado Esfinge y Pensando Sphinx para Ruby on Rails 2.3.2.
Cuando busco sin condiciones de 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 corro el siguiente comando, que traerá un solo anuncio, que no tiene nada que ver con lo que espero. Tengo muchos anuncios, así que esperaba una gran cantidad de resultados en su lugar.
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.
Puede alguien dar mi idea de lo que está pasando?
Gracias, Brian
Solución
Pensando Esfinge se basa en asociaciones en el modelo. En situaciones comunes que sólo se tiene que poner de definición del índice continuación sus asociaciones.
acts_as_taggable_on plug-in no tiene asociaciones específica de TAG en el archivo de modelo y cuando se escribe
índices tags.name,: as =>: las etiquetas
TS interpreta como:
CAST(`announcements`.`name` AS CHAR) AS `tags`
(mirar sql_query en development.sphinx.conf, en mi caso). Supongo que tienes nombre de atributo en el Anuncio de modelo y no se quede en el error cuando la reconstrucción de índice.
Sin embargo, 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 que todo funcione 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 )
Otros consejos
He descubierto 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.
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 ).
Pero 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 usarlo).
Para la depuración, me gustaría ir a la consola y tira hacia abajo su consulta lo más posible (eliminar argumentos de paginación, incluso la consulta (acaba de hacer ""), etc.).