【问题标题】:Rails / Sunspot / Solr: Duplicate indexing on inherited classesRails / Sunspot / Solr:继承类的重复索引
【发布时间】:2013-01-27 18:46:32
【问题描述】:

我们正在构建一个使用 Solr 作为搜索引擎的 Ruby on Rails 应用程序。以下版本号可能与下一段中描述的问题相关:

  • 红宝石:1.9.2
  • 导轨:3.2.6
  • 太阳黑子:1.3.0.rc5

背景

我们有一个由不同子类继承的Feedback 模型。类层次结构如下(单表继承):

Feedback
  |- Problem
  |- Question
  |- Suggestion
  |- Announcement

Feedback 模型中,通过以下代码启用索引:

searchable :auto_index => true, :auto_remove => true do
  string :type
  text :title, :boost => 2
  text :content
  integer :user_id
  time :created_at
  ...
end

问题

问题在于,例如,在创建标题为“问题标题”的新 Problem 时,Sunspot 会初始化 Problem 基础 Feedback 的自动索引.当搜索标题为“问题标题”的反馈时,

search = Feedback.solr_search do
    with(:type, type.capitalize)
    fulltext("problemtitle") {minimum_match 1}
    paginate(page: options[:page], per_page: options[:per_page])
end

找到两个结果。一个结果是Problem,另一个是Feedback。这表明在类层次结构中,一个类及其子类被索引;据我所知,这应该是正确的。

这里奇怪的是,使用命令bundle exec rake sunspot:solr:reindex 重新索引索引并搜索标题为“问题标题”的Feedback 会得到一个结果,即上面创建的Problem

我们通过将:unless => proc {|model| model.class == Feedback} 添加到Feedback 模型中的可搜索定义来解决此问题。这确保只有 Feedback 的子类会被自动索引。

问题

我的问题是这是否是一种期望的行为(它是一个功能还是一个错误)。我不明白为什么重新索引将模型索引与创建时的自动索引不同。这可能是我们如何实现类层次结构的问题吗?

如果需要更多信息来回答我的问题,我会尽力提供。

致以最诚挚的问候,

塞巴斯蒂安

【问题讨论】:

    标签: ruby-on-rails search inheritance solr sunspot


    【解决方案1】:

    Sebastian,我认为这里的问题是 Sunspot 使用完整的类名和 id 创建了 Solr 主 id:

    def index_id_for(class_name, id) #:nodoc:
      "#{class_name} #{id}"
    end
    

    所以如果你的类被索引为Feedback,然后又被索引为Feedback::Problem,Solr 将有两个条目,因此在搜索时返回它们。然后,Sunspot 将尝试将每个项目与数据库进行匹配,两次提取相同的项目。当重新索引整个数据库时,会删除每个项目的当前类索引 - 这就是为什么重新索引后只有一个。

    我们遇到了类似的问题,解决方案是为 STI 类创建我们自己的 InstanceAdapter 并将其注册到初始化程序中:

    class StiInstanceAdapter < Sunspot::Adapters::InstanceAdapter
    
      def id
        @instance.id
      end
    
      def index_id
        return Sunspot::Adapters::InstanceAdapter.index_id_for(@instance.class.base_class.name, id)
      end
    
    end
    
    Sunspot::Adapters::InstanceAdapter.register(StiInstanceAdapter, Feedback)
    

    我知道这有点晚了,但希望能有所帮助。

    【讨论】:

    • 你用什么初始化器调用它?反馈类、问题类或其他地方?
    • 这对我们没有帮助 - 只有使用接受的答案解决了我们与 OP 的类似问题
    【解决方案2】:

    我们通过使用除非语句扩展可搜索块解决了上述问题:

    searchable :auto_index => true, :auto_remove => true, 
      :unless => proc {|model| model.class == Feedback} do
        string :type
        text :title, :boost => 2
        text :content
        integer :user_id
        time :created_at
        ...
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多