Module Foo::Acts::Indexed::ClassMethods
In: lib/acts_as_indexed.rb

Methods

Included Modules

Foo::Acts::Indexed::InstanceMethods

Public Instance methods

Declares a class as searchable.

options:

fields:Names of fields to include in the index. Symbols pointing to instance methods of your model may also be given here.
index_file_depth:Tuning value for the index partitioning. Larger values result in quicker searches, but slower indexing. Default is 3.
min_word_size:Sets the minimum length for a word in a query. Words shorter than this value are ignored in searches unless preceded by the ’+’ operator. Default is 3.
index_file:Sets the location for the index. By default this is RAILS_ROOT/index. Specify as an array. Heroku, for example would use RAILS_ROOT/tmp/index, which would be set as [RAILS_ROOT,’tmp’,’index]

[Source]

    # File lib/acts_as_indexed.rb, line 37
37:         def acts_as_indexed(options = {})
38:           class_eval do
39:             extend Foo::Acts::Indexed::SingletonMethods
40:           end
41:           include Foo::Acts::Indexed::InstanceMethods
42: 
43:           after_create  :add_to_index
44:           before_update  :update_index
45:           after_destroy :remove_from_index
46: 
47:           cattr_accessor :aai_config
48: 
49:           # default config
50:           self.aai_config = { 
51:             :index_file => [RAILS_ROOT,'index'],
52:             :index_file_depth => 3,
53:             :min_word_size => 3,
54:             :fields => []
55:           }
56: 
57:           aai_config[:index_file] += [RAILS_ENV,name]
58: 
59:           aai_config.merge!(options)
60: 
61:           raise(ArgumentError, 'no fields specified') unless aai_config.include?(:fields)
62:           raise(ArgumentError, 'index_file_depth cannot be less than one (1)') if aai_config[:index_file_depth].to_i < 1
63:         end

Adds the passed record to the index. Index is built if it does not already exist. Clears the query cache.

[Source]

    # File lib/acts_as_indexed.rb, line 67
67:         def index_add(record)
68:           build_index if !File.exists?(File.join(aai_config[:index_file]))
69:           index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
70:           index.add_record(record)
71:           index.save
72:           @query_cache = {}
73:           true
74:         end

Removes the passed record from the index. Clears the query cache.

[Source]

    # File lib/acts_as_indexed.rb, line 78
78:         def index_remove(record)
79:           index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
80:           # record won't be in index if it doesn't exist. Just return true.
81:           return true if !index.exists?
82:           index.remove_record(record)
83:           index.save
84:           @query_cache = {}
85:           true
86:         end

Updates the index.

  1. Removes the previous version of the record from the index
  2. Adds the new version to the index.

[Source]

     # File lib/acts_as_indexed.rb, line 92
 92:         def index_update(record)
 93:           build_index if !File.exists?(File.join(aai_config[:index_file]))
 94:           index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
 95:           #index.remove_record(find(record.id))
 96:           #index.add_record(record)
 97:           index.update_record(record,find(record.id))
 98:           index.save
 99:           @query_cache = {}
100:           true
101:         end

Finds instances matching the terms passed in query. Terms are ANDed by default. Returns an array of model instances or, if ids_only is true, an array of integer IDs.

Keeps a cache of matched IDs for the current session to speed up multiple identical searches.

find_options

Same as ActiveRecord#find options hash. An :order key will override the relevance ranking

options

ids_only:Method returns an array of integer IDs when set to true.
no_query_cache:Turns off the query cache when set to true. Useful for testing.

[Source]

     # File lib/acts_as_indexed.rb, line 118
118:         def search_index(query, find_options={}, options={})
119:           # Clear the query cache off  if the key is set.
120:           @query_cache = {}  if (options.has_key?('no_query_cache') || options[:no_query_cache])
121:           if !@query_cache || !@query_cache[query]
122:             logger.debug('Query not in cache, running search.')
123:             build_index if !File.exists?(File.join(aai_config[:index_file]))
124:             index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
125:             @query_cache = {} if !@query_cache
126:             @query_cache[query] = index.search(query)
127:           else
128:             logger.debug('Query held in cache.')
129:           end
130:           return @query_cache[query].sort{|a,b| b <=> a }.collect{|a| a.first} if (options.has_key?(:ids_only) && options[:ids_only]) || @query_cache[query].empty?
131:           
132:           # slice up the results by offset and limit
133:           offset = find_options[:offset] || 0
134:           limit = find_options.include?(:limit) ? find_options[:limit] : @query_cache[query].size
135:           part_query = @query_cache[query].sort{|a,b| b <=> a }.slice(offset,limit).collect{|a| a.first}
136:           
137:           # Set these to nil as we are dealing with the pagination by setting
138:           # exactly what records we want.
139:           find_options[:offset] = nil
140:           find_options[:limit] = nil
141:           
142:           with_scope :find => find_options do
143:             # Doing the find like this eliminates the possibility of errors occuring
144:             # on either missing records (out-of-sync) or an empty results array.
145:             records = find(:all, :conditions => [ "#{class_name.tableize}.id IN (?)", part_query])
146:             
147:             if find_options.include?(:order)
148:              records # Just return the records without ranking them.
149:            else
150:              # Results come back in random order from SQL, so order again.
151:              ranked_records = {}
152:              records.each do |r|
153:                ranked_records[r] = @query_cache[query][r.id]
154:              end
155:           
156:              ranked_records.to_a.sort{|a,b| b.last <=> a.last }.collect{|a| a.first}
157:            end
158:           end
159:           
160:         end

[Validate]