def search_index(query, find_options={}, options={})

      # Clear the query cache off  if the key is set.
      @query_cache = {}  if options[:no_query_cache]

      # Run the query if not already in cache.
      if !@query_cache || !@query_cache[query]
        build_index
        (@query_cache ||= {})[query] = new_index.search(query)
      end

      if options[:ids_only]
        find_option_keys = find_options.keys.map{ |k| k.to_sym }
        find_option_keys -= [:limit, :offset]
        if find_option_keys.any?
          raise ArgumentError, 'ids_only can not be combined with find option keys other than :offset or :limit'
        end
      end

      if find_options.include?(:order)
        part_query = @query_cache[query].map{ |r| r.first }

      else
        # slice up the results by offset and limit
        offset = find_options[:offset] || 0
        limit = find_options.include?(:limit) ? find_options[:limit] : @query_cache[query].size
        part_query = sort(@query_cache[query]).slice(offset,limit).map{ |r| r.first }

        # Set these to nil as we are dealing with the pagination by setting
        # exactly what records we want.
        find_options[:offset] = nil
        find_options[:limit] = nil
      end

      return part_query if options[:ids_only]

      with_scope :find => find_options do
        # Doing the find like this eliminates the possibility of errors occuring
        # on either missing records (out-of-sync) or an empty results array.
        records = find(:all, :conditions => [ "#{table_name}.#{primary_key} IN (?)", part_query])

        if find_options.include?(:order)
         records # Just return the records without ranking them.

         else
           # Results come back in random order from SQL, so order again.
           ranked_records = ActiveSupport::OrderedHash.new
           records.each do |r|
             ranked_records[r] = @query_cache[query][r.id]
           end

           sort(ranked_records.to_a).map{ |r| r.first }
         end
      end

    end
def search_index(query, find_options={}, options={})

      # Clear the query cache off  if the key is set.
      @query_cache = {}  if options[:no_query_cache]

      # Run the query if not already in cache.
      if !@query_cache || !@query_cache[query]
        build_index
        (@query_cache ||= {})[query] = new_index.search(query)
      end

      if options[:ids_only]
        find_option_keys = find_options.keys.map{ |k| k.to_sym }
        find_option_keys -= [:limit, :offset]
        if find_option_keys.any?
          raise ArgumentError, 'ids_only can not be combined with find option keys other than :offset or :limit'
        end
      end

      if find_options.include?(:order)
        part_query = @query_cache[query].map{ |r| r.first }

      else
        # slice up the results by offset and limit
        offset = find_options[:offset] || 0
        limit = find_options.include?(:limit) ? find_options[:limit] : @query_cache[query].size
        part_query = sort(@query_cache[query]).slice(offset,limit).map{ |r| r.first }

        # Set these to nil as we are dealing with the pagination by setting
        # exactly what records we want.
        find_options[:offset] = nil
        find_options[:limit] = nil
      end

      return part_query if options[:ids_only]

      with_scope :find => find_options do
        # Doing the find like this eliminates the possibility of errors occuring
        # on either missing records (out-of-sync) or an empty results array.
        records = find(:all, :conditions => [ "#{table_name}.#{primary_key} IN (?)", part_query])

        if find_options.include?(:order)
         records # Just return the records without ranking them.

         else
           # Results come back in random order from SQL, so order again.
           ranked_records = ActiveSupport::OrderedHash.new
           records.each do |r|
             ranked_records[r] = @query_cache[query][r.id]
           end

           sort(ranked_records.to_a).map{ |r| r.first }
         end
      end

    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.