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
20
# 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]
  @version_mutex = Mutex.new
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



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/search_flip/connection.rb', line 150

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



114
115
116
117
118
119
120
# File 'lib/search_flip/connection.rb', line 114

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:



389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/search_flip/connection.rb', line 389

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



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

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



46
47
48
49
50
# File 'lib/search_flip/connection.rb', line 46

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



190
191
192
193
194
# File 'lib/search_flip/connection.rb', line 190

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



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

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

  true
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



229
230
231
232
233
# File 'lib/search_flip/connection.rb', line 229

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



134
135
136
137
138
139
140
# File 'lib/search_flip/connection.rb', line 134

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



271
272
273
274
275
276
277
# File 'lib/search_flip/connection.rb', line 271

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



170
171
172
173
174
175
176
# File 'lib/search_flip/connection.rb', line 170

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



320
321
322
323
324
325
326
327
# File 'lib/search_flip/connection.rb', line 320

def get_mapping(index_name, type_name: nil)
  url = type_name && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
  params = type_name && 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



348
349
350
351
352
353
354
355
356
# File 'lib/search_flip/connection.rb', line 348

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



422
423
424
# File 'lib/search_flip/connection.rb', line 422

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:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/search_flip/connection.rb', line 64

def msearch(criterias)
  payload = criterias.flat_map do |criteria|
    [
      SearchFlip::JSON.generate(index: criteria.target.index_name_with_prefix, **(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



216
217
218
219
220
# File 'lib/search_flip/connection.rb', line 216

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



285
286
287
288
289
# File 'lib/search_flip/connection.rb', line 285

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



411
412
413
# File 'lib/search_flip/connection.rb', line 411

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



242
243
244
245
246
# File 'lib/search_flip/connection.rb', line 242

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



98
99
100
101
102
103
104
# File 'lib/search_flip/connection.rb', line 98

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



257
258
259
260
261
# File 'lib/search_flip/connection.rb', line 257

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



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

def update_mapping(index_name, mapping, type_name: nil)
  url = type_name && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
  params = type_name && 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



29
30
31
32
33
34
35
36
37
# File 'lib/search_flip/connection.rb', line 29

def version
  @version_mutex.synchronize do
    @version ||= begin
      response = http_client.headers(accept: "application/json").get("#{base_url}/")

      SearchFlip::JSON.parse(response.to_s)["version"]["number"]
    end
  end
end