Class: ActsAsFerret::LocalIndex
- Inherits:
-
AbstractIndex
- Object
- AbstractIndex
- ActsAsFerret::LocalIndex
- Includes:
- MoreLikeThis::IndexMethods
- Defined in:
- lib/acts_as_ferret/local_index.rb
Instance Attribute Summary
Attributes inherited from AbstractIndex
#index_definition, #index_name, #logger, #registered_models_config
Instance Method Summary (collapse)
-
- (Object) add(record, analyzer = nil)
(also: #<<)
add record to index record may be the full AR object, a Ferret document instance or a Hash.
- - (Object) bulk_index(class_name, ids, options)
-
- (Object) close
Closes the underlying index instance.
-
- (Object) determine_stored_fields(options = {})
retrieves stored fields from index definition in case the fields to retrieve haven't been specified with the :lazy option.
-
- (Object) document_number(key)
retrieves the ferret document number of the record with the given key.
-
- (Object) ensure_index_exists
Checks for the presence of a segments file in the index directory Rebuilds the index if none exists.
-
- (Object) extract_stored_fields(doc, stored_fields)
loads data for fields declared as :lazy from the Ferret document.
-
- (Object) ferret_index
The 'real' Ferret Index instance.
-
- (Object) highlight(key, query, options = {})
highlight search terms for the record with the given id.
-
- (LocalIndex) initialize(index_name)
constructor
A new instance of LocalIndex.
-
- (Object) process_query(query, options = {})
Parses the given query string into a Ferret Query object.
-
- (Object) query_for_record(key)
build a ferret query matching only the record with the given id the class name only needs to be given in case of a shared index configuration.
-
- (Object) rebuild_index
rebuilds the index from all records of the model classes associated with this index.
-
- (Object) remove(key)
delete record from index.
- - (Object) reopen!
- - (Object) searcher
-
- (Object) total_hits(query, options = {})
Total number of hits for the given query.
Methods included from MoreLikeThis::IndexMethods
Methods inherited from AbstractIndex
#change_index_dir, #register_class, #shared?
Methods included from FerretFindMethods
#ar_find, #count_records, #find_id_model_arrays, #find_ids, #find_records, #lazy_find, #scope_query_to_models
Constructor Details
- (LocalIndex) initialize(index_name)
A new instance of LocalIndex
5 6 7 8 |
# File 'lib/acts_as_ferret/local_index.rb', line 5 def initialize(index_name) super ensure_index_exists end |
Instance Method Details
- (Object) add(record, analyzer = nil) Also known as: <<
add record to index record may be the full AR object, a Ferret document instance or a Hash
100 101 102 103 104 105 106 |
# File 'lib/acts_as_ferret/local_index.rb', line 100 def add(record, analyzer = nil) unless Hash === record || Ferret::Document === record analyzer = record.ferret_analyzer record = record.to_doc end ferret_index.add_document(record, analyzer) end |
- (Object) bulk_index(class_name, ids, options)
58 59 60 |
# File 'lib/acts_as_ferret/local_index.rb', line 58 def bulk_index(class_name, ids, ) ferret_index.bulk_index(class_name.constantize, ids, ) end |
- (Object) close
Closes the underlying index instance
36 37 38 39 40 41 42 |
# File 'lib/acts_as_ferret/local_index.rb', line 36 def close @ferret_index.close if @ferret_index rescue StandardError # is raised when index already closed ensure @ferret_index = nil end |
- (Object) determine_stored_fields(options = {})
retrieves stored fields from index definition in case the fields to retrieve haven't been specified with the :lazy option
163 164 165 166 167 168 169 170 |
# File 'lib/acts_as_ferret/local_index.rb', line 163 def determine_stored_fields( = {}) stored_fields = [:lazy] if stored_fields && !(Array === stored_fields) stored_fields = index_definition[:ferret_fields].select { |field, config| config[:store] == :yes }.map(&:first) end logger.debug "stored_fields: #{stored_fields.inspect}" return stored_fields end |
- (Object) document_number(key)
retrieves the ferret document number of the record with the given key.
137 138 139 140 141 142 143 |
# File 'lib/acts_as_ferret/local_index.rb', line 137 def document_number(key) docnum = ferret_index.doc_number(key) # hits = ferret_index.search query_for_record(key) # return hits.hits.first.doc if hits.total_hits == 1 raise "cannot determine document number for record #{key}" if docnum.nil? docnum end |
- (Object) ensure_index_exists
Checks for the presence of a segments file in the index directory Rebuilds the index if none exists.
27 28 29 30 31 32 33 |
# File 'lib/acts_as_ferret/local_index.rb', line 27 def ensure_index_exists #logger.debug "LocalIndex: ensure_index_exists at #{index_definition[:index_dir]}" unless File.file? "#{index_definition[:index_dir]}/segments" ActsAsFerret::ensure_directory(index_definition[:index_dir]) rebuild_index end end |
- (Object) extract_stored_fields(doc, stored_fields)
loads data for fields declared as :lazy from the Ferret document
173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/acts_as_ferret/local_index.rb', line 173 def extract_stored_fields(doc, stored_fields) data = {} unless stored_fields.nil? logger.debug "extracting stored fields #{stored_fields.inspect} from document #{doc[:class_name]} / #{doc[:id]}" fields = index_definition[:ferret_fields] stored_fields.each do |field| if field_cfg = fields[field] data[field_cfg[:via]] = doc[field] end end logger.debug "done: #{data.inspect}" end return data end |
- (Object) ferret_index
The 'real' Ferret Index instance
17 18 19 20 21 22 23 |
# File 'lib/acts_as_ferret/local_index.rb', line 17 def ferret_index ensure_index_exists (@ferret_index ||= Ferret::Index::Index.new(index_definition[:ferret])).tap do |idx| idx.batch_size = index_definition[:reindex_batch_size] idx.logger = logger end end |
- (Object) highlight(key, query, options = {})
highlight search terms for the record with the given id.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/acts_as_ferret/local_index.rb', line 115 def highlight(key, query, = {}) logger.debug("highlight: #{key} query: #{query}") .reverse_merge! :num_excerpts => 2, :pre_tag => '<em>', :post_tag => '</em>' highlights = [] ferret_index.synchronize do doc_num = document_number(key) if [:field] highlights << ferret_index.highlight(query, doc_num, ) else query = process_query(query) # process only once index_definition[:ferret_fields].each_pair do |field, config| next if config[:store] == :no || config[:highlight] == :no [:field] = field highlights << ferret_index.highlight(query, doc_num, ) end end end return highlights.compact.flatten[0..[:num_excerpts]-1] end |
- (Object) process_query(query, options = {})
Parses the given query string into a Ferret Query object.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/acts_as_ferret/local_index.rb', line 63 def process_query(query, = {}) return query unless String === query ferret_index.synchronize do if [:analyzer] # use per-query analyzer if present qp = Ferret::QueryParser.new ferret_index.instance_variable_get('@options').merge() reader = ferret_index.reader qp.fields = reader.fields unless [:all_fields] || [:fields] qp.tokenized_fields = reader.tokenized_fields unless [:tokenized_fields] return qp.parse query else return ferret_index.process_query(query) end end end |
- (Object) query_for_record(key)
build a ferret query matching only the record with the given id the class name only needs to be given in case of a shared index configuration
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/acts_as_ferret/local_index.rb', line 147 def query_for_record(key) return Ferret::Search::TermQuery.new(:key, key.to_s) # if shared? # raise InvalidArgumentError.new("shared index needs class_name argument") if class_name.nil? # Ferret::Search::BooleanQuery.new.tap do |bq| # bq.add_query(Ferret::Search::TermQuery.new(:id, id.to_s), :must) # bq.add_query(Ferret::Search::TermQuery.new(:class_name, class_name), :must) # end # else # Ferret::Search::TermQuery.new(:id, id.to_s) # end end |
- (Object) rebuild_index
rebuilds the index from all records of the model classes associated with this index
45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/acts_as_ferret/local_index.rb', line 45 def rebuild_index models = index_definition[:registered_models] logger.debug "rebuild index with models: #{models.inspect}" close index = Ferret::Index::Index.new(index_definition[:ferret].dup.update(:auto_flush => false, :field_infos => ActsAsFerret::field_infos(index_definition), :create => true)) index.batch_size = index_definition[:reindex_batch_size] index.logger = logger index.index_models models reopen! end |
- (Object) remove(key)
delete record from index
110 111 112 |
# File 'lib/acts_as_ferret/local_index.rb', line 110 def remove(key) ferret_index.delete key end |
- (Object) reopen!
10 11 12 13 14 |
# File 'lib/acts_as_ferret/local_index.rb', line 10 def reopen! logger.debug "reopening index at #{index_definition[:ferret][:path]}" close ferret_index end |
- (Object) searcher
86 87 88 |
# File 'lib/acts_as_ferret/local_index.rb', line 86 def searcher ferret_index end |
- (Object) total_hits(query, options = {})
Total number of hits for the given query.
82 83 84 |
# File 'lib/acts_as_ferret/local_index.rb', line 82 def total_hits(query, = {}) ferret_index.search(process_query(query, ), ).total_hits end |