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.

[Source]

    # File lib/acts_as_indexed.rb, line 33
33:         def acts_as_indexed(options = {})
34:           class_eval do
35:             extend Foo::Acts::Indexed::SingletonMethods
36:           end
37:           include Foo::Acts::Indexed::InstanceMethods
38: 
39:           after_create  :add_to_index
40:           before_update  :update_index
41:           after_destroy :remove_from_index
42: 
43:           cattr_accessor :aai_config
44: 
45:           # default config
46:           self.aai_config = { 
47:             :index_file => [RAILS_ROOT,'index',RAILS_ENV,name],
48:             :index_file_depth => 3,
49:             :min_word_size => 3,
50:             :fields => []
51:           }
52: 
53:           # set fields
54:           aai_config[:fields] = options[:fields] if options.include?(:fields)
55: 
56:           # set minimum word size if available.
57:           aai_config[:min_word_size] = options[:min_word_size] if options.include?(:min_word_size)
58: 
59:           # set index file depth if available.
60:           # Min size of 1.
61:           aai_config[:index_file_depth] = options[:index_file_depth].to_i if options.include?(:index_file_depth) && options[:index_file_depth].to_i > 0
62: 
63:           # Set file location for plugin testing.
64:           # TODO: Find more portable (ruby) way of doing the up-one-level.
65:           aai_config[:index_file] = [File.dirname(__FILE__),'../test/index',RAILS_ENV,name] if options.include?(:self_test)
66: 
67:         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 71
71:         def index_add(record)
72:           build_index if !File.exists?(File.join(aai_config[:index_file]))
73:           index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
74:           index.add_record(record)
75:           index.save
76:           @query_cache = {}
77:           true
78:         end

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

[Source]

    # File lib/acts_as_indexed.rb, line 82
82:         def index_remove(record)
83:           index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
84:           # record won't be in index if it doesn't exist. Just return true.
85:           return true if !index.exists?
86:           index.remove_record(record)
87:           index.save
88:           @query_cache = {}
89:           true
90:         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 96
 96:         def index_update(record)
 97:           build_index if !File.exists?(File.join(aai_config[:index_file]))
 98:           index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
 99:           #index.remove_record(find(record.id))
100:           #index.add_record(record)
101:           index.update_record(record,find(record.id))
102:           index.save
103:           @query_cache = {}
104:           true
105:         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

A hash passed on to active_record‘s find when retrieving the data from db, useful for pagination.

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 121
121:         def search_index(query, find_options={}, options={})
122:           # Clear the query cache off  if the key is set.
123:           @query_cache = {}  if (options.has_key?('no_query_cache') || options[:no_query_cache])
124:           if !@query_cache || !@query_cache[query]
125:             logger.debug('Query not in cache, running search.')
126:             build_index if !File.exists?(File.join(aai_config[:index_file]))
127:             index = SearchIndex.new(aai_config[:index_file], aai_config[:index_file_depth], aai_config[:fields], aai_config[:min_word_size])
128:             @query_cache = {} if !@query_cache
129:             @query_cache[query] = index.search(query)
130:           else
131:             logger.debug('Query held in cache.')
132:           end
133:           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?
134:           
135:           # slice up the results by offset and limit
136:           offset = find_options[:offset] || 0
137:           limit = find_options.include?(:limit) ? find_options[:limit] : @query_cache[query].size
138:           part_query = @query_cache[query].sort{|a,b| b <=> a }.slice(offset,limit).collect{|a| a.first}
139:           
140:           # Set these to nil as we are dealing with the pagination by setting
141:           # exactly what records we want.
142:           find_options[:offset] = nil
143:           find_options[:limit] = nil
144:           
145:           with_scope :find => find_options do
146:             # Doing the find like this eliminates the possibility of errors occuring
147:             # on either missing records (out-of-sync) or an empty results array.
148:             records = find(:all, :conditions => [ "#{class_name.tableize}.id IN (?)", part_query])
149:             
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:           
159:         end

[Validate]