Module: Searchkick

Defined in:
lib/searchkick.rb,
lib/searchkick/index.rb,
lib/searchkick/model.rb,
lib/searchkick/query.rb,
lib/searchkick/indexer.rb,
lib/searchkick/logging.rb,
lib/searchkick/results.rb,
lib/searchkick/version.rb,
lib/searchkick/middleware.rb,
lib/searchkick/record_data.rb,
lib/searchkick/bulk_indexer.rb,
lib/searchkick/hash_wrapper.rb,
lib/searchkick/multi_search.rb,
lib/searchkick/index_options.rb,
lib/searchkick/reindex_queue.rb,
lib/searchkick/record_indexer.rb,
lib/searchkick/reindex_v2_job.rb,
lib/searchkick/bulk_reindex_job.rb,
lib/searchkick/process_batch_job.rb,
lib/searchkick/process_queue_job.rb

Defined Under Namespace

Modules: ControllerRuntime, IndexOptions, IndexWithInstrumentation, IndexerWithInstrumentation, Model, QueryWithInstrumentation, SearchkickWithInstrumentation Classes: BulkIndexer, BulkReindexJob, DangerousOperation, Error, HashWrapper, ImportError, Index, Indexer, InvalidQueryError, LogSubscriber, Middleware, MissingIndexError, MultiSearch, ProcessBatchJob, ProcessQueueJob, Query, RecordData, RecordIndexer, ReindexQueue, ReindexV2Job, Results, UnsupportedVersionError

Constant Summary collapse

VERSION =
"4.0.2"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.aws_credentialsObject

Returns the value of attribute aws_credentials.



40
41
42
# File 'lib/searchkick.rb', line 40

def aws_credentials
  @aws_credentials
end

.clientObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/searchkick.rb', line 50

def self.client
  @client ||= begin
    require "typhoeus/adapters/faraday" if defined?(Typhoeus)

    Elasticsearch::Client.new({
      url: ENV["ELASTICSEARCH_URL"],
      transport_options: {request: {timeout: timeout}, headers: {content_type: "application/json"}},
      retry_on_failure: 2
    }.deep_merge(client_options)) do |f|
      f.use Searchkick::Middleware
      f.request signer_middleware_key, signer_middleware_aws_params if aws_credentials
    end
  end
end

.client_optionsObject

Returns the value of attribute client_options.



38
39
40
# File 'lib/searchkick.rb', line 38

def client_options
  @client_options
end

.envObject



65
66
67
# File 'lib/searchkick.rb', line 65

def self.env
  @env ||= ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
end

.index_prefixObject

Returns the value of attribute index_prefix.



38
39
40
# File 'lib/searchkick.rb', line 38

def index_prefix
  @index_prefix
end

.index_suffixObject

Returns the value of attribute index_suffix.



38
39
40
# File 'lib/searchkick.rb', line 38

def index_suffix
  @index_suffix
end

.model_optionsObject

Returns the value of attribute model_options.



38
39
40
# File 'lib/searchkick.rb', line 38

def model_options
  @model_options
end

.modelsObject

Returns the value of attribute models.



38
39
40
# File 'lib/searchkick.rb', line 38

def models
  @models
end

.queue_nameObject

Returns the value of attribute queue_name.



38
39
40
# File 'lib/searchkick.rb', line 38

def queue_name
  @queue_name
end

.redisObject

Returns the value of attribute redis.



38
39
40
# File 'lib/searchkick.rb', line 38

def redis
  @redis
end

.search_method_nameObject

Returns the value of attribute search_method_name.



38
39
40
# File 'lib/searchkick.rb', line 38

def search_method_name
  @search_method_name
end

.search_timeoutObject



69
70
71
# File 'lib/searchkick.rb', line 69

def self.search_timeout
  (defined?(@search_timeout) && @search_timeout) || timeout
end

.timeoutObject

Returns the value of attribute timeout.



38
39
40
# File 'lib/searchkick.rb', line 38

def timeout
  @timeout
end

.wordnet_pathObject

Returns the value of attribute wordnet_path.



38
39
40
# File 'lib/searchkick.rb', line 38

def wordnet_path
  @wordnet_path
end

Class Method Details

.callbacks(value) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/searchkick.rb', line 145

def self.callbacks(value)
  if block_given?
    previous_value = callbacks_value
    begin
      self.callbacks_value = value
      result = yield
      indexer.perform if callbacks_value == :bulk
      result
    ensure
      self.callbacks_value = previous_value
    end
  else
    self.callbacks_value = value
  end
end

.callbacks?(default: true) ⇒ Boolean

Returns:

  • (Boolean)


137
138
139
140
141
142
143
# File 'lib/searchkick.rb', line 137

def self.callbacks?(default: true)
  if callbacks_value.nil?
    default
  else
    callbacks_value != false
  end
end

.callbacks_valueObject

private



222
223
224
# File 'lib/searchkick.rb', line 222

def self.callbacks_value
  Thread.current[:searchkick_callbacks_enabled]
end

.callbacks_value=(value) ⇒ Object

private



227
228
229
# File 'lib/searchkick.rb', line 227

def self.callbacks_value=(value)
  Thread.current[:searchkick_callbacks_enabled] = value
end

.disable_callbacksObject



133
134
135
# File 'lib/searchkick.rb', line 133

def self.disable_callbacks
  self.callbacks_value = false
end

.enable_callbacksObject

callbacks



129
130
131
# File 'lib/searchkick.rb', line 129

def self.enable_callbacks
  self.callbacks_value = nil
end

.indexerObject

private



217
218
219
# File 'lib/searchkick.rb', line 217

def self.indexer
  Thread.current[:searchkick_indexer] ||= Searchkick::Indexer.new
end

.load_records(records, ids) ⇒ Object

private

Raises:



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/searchkick.rb', line 196

def self.load_records(records, ids)
  records =
    if records.respond_to?(:primary_key)
      # ActiveRecord
      records.where(records.primary_key => ids) if records.primary_key
    elsif records.respond_to?(:queryable)
      # Mongoid 3+
      records.queryable.for_ids(ids)
    elsif records.respond_to?(:unscoped) && :id.respond_to?(:in)
      # Nobrainer
      records.unscoped.where(:id.in => ids)
    elsif records.respond_to?(:key_column_names)
      records.where(records.key_column_names.first => ids)
    end

  raise Searchkick::Error, "Not sure how to load records" if !records

  records
end

.multi_search(queries) ⇒ Object



123
124
125
# File 'lib/searchkick.rb', line 123

def self.multi_search(queries)
  Searchkick::MultiSearch.new(queries).perform
end

.reindex_status(index_name) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/searchkick.rb', line 171

def self.reindex_status(index_name)
  if redis
    batches_left = Searchkick::Index.new(index_name).batches_left
    {
      completed: batches_left == 0,
      batches_left: batches_left
    }
  else
    raise Searchkick::Error, "Redis not configured"
  end
end

.search(term = "*", model: nil, **options, &block) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/searchkick.rb', line 89

def self.search(term = "*", model: nil, **options, &block)
  options = options.dup
  klass = model

  # convert index_name into models if possible
  # this should allow for easier upgrade
  if options[:index_name] && !options[:models] && Array(options[:index_name]).all? { |v| v.respond_to?(:searchkick_index) }
    options[:models] = options.delete(:index_name)
  end

  # make Searchkick.search(models: [Product]) and Product.search equivalent
  unless klass
    models = Array(options[:models])
    if models.size == 1
      klass = models.first
      options.delete(:models)
    end
  end

  if klass
    if (options[:models] && Array(options[:models]) != [klass]) || Array(options[:index_name]).any? { |v| v.respond_to?(:searchkick_index) && v != klass }
      raise ArgumentError, "Use Searchkick.search to search multiple models"
    end
  end

  options = options.merge(block: block) if block
  query = Searchkick::Query.new(klass, term, options)
  if options[:execute] == false
    query
  else
    query.execute
  end
end

.server_below7?Boolean

memoize for performance

Returns:

  • (Boolean)


82
83
84
85
86
87
# File 'lib/searchkick.rb', line 82

def self.server_below7?
  unless defined?(@server_below7)
    @server_below7 = server_below?("7.0.0")
  end
  @server_below7
end

.server_below?(version) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/searchkick.rb', line 77

def self.server_below?(version)
  Gem::Version.new(server_version.split("-")[0]) < Gem::Version.new(version.split("-")[0])
end

.server_versionObject



73
74
75
# File 'lib/searchkick.rb', line 73

def self.server_version
  @server_version ||= client.info["version"]["number"]
end

.signer_middleware_aws_paramsObject

private



237
238
239
240
241
242
243
244
245
246
247
# File 'lib/searchkick.rb', line 237

def self.signer_middleware_aws_params
  if signer_middleware_key == :aws_sigv4
    {service: "es", region: "us-east-1"}.merge(aws_credentials)
  else
    {
      credentials: aws_credentials[:credentials] || Aws::Credentials.new(aws_credentials[:access_key_id], aws_credentials[:secret_access_key]),
      service_name: "es",
      region: aws_credentials[:region] || "us-east-1"
    }
  end
end

.signer_middleware_keyObject

private



232
233
234
# File 'lib/searchkick.rb', line 232

def self.signer_middleware_key
  defined?(FaradayMiddleware::AwsSignersV4) ? :aws_signers_v4 : :aws_sigv4
end

.with_redisObject



183
184
185
186
187
188
189
190
191
192
193
# File 'lib/searchkick.rb', line 183

def self.with_redis
  if redis
    if redis.respond_to?(:with)
      redis.with do |r|
        yield r
      end
    else
      yield redis
    end
  end
end