Skip to content

Longer Indexing Example

dburry edited this page Jul 15, 2012 · 1 revision

Longer Indexing Example

# app/models/foo_thing.rb
class FooThing < ActiveRecord::Base
  has_many :bar_things

  # the following include can be left out if this model will never be auto-reindexed
  # since the rake tasks include it if it's not done already
  include IndexedSearch::Index

  # define scope as {} if every row should be indexed
  # or supply any scope you wish to limit what should be indexed
  scope :search_index_scope, where(:public => true)

  # title and summary only used by views
  # you can call these whatever you wish, it's just a way of presenting the search views with a common interface
  def search_result_title
    name
  end
  def search_result_summary
    # whatever text munging you need here, squish_space and strip_html are left for you to implement
    squish_space(strip_html(description))
  end

  # how to index this row!
  def search_index_info
    # each row is one ranking expression
    # words are indexed by model row, with their total score being the primary ranking element,
    # calculated by adding up all individual occurrences of that word within the following expressions.
    [
      # string/array of words to index, integer of rank to assign for each word
      # times as many different rows as you need to describe all searchable text of the model
      # string may be nil or empty, if this one doesn't apply this time
      [name,                             50],
      [abstract,                          6],
      # you can add arbitrary model-based keywords:
      ['foo',                            10],
      # you can perform pre-processing (note strip_html is left for you to implement):
      [strip_html(description),           1],
      # more complicated pre-processing example, +2 points for words in 1st sentence (like a fake abstract):
      [strip_html(description =~ /.*?\./m ? $~[0] : description), 2],
      # you can index attributes on relationships too
      [bar_things.collect(&:name),        4]
    ]
  end

  # If some rows should have more importance than others (for example, archived stuff might be
  # less important than recently added stuff), then set that here. It will affect results ranking.
  # The following could also be an actual model attribute if you want to precalculate/store it,
  # for example, for static data that could make indexing go a little bit faster.
  # Should return a float between 0 and 1.
  def search_priority
    0.5 + (public? ? 0.3 : -0.2)
  end
end

Example relationship model used above:

# app/models/bar_thing.rb
class BarThing < ActiveRecord::Base
  belongs_to :foo_thing
end