Search code examples
ruby-on-railssearchinheritancesolrsunspot

Rails / Sunspot / Solr: Duplicate indexing on inherited classes


We are building a Ruby on Rails application which uses Solr as a search engine. The following version numbers could be relevant to the issue described in the next paragraphs:

  • Ruby: 1.9.2
  • Rails: 3.2.6
  • Sunspot: 1.3.0.rc5

Background

We have a Feedback model that is inherited by different subclasses. The class hierarchy looks like the following (single table inheritance):

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

In the Feedback model indexing is enabled by the following code:

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

Issue

The issue with this is that when creating, for example, a new Problem with a title of "problemtitle" Sunspot initializes the automatic indexing for the Problem and the underlying Feedback. When searching for feedbacks with a title of "problemtitle" with

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

two results are found. One result is the Problem and the other one is the Feedback. This indicates that in a class hierarchy a class and its subclasses are indexed; which should be correct as far as I am aware.

The strange thing here is that reindexing the index with the command bundle exec rake sunspot:solr:reindex and searching for a Feedback with title "problemtitle" results in one result which is the Problem created above.

We solved this by adding :unless => proc {|model| model.class == Feedback} to the searchable definition in the Feedback model. This ensures that only subclasses of Feedback are indexed automatically.

Question

My question is if this is a desired behavior or not (is it a feature or a bug). I do not understand why the reindexing treats the models to index differently than the automatic indexing at creation time. Can this be a problem of how we implemented the class hierarchy?

If more information is needed to answer my question I will try to give it.

With best regards,

Sebastian


Solution

  • We solved the mentioned issue by extending the searchable-block with an unless-statement:

    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