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



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/search_flip/connection.rb', line 154

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



118
119
120
121
122
123
124
# File 'lib/search_flip/connection.rb', line 118

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:



393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/search_flip/connection.rb', line 393

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



207
208
209
210
211
# File 'lib/search_flip/connection.rb', line 207

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



50
51
52
53
54
# File 'lib/search_flip/connection.rb', line 50

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



194
195
196
197
198
# File 'lib/search_flip/connection.rb', line 194

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



340
341
342
343
344
# File 'lib/search_flip/connection.rb', line 340

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



233
234
235
236
237
# File 'lib/search_flip/connection.rb', line 233

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



138
139
140
141
142
143
144
# File 'lib/search_flip/connection.rb', line 138

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_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



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

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



174
175
176
177
178
179
180
# File 'lib/search_flip/connection.rb', line 174

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



324
325
326
327
328
329
330
331
# File 'lib/search_flip/connection.rb', line 324

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



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

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



426
427
428
# File 'lib/search_flip/connection.rb', line 426

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:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/search_flip/connection.rb', line 68

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



220
221
222
223
224
# File 'lib/search_flip/connection.rb', line 220

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



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

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



415
416
417
# File 'lib/search_flip/connection.rb', line 415

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



246
247
248
249
250
# File 'lib/search_flip/connection.rb', line 246

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



102
103
104
105
106
107
108
# File 'lib/search_flip/connection.rb', line 102

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_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



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

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



306
307
308
309
310
311
312
313
# File 'lib/search_flip/connection.rb', line 306

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



39
40
41
# File 'lib/search_flip/connection.rb', line 39

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