【问题标题】:Thinking Sphinx and acts_as_taggable_on pluginThinking Sphinx 和acts_as_taggable_on 插件
【发布时间】:2010-01-17 19:59:28
【问题描述】:

我在 rails 2.3.2 上为 ruby​​ 安装了 Sphinx 和 Thinking Sphinx。

当我没有条件搜索时,搜索工作正常。现在,我想做的是按标签过滤,所以,当我使用acts_as_taggable_on 插件时,我的公告模型如下所示:

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

由于某种原因,当我运行以下命令时,它只会带来一个公告,这与我的预期无关。我有很多公告,所以我期待很多结果。

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

我猜有问题,搜索不正确。

谁能告诉我发生了什么?

谢谢, 布赖恩

【问题讨论】:

    标签: ruby-on-rails sphinx thinking-sphinx acts-as-taggable


    【解决方案1】:

    Thinking Sphinx 依赖于模型中的关联。在一般情况下,您只需将索引定义below 放入您的关联中。

    使用 acts_as_taggable_on 插件,您在模型文件和编写时没有标签相关的关联

    索引 tags.name, :as => :tags

    TS 将其解释为:

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

    (在我的例子中,查看 development.sphinx.conf 中的 sql_query)。 我想您在模型公告中有属性名称,并且在重建索引时不会出错。

    但我们期望:

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

    和:

    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'
    

    要让事情正常工作,只需在重建索引之前在模型中添加与标签相关的关联:

    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方法中:

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

    在控制器中:

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

    【讨论】:

      【解决方案2】:

      我发现只需这样定义索引:

      Class Thing < ActiveRecord::Base    
      
      acts_as_taggable
      
           define_index do
              ..other indexing...
              indexes taggings.tag.name, :as => :tags
           end
      end
      

      工作正常。

      【讨论】:

        【解决方案3】:

        一种可能性是您需要将 tag_ids 的类型声明为 :multi 因为 TS 可能会混淆(我刚刚在这里发现了这一点 http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q=yanowitz#14d4c1503f5959a9)。

        但是为什么不使用标签名来搜索呢?例如,

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

        或者,如果您需要搜索多个标签:

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

        (顺便说一句,您可能希望在使用之前从用户提供的查询中清理/删除 sphinx-control-characters)。

        为了调试,我会进入控制台并尽可能地删除您的查询(消除分页参数,甚至是查询(只需执行“”)等)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多