| Class | Foo::Acts::Indexed::SearchIndex |
| In: |
lib/search_index.rb
|
| Parent: | Object |
| root: | Location of index on filesystem. |
| index_depth: | Degree of index partitioning. |
| fields: | Fields or instance methods of ActiveRecord model to be indexed. |
| min_word_size: | Smallest query term that will be run through search. |
# File lib/search_index.rb, line 15
15: def initialize(root, index_depth, fields, min_word_size)
16: @root = root
17: @fields = fields
18: @index_depth = index_depth
19: @atoms = {}
20: @min_word_size = min_word_size
21: @records_size = exists? ? load_record_size : 0
22: end
Adds record to the index.
# File lib/search_index.rb, line 25
25: def add_record(record)
26: condensed_record = condense_record(record)
27: load_atoms(condensed_record)
28: add_occurences(condensed_record,record.id)
29: @records_size += 1
30: end
Adds multiple records to the index. Accepts an array of records.
# File lib/search_index.rb, line 33
33: def add_records(records)
34: records.each do |r|
35: condensed_record = condense_record(r)
36: load_atoms(condensed_record)
37: add_occurences(condensed_record,r.id)
38: @records_size += 1
39: end
40: end
Deletes the current model‘s index from the filesystem.
# File lib/search_index.rb, line 93
93: def destroy
94: FileUtils.rm_rf(@root)
95: true
96: end
Returns true if the index root exists on the FS.
# File lib/search_index.rb, line 127
127: def exists?
128: File.exists?(File.join(@root))
129: end
Removes record from the index.
# File lib/search_index.rb, line 43
43: def remove_record(record)
44: atoms = condense_record(record)
45: load_atoms(atoms)
46: atoms.each do |a|
47: @atoms[a].remove_record(record.id) if @atoms.has_key?(a)
48: @records_size -= 1
49: #p "removing #{record.id} from #{a}"
50: end
51: end
Saves the current index partitions to the filesystem.
# File lib/search_index.rb, line 73
73: def save
74: prepare
75: atoms_sorted = {}
76: @atoms.each do |atom_name, records|
77: e_p = encoded_prefix(atom_name)
78: atoms_sorted[e_p] = {} if !atoms_sorted.has_key?(e_p)
79: atoms_sorted[e_p][atom_name] = records
80: end
81: atoms_sorted.each do |e_p, atoms|
82: #p "Saving #{e_p}."
83: File.open(File.join(@root + [e_p.to_s]),'w+') do |f|
84: Marshal.dump(atoms,f)
85: end
86: end
87: save_record_size
88: end
Returns an array of IDs for records matching query.
# File lib/search_index.rb, line 99
99: def search(query)
100: load_atoms(cleanup_atoms(query))
101: return [] if query.nil?
102: queries = parse_query(query.dup)
103: positive = run_queries(queries[:positive])
104: positive_quoted = run_quoted_queries(queries[:positive_quoted])
105: negative = run_queries(queries[:negative])
106: negative_quoted = run_quoted_queries(queries[:negative_quoted])
107:
108: if !queries[:positive].empty? && !queries[:positive_quoted].empty?
109: p = positive.delete_if{ |r_id,w| !positive_quoted.include?(r_id) }
110: pq = positive_quoted.delete_if{ |r_id,w| !positive.include?(r_id) }
111: results = p.merge(pq) { |r_id,old_val,new_val| old_val + new_val}
112: elsif !queries[:positive].empty?
113: results = positive
114: else
115: results = positive_quoted
116: end
117:
118: negative_results = (negative.keys + negative_quoted.keys)
119: results.delete_if { |r_id, w| negative_results.include?(r_id) }
120: #p results
121: results
122: end
# File lib/search_index.rb, line 53
53: def update_record(record_new, record_old)
54: # Work out which atoms have modifications.
55: # Minimises loading and saving of partitions.
56: old_atoms = condense_record(record_old)
57: new_atoms = condense_record(record_new)
58:
59: # Remove the old version from the appropriate atoms.
60: load_atoms(old_atoms)
61: old_atoms.each do |a|
62: @atoms[a].remove_record(record_new.id) if @atoms.has_key?(a)
63: end
64:
65: # Add the new version to the appropriate atoms.
66: load_atoms(new_atoms)
67: # TODO: Make a version of this method that takes the
68: # atomised version of the record.
69: add_occurences(new_atoms, record_new.id)
70: end