Class: SearchFlip::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/search_flip/connection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Connection

Creates a new connection.

Examples:

SearchFlip::Connection.new(base_url: "http://elasticsearch.host:9200")

Parameters:

  • options (Hash) (defaults to: {})

    A hash containing the config options

Options Hash (options):

  • base_url (String)

    The base url for the connection

  • http_client (SearchFlip::HTTPClient)

    An optional http client instance

  • bulk_max_mb (Fixnum)

    An optional MB limit for bulk requests



15
16
17
18
19
# File 'lib/search_flip/connection.rb', line 15

def initialize(options = {})
  @base_url = options[:base_url] || SearchFlip::Config[:base_url]
  @http_client = options[:http_client] || SearchFlip::HTTPClient.new
  @bulk_limit = options[:bulk_limit] || SearchFlip::Config[:bulk_limit]
end

Instance Attribute Details

#base_urlObject (readonly)

Returns the value of attribute base_url.



3
4
5
# File 'lib/search_flip/connection.rb', line 3

def base_url
  @base_url
end

#bulk_limitObject (readonly)

Returns the value of attribute bulk_limit.



3
4
5
# File 'lib/search_flip/connection.rb', line 3

def bulk_limit
  @bulk_limit
end

#bulk_max_mbObject (readonly)

Returns the value of attribute bulk_max_mb.



3
4
5
# File 'lib/search_flip/connection.rb', line 3

def bulk_max_mb
  @bulk_max_mb
end

#http_clientObject (readonly)

Returns the value of attribute http_client.



3
4
5
# File 'lib/search_flip/connection.rb', line 3

def http_client
  @http_client
end

Instance Method Details

#alias_exists?(alias_name) ⇒ Boolean

Returns whether or not the associated Elasticsearch alias already exists.

Examples:

connection.alias_exists?("some_alias")

Returns:

  • (Boolean)

    Whether or not the alias exists



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

def alias_exists?(alias_name)
  http_client
    .headers(accept: "application/json", content_type: "application/json")
    .get("#{base_url}/_alias/#{alias_name}")

  true
rescue SearchFlip::ResponseError => e
  return false if e.code == 404

  raise e
end

#analyze(request, params = {}) ⇒ Hash

Sends an analyze request to Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur.

Examples:

connection.analyze(analyzer: "standard", text: "this is a test")

Returns:

  • (Hash)

    The raw response



147
148
149
150
151
152
153
# File 'lib/search_flip/connection.rb', line 147

def analyze(request, params = {})
  response = http_client
    .headers(accept: "application/json")
    .post("#{base_url}/_analyze", json: request, params: params)

  SearchFlip::JSON.parse(response.to_s)
end

#bulk(options = {}) ⇒ Object

Initiates and yields a bulk object, such that index, import, create, update and delete requests can be appended to the bulk request. Please note that you need to manually pass the desired index name as well as type name (depending on the Elasticsearch version) when using #bulk on a connection object or Elasticsearch will return an error. After the bulk requests are successfully processed all existing indices will subsequently be refreshed when auto_refresh is enabled.

Examples:

connection = SearchFlip::Connection.new

connection.bulk ignore_errors: [409] do |bulk|
  bulk.create comment.id, CommentIndex.serialize(comment),
    _index: CommentIndex.index_name, version: comment.version, version_type: "external_gte"

  bulk.delete product.id, _index: ProductIndex.index_name, routing: product.user_id

  # ...
end

Parameters:

  • options (Hash) (defaults to: {})

    Specifies options regarding the bulk indexing

Options Hash (options):

  • ignore_errors (Array)

    Specifies an array of http status codes that shouldn’t raise any exceptions, like eg 409 for conflicts, ie when optimistic concurrency control is used.

  • raise (Boolean)

    Prevents any exceptions from being raised. Please note that this only applies to the bulk response, not to the request in general, such that connection errors, etc will still raise.

See Also:



422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/search_flip/connection.rb', line 422

def bulk(options = {})
  default_options = {
    http_client: http_client,
    bulk_limit: bulk_limit,
    bulk_max_mb: bulk_max_mb
  }

  SearchFlip::Bulk.new("#{base_url}/_bulk", default_options.merge(options)) do |indexer|
    yield indexer
  end

  refresh if SearchFlip::Config[:auto_refresh]
end

#close_index(index_name) ⇒ Boolean

Closes the specified index within Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur

Parameters:

  • index_name (String)

    The index name

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



236
237
238
239
240
# File 'lib/search_flip/connection.rb', line 236

def close_index(index_name)
  http_client.post("#{index_url(index_name)}/_close")

  true
end

#cluster_healthHash

Queries and returns the Elasticsearch cluster health.

Examples:

connection.cluster_health # => { "status" => "green", ... }

Returns:

  • (Hash)

    The raw response



79
80
81
82
83
# File 'lib/search_flip/connection.rb', line 79

def cluster_health
  response = http_client.headers(accept: "application/json").get("#{base_url}/_cluster/health")

  SearchFlip::JSON.parse(response.to_s)
end

#create_index(index_name, index_settings = {}, params = {}) ⇒ Boolean

Creates the specified index within Elasticsearch and applies index settings, if specified. Raises SearchFlip::ResponseError in case any errors occur.

Parameters:

  • index_name (String)

    The index name

  • index_settings (Hash) (defaults to: {})

    The index settings

  • params (Hash) (defaults to: {})

    Optional url params

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



223
224
225
226
227
# File 'lib/search_flip/connection.rb', line 223

def create_index(index_name, index_settings = {}, params = {})
  http_client.put(index_url(index_name), params: params, json: index_settings)

  true
end

#delete_index(index_name) ⇒ Boolean

Deletes the specified index from Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur.

Parameters:

  • index_name (String)

    The index name

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



369
370
371
372
373
# File 'lib/search_flip/connection.rb', line 369

def delete_index(index_name)
  http_client.delete index_url(index_name)

  true
end

#distributionString

Queries and returns the Elasticsearch distribution used.

Examples:

connection.distribution # => e.g. "opensearch"

Returns:

  • (String)

    The Elasticsearch distribution



28
29
30
# File 'lib/search_flip/connection.rb', line 28

def distribution
  @distribution ||= SearchFlip::Config.dig(:version, :distribution) || SearchFlip::JSON.parse(version_response.to_s)["version"]["distribution"]
end

#freeze_index(index_name) ⇒ Boolean

Freezes the specified index within Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur

Parameters:

  • index_name (String)

    The index name

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



262
263
264
265
266
# File 'lib/search_flip/connection.rb', line 262

def freeze_index(index_name)
  http_client.post("#{index_url(index_name)}/_freeze")

  true
end

#get_aliases(index_name: "*", alias_name: "*") ⇒ Hash

Fetches information about the specified index aliases. Raises SearchFlip::ResponseError in case any errors occur.

Examples:

connection.get_aliases(alias_name: "some_alias")
connection.get_aliases(index_name: "index1,index2")

Parameters:

  • alias_name (String) (defaults to: "*")

    The alias or comma separated list of alias names

  • index_name (String) (defaults to: "*")

    The index or comma separated list of index names

Returns:

  • (Hash)

    The raw response



167
168
169
170
171
172
173
# File 'lib/search_flip/connection.rb', line 167

def get_aliases(index_name: "*", alias_name: "*")
  response = http_client
    .headers(accept: "application/json", content_type: "application/json")
    .get("#{base_url}/#{index_name}/_alias/#{alias_name}")

  SearchFlip::JSON.parse(response.to_s)
end

#get_cluster_settingsHash

Queries the cluster settings from Elasticsearch

Examples:

connection.get_cluster_settings
# => { "persistent" => { ... }, ... }

Returns:

  • (Hash)

    The cluster settings



40
41
42
43
44
# File 'lib/search_flip/connection.rb', line 40

def get_cluster_settings
  response = http_client.get("#{base_url}/_cluster/settings")

  SearchFlip::JSON.parse(response.to_s)
end

#get_index_settings(index_name) ⇒ Hash

Fetches the index settings for the specified index from Elasticsearch. Sends a GET request to index_url/_settings. Raises SearchFlip::ResponseError in case any errors occur.

Parameters:

  • index_name (String)

    The index name

Returns:

  • (Hash)

    The index settings



304
305
306
307
308
309
310
# File 'lib/search_flip/connection.rb', line 304

def get_index_settings(index_name)
  response = http_client
    .headers(accept: "application/json")
    .get("#{index_url(index_name)}/_settings")

  SearchFlip::JSON.parse(response.to_s)
end

#get_indices(name = "*", params: {}) ⇒ Array Also known as: cat_indices

Fetches information about the specified indices. Raises SearchFlip::ResponseError in case any errors occur.

Examples:

connection.get_indices('prefix*')

Returns:

  • (Array)

    The raw response



203
204
205
206
207
208
209
# File 'lib/search_flip/connection.rb', line 203

def get_indices(name = "*", params: {})
  response = http_client
    .headers(accept: "application/json", content_type: "application/json")
    .get("#{base_url}/_cat/indices/#{name}", params: params)

  SearchFlip::JSON.parse(response.to_s)
end

#get_mapping(index_name, type_name: nil) ⇒ Hash

Retrieves the mapping for the specified index and type from Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur.

Parameters:

  • index_name (String)

    The index name

  • type_name (String) (defaults to: nil)

    The type name. Starting with Elasticsearch 7, the type name is optional.

Returns:

  • (Hash)

    The current type mapping



353
354
355
356
357
358
359
360
# File 'lib/search_flip/connection.rb', line 353

def get_mapping(index_name, type_name: nil)
  url = type_name && distribution.nil? && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
  params = type_name && distribution.nil? && version.to_f >= 6.7 && version.to_i < 8 ? { include_type_name: true } : {}

  response = http_client.headers(accept: "application/json").get("#{url}/_mapping", params: params)

  SearchFlip::JSON.parse(response.to_s)
end

#index_exists?(index_name) ⇒ Boolean

Returns whether or not the specified index already exists.

Parameters:

  • index_name (String)

    The index name

Returns:

  • (Boolean)

    Whether or not the index exists



381
382
383
384
385
386
387
388
389
# File 'lib/search_flip/connection.rb', line 381

def index_exists?(index_name)
  http_client.headers(accept: "application/json").head(index_url(index_name))

  true
rescue SearchFlip::ResponseError => e
  return false if e.code == 404

  raise e
end

#index_url(index_name) ⇒ String

Returns the Elasticsearch index URL for the specified index name, ie base URL and index name with prefix.

Parameters:

  • index_name (String)

    The index name

Returns:

  • (String)

    The Elasticsearch index URL



455
456
457
# File 'lib/search_flip/connection.rb', line 455

def index_url(index_name)
  "#{base_url}/#{index_name}"
end

#msearch(criterias) ⇒ Array<SearchFlip::Response>

Uses the Elasticsearch Multi Search API to execute multiple search requests within a single request. Raises SearchFlip::ResponseError in case any errors occur.

Examples:

connection.msearch [ProductIndex.match_all, CommentIndex.match_all]

Parameters:

Returns:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/search_flip/connection.rb', line 97

def msearch(criterias)
  payload = criterias.flat_map do |criteria|
    [
      SearchFlip::JSON.generate(index: criteria.target.index_name_with_prefix, **(distribution.nil? && version.to_i < 8 ? { type: criteria.target.type_name } : {})),
      SearchFlip::JSON.generate(criteria.request)
    ]
  end

  payload = payload.join("\n")
  payload << "\n"

  raw_response =
    http_client
      .headers(accept: "application/json", content_type: "application/x-ndjson")
      .post("#{base_url}/_msearch", body: payload)

  SearchFlip::JSON.parse(raw_response.to_s)["responses"].map.with_index do |response, index|
    SearchFlip::Response.new(criterias[index], response)
  end
end

#open_index(index_name) ⇒ Boolean

Opens the specified index within Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur

Parameters:

  • index_name (String)

    The index name

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



249
250
251
252
253
# File 'lib/search_flip/connection.rb', line 249

def open_index(index_name)
  http_client.post("#{index_url(index_name)}/_open")

  true
end

#refresh(index_names = nil) ⇒ Boolean

Sends a refresh request to Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur.

Parameters:

  • index_names (String, Array) (defaults to: nil)

    The optional index names to refresh

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



318
319
320
321
322
# File 'lib/search_flip/connection.rb', line 318

def refresh(index_names = nil)
  http_client.post("#{index_names ? index_url(Array(index_names).join(",")) : base_url}/_refresh")

  true
end

#type_url(index_name, type_name) ⇒ String

Returns the full Elasticsearch type URL, ie base URL, index name with prefix and type name.

Parameters:

  • index_name (String)

    The index name

  • type_name (String)

    The type name

Returns:

  • (String)

    The Elasticsearch type URL



444
445
446
# File 'lib/search_flip/connection.rb', line 444

def type_url(index_name, type_name)
  "#{index_url(index_name)}/#{type_name}"
end

#unfreeze_index(index_name) ⇒ Boolean

Unfreezes the specified index within Elasticsearch. Raises SearchFlip::ResponseError in case any errors occur

Parameters:

  • index_name (String)

    The index name

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



275
276
277
278
279
# File 'lib/search_flip/connection.rb', line 275

def unfreeze_index(index_name)
  http_client.post("#{index_url(index_name)}/_unfreeze")

  true
end

#update_aliases(payload) ⇒ Hash

Used to manipulate, ie add and remove index aliases. Raises an SearchFlip::ResponseError in case any errors occur.

Examples:

connection.update_aliases(actions: [
  { remove: { index: "test1", alias: "alias1" }},
  { add: { index: "test2", alias: "alias1" }}
])

Parameters:

  • payload (Hash)

    The raw request payload

Returns:

  • (Hash)

    The raw response



131
132
133
134
135
136
137
# File 'lib/search_flip/connection.rb', line 131

def update_aliases(payload)
  response = http_client
    .headers(accept: "application/json", content_type: "application/json")
    .post("#{base_url}/_aliases", body: SearchFlip::JSON.generate(payload))

  SearchFlip::JSON.parse(response.to_s)
end

#update_cluster_settings(cluster_settings) ⇒ Boolean

Updates the cluster settings according to the specified payload

Examples:

connection.update_cluster_settings(persistent: { action: { auto_create_index: false } })

Parameters:

  • cluster_settings (Hash)

    The cluster settings

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



55
56
57
58
59
# File 'lib/search_flip/connection.rb', line 55

def update_cluster_settings(cluster_settings)
  http_client.put("#{base_url}/_cluster/settings", json: cluster_settings)

  true
end

#update_index_settings(index_name, index_settings) ⇒ Boolean

Updates the index settings within Elasticsearch according to the index settings specified. Raises SearchFlip::ResponseError in case any errors occur.

Parameters:

  • index_name (String)

    The index name to update the settings for

  • index_settings (Hash)

    The index settings

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



290
291
292
293
294
# File 'lib/search_flip/connection.rb', line 290

def update_index_settings(index_name, index_settings)
  http_client.put("#{index_url(index_name)}/_settings", json: index_settings)

  true
end

#update_mapping(index_name, mapping, type_name: nil) ⇒ Boolean

Updates the type mapping for the specified index and type within Elasticsearch according to the specified mapping. Raises SearchFlip::ResponseError in case any errors occur.

Parameters:

  • index_name (String)

    The index name

  • mapping (Hash)

    The mapping

  • type_name (String) (defaults to: nil)

    The type name. Starting with Elasticsearch 7, the type name is optional.

Returns:

  • (Boolean)

    Returns true or raises SearchFlip::ResponseError



335
336
337
338
339
340
341
342
# File 'lib/search_flip/connection.rb', line 335

def update_mapping(index_name, mapping, type_name: nil)
  url = type_name && distribution.nil? && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
  params = type_name && distribution.nil? && version.to_f >= 6.7 && version.to_i < 8 ? { include_type_name: true } : {}

  http_client.put("#{url}/_mapping", params: params, json: mapping)

  true
end

#versionString

Queries and returns the Elasticsearch version used.

Examples:

connection.version # => e.g. "2.4.1"

Returns:

  • (String)

    The Elasticsearch version



68
69
70
# File 'lib/search_flip/connection.rb', line 68

def version
  @version ||= SearchFlip::Config.dig(:version, :number) || SearchFlip::JSON.parse(version_response.to_s)["version"]["number"]
end