Class: Searchkick::Index
- Inherits:
-
Object
- Object
- Searchkick::Index
- Includes:
- IndexWithInstrumentation
- Defined in:
- lib/searchkick/index.rb
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
- #alias_exists? ⇒ Boolean
- #all_indices(unaliased: false) ⇒ Object
- #batches_left ⇒ Object
- #bulk_delete(records) ⇒ Object
- #bulk_index(records) ⇒ Object (also: #import)
- #bulk_update(records, method_name) ⇒ Object
-
#clean_indices ⇒ Object
remove old indices that start w/ index_name.
-
#conversions_fields ⇒ Object
should not be public.
- #create(body = {}) ⇒ Object
- #create_index(index_options: nil) ⇒ Object
- #delete ⇒ Object
- #document_type(record) ⇒ Object
- #exists? ⇒ Boolean
- #import_scope(relation, **options) ⇒ Object
- #index_options ⇒ Object
-
#initialize(name, options = {}) ⇒ Index
constructor
A new instance of Index.
-
#klass_document_type(klass, ignore_type = false) ⇒ Object
other.
- #locations_fields ⇒ Object
- #mapping ⇒ Object
- #promote(new_name, update_refresh_interval: false) ⇒ Object (also: #swap)
- #refresh ⇒ Object
- #refresh_interval ⇒ Object
-
#reindex(relation, method_name, scoped:, full: false, scope: nil, **options) ⇒ Object
reindex.
-
#reindex_queue ⇒ Object
queue.
- #reload_synonyms ⇒ Object
- #remove(record) ⇒ Object
- #retrieve(record) ⇒ Object
- #search_id(record) ⇒ Object
- #settings ⇒ Object
- #similar_record(record, **options) ⇒ Object
-
#store(record) ⇒ Object
record based use helpers for notifications.
- #suggest_fields ⇒ Object
- #tokens(text, options = {}) ⇒ Object
- #total_docs ⇒ Object
- #update_record(record, method_name) ⇒ Object
- #update_settings(settings) ⇒ Object
-
#uuid ⇒ Object
private.
Constructor Details
#initialize(name, options = {}) ⇒ Index
Returns a new instance of Index.
7 8 9 10 11 |
# File 'lib/searchkick/index.rb', line 7 def initialize(name, = {}) @name = name @options = @klass_document_type = {} # cache end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
5 6 7 |
# File 'lib/searchkick/index.rb', line 5 def name @name end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
5 6 7 |
# File 'lib/searchkick/index.rb', line 5 def @options end |
Instance Method Details
#alias_exists? ⇒ Boolean
39 40 41 |
# File 'lib/searchkick/index.rb', line 39 def alias_exists? client.indices.exists_alias name: name end |
#all_indices(unaliased: false) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/searchkick/index.rb', line 104 def all_indices(unaliased: false) indices = begin if client.indices.respond_to?(:get_alias) client.indices.get_alias else client.indices.get_aliases end rescue Elasticsearch::Transport::Transport::Errors::NotFound {} end indices = indices.select { |_k, v| v.empty? || v["aliases"].empty? } if unaliased indices.select { |k, _v| k =~ /\A#{Regexp.escape(name)}_\d{14,17}\z/ }.keys end |
#batches_left ⇒ Object
235 236 237 |
# File 'lib/searchkick/index.rb', line 235 def batches_left bulk_indexer.batches_left end |
#bulk_delete(records) ⇒ Object
143 144 145 |
# File 'lib/searchkick/index.rb', line 143 def bulk_delete(records) bulk_indexer.bulk_delete(records) end |
#bulk_index(records) ⇒ Object Also known as: import
147 148 149 |
# File 'lib/searchkick/index.rb', line 147 def bulk_index(records) bulk_indexer.bulk_index(records) end |
#bulk_update(records, method_name) ⇒ Object
152 153 154 |
# File 'lib/searchkick/index.rb', line 152 def bulk_update(records, method_name) bulk_indexer.bulk_update(records, method_name) end |
#clean_indices ⇒ Object
remove old indices that start w/ index_name
120 121 122 123 124 125 126 |
# File 'lib/searchkick/index.rb', line 120 def clean_indices indices = all_indices(unaliased: true) indices.each do |index| Searchkick::Index.new(index).delete end indices end |
#conversions_fields ⇒ Object
should not be public
254 255 256 257 258 259 |
# File 'lib/searchkick/index.rb', line 254 def conversions_fields @conversions_fields ||= begin conversions = Array([:conversions]) conversions.map(&:to_s) + conversions.map(&:to_sym) end end |
#create(body = {}) ⇒ Object
17 18 19 |
# File 'lib/searchkick/index.rb', line 17 def create(body = {}) client.indices.create index: name, body: body end |
#create_index(index_options: nil) ⇒ Object
224 225 226 227 228 229 |
# File 'lib/searchkick/index.rb', line 224 def create_index(index_options: nil) ||= self. index = Searchkick::Index.new("#{name}_#{Time.now.strftime('%Y%m%d%H%M%S%L')}", @options) index.create() index end |
#delete ⇒ Object
21 22 23 24 25 26 27 28 29 |
# File 'lib/searchkick/index.rb', line 21 def delete if alias_exists? # can't call delete directly on aliases in ES 6 indices = client.indices.get_alias(name: name).keys client.indices.delete index: indices else client.indices.delete index: name end end |
#document_type(record) ⇒ Object
160 161 162 |
# File 'lib/searchkick/index.rb', line 160 def document_type(record) RecordData.new(self, record).document_type end |
#exists? ⇒ Boolean
31 32 33 |
# File 'lib/searchkick/index.rb', line 31 def exists? client.indices.exists index: name end |
#import_scope(relation, **options) ⇒ Object
231 232 233 |
# File 'lib/searchkick/index.rb', line 231 def import_scope(relation, **) bulk_indexer.import_scope(relation, **) end |
#index_options ⇒ Object
13 14 15 |
# File 'lib/searchkick/index.rb', line 13 def IndexOptions.new(self). end |
#klass_document_type(klass, ignore_type = false) ⇒ Object
other
241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/searchkick/index.rb', line 241 def klass_document_type(klass, ignore_type = false) @klass_document_type[[klass, ignore_type]] ||= begin if !ignore_type && klass.searchkick_klass.[:_type] type = klass.searchkick_klass.[:_type] type = type.call if type.respond_to?(:call) type else klass.model_name.to_s.underscore end end end |
#locations_fields ⇒ Object
265 266 267 268 269 270 |
# File 'lib/searchkick/index.rb', line 265 def locations_fields @locations_fields ||= begin locations = Array([:locations]) locations.map(&:to_s) + locations.map(&:to_sym) end end |
#mapping ⇒ Object
43 44 45 |
# File 'lib/searchkick/index.rb', line 43 def mapping client.indices.get_mapping index: name end |
#promote(new_name, update_refresh_interval: false) ⇒ Object Also known as: swap
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/searchkick/index.rb', line 76 def promote(new_name, update_refresh_interval: false) if update_refresh_interval new_index = Searchkick::Index.new(new_name, @options) settings = [:settings] || {} refresh_interval = (settings[:index] && settings[:index][:refresh_interval]) || "1s" new_index.update_settings(index: {refresh_interval: refresh_interval}) end old_indices = begin client.indices.get_alias(name: name).keys rescue Elasticsearch::Transport::Transport::Errors::NotFound {} end actions = old_indices.map { |old_name| {remove: {index: old_name, alias: name}} } + [{add: {index: new_name, alias: name}}] client.indices.update_aliases body: {actions: actions} end |
#refresh ⇒ Object
35 36 37 |
# File 'lib/searchkick/index.rb', line 35 def refresh client.indices.refresh index: name end |
#refresh_interval ⇒ Object
51 52 53 |
# File 'lib/searchkick/index.rb', line 51 def refresh_interval index_settings["refresh_interval"] end |
#reindex(relation, method_name, scoped:, full: false, scope: nil, **options) ⇒ Object
reindex
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/searchkick/index.rb', line 198 def reindex(relation, method_name, scoped:, full: false, scope: nil, **) refresh = .fetch(:refresh, !scoped) .delete(:refresh) if method_name # TODO throw ArgumentError Searchkick.warn("unsupported keywords: #{.keys.map(&:inspect).join(", ")}") if .any? # update import_scope(relation, method_name: method_name, scope: scope) self.refresh if refresh true elsif scoped && !full # TODO throw ArgumentError Searchkick.warn("unsupported keywords: #{.keys.map(&:inspect).join(", ")}") if .any? # reindex association import_scope(relation, scope: scope) self.refresh if refresh true else # full reindex reindex_scope(relation, scope: scope, **) end end |
#reindex_queue ⇒ Object
queue
192 193 194 |
# File 'lib/searchkick/index.rb', line 192 def reindex_queue Searchkick::ReindexQueue.new(name) end |
#reload_synonyms ⇒ Object
179 180 181 182 183 184 185 186 187 188 |
# File 'lib/searchkick/index.rb', line 179 def reload_synonyms require "elasticsearch/xpack" raise Error, "Requires Elasticsearch 7.3+" if Searchkick.server_below?("7.3.0") raise Error, "Requires elasticsearch-xpack 7.8+" unless client.xpack.respond_to?(:indices) begin client.xpack.indices.reload_search_analyzers(index: name) rescue Elasticsearch::Transport::Transport::Errors::MethodNotAllowed raise Error, "Requires non-OSS version of Elasticsearch" end end |
#remove(record) ⇒ Object
135 136 137 |
# File 'lib/searchkick/index.rb', line 135 def remove(record) bulk_indexer.bulk_delete([record]) end |
#retrieve(record) ⇒ Object
95 96 97 98 99 100 101 102 |
# File 'lib/searchkick/index.rb', line 95 def retrieve(record) record_data = RecordData.new(self, record).record_data # remove underscore = Hash[record_data.map { |k, v| [k.to_s.sub(/\A_/, "").to_sym, v] }] client.get()["_source"] end |
#search_id(record) ⇒ Object
156 157 158 |
# File 'lib/searchkick/index.rb', line 156 def search_id(record) RecordData.new(self, record).search_id end |
#settings ⇒ Object
47 48 49 |
# File 'lib/searchkick/index.rb', line 47 def settings client.indices.get_settings index: name end |
#similar_record(record, **options) ⇒ Object
164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/searchkick/index.rb', line 164 def similar_record(record, **) like_text = retrieve(record).to_hash .keep_if { |k, _| ![:fields] || [:fields].map(&:to_s).include?(k) } .values.compact.join(" ") [:where] ||= {} [:where][:_id] ||= {} [:where][:_id][:not] = Array([:where][:_id][:not]) + [record.id.to_s] [:per_page] ||= 10 [:similar] = true # TODO use index class instead of record class Searchkick.search(like_text, model: record.class, **) end |
#store(record) ⇒ Object
record based use helpers for notifications
131 132 133 |
# File 'lib/searchkick/index.rb', line 131 def store(record) bulk_indexer.bulk_index([record]) end |
#suggest_fields ⇒ Object
261 262 263 |
# File 'lib/searchkick/index.rb', line 261 def suggest_fields @suggest_fields ||= Array([:suggest]).map(&:to_s) end |
#tokens(text, options = {}) ⇒ Object
59 60 61 |
# File 'lib/searchkick/index.rb', line 59 def tokens(text, = {}) client.indices.analyze(body: {text: text}.merge(), index: name)["tokens"].map { |t| t["token"] } end |
#total_docs ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/searchkick/index.rb', line 63 def total_docs response = client.search( index: name, body: { query: {match_all: {}}, size: 0 } ) Searchkick::Results.new(nil, response).total_count end |
#update_record(record, method_name) ⇒ Object
139 140 141 |
# File 'lib/searchkick/index.rb', line 139 def update_record(record, method_name) bulk_indexer.bulk_update([record], method_name) end |
#update_settings(settings) ⇒ Object
55 56 57 |
# File 'lib/searchkick/index.rb', line 55 def update_settings(settings) client.indices.put_settings index: name, body: settings end |
#uuid ⇒ Object
private
273 274 275 |
# File 'lib/searchkick/index.rb', line 273 def uuid index_settings["uuid"] end |