Module: Elasticsearch::API::Utils

Extended by:
Utils
Included in:
Utils
Defined in:
lib/elasticsearch/api/utils.rb

Overview

Generic utility methods

Instance Method Summary collapse

Instance Method Details

#bulkify(payload) ⇒ Object

Convert an array of payloads into Elasticsearch ‘headerndata` format

Supports various different formats of the payload: Array of Strings, Header/Data pairs, or the conveniency “combined” format where data is passed along with the header in a single item.

Elasticsearch::API::Utils.bulkify [
  { :index =>  { :_index => 'myindexA', :_type => 'mytype', :_id => '1', :data => { :title => 'Test' } } },
  { :update => { :_index => 'myindexB', :_type => 'mytype', :_id => '2', :data => { :doc => { :title => 'Update' } } } }
]

# => {"index":{"_index":"myindexA","_type":"mytype","_id":"1"}}
# => {"title":"Test"}
# => {"update":{"_index":"myindexB","_type":"mytype","_id":"2"}}
# => {"doc":{"title":"Update"}}


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/elasticsearch/api/utils.rb', line 101

def bulkify(payload)
  operations = %w[index create delete update]

  case
  # Hashes with `:data`
  when payload.any? { |d| d.is_a?(Hash) && d.values.first.is_a?(Hash) && operations.include?(d.keys.first.to_s) && (d.values.first[:data] || d.values.first['data']) }
    payload = payload.
      inject([]) do |sum, item|
        operation, meta = item.to_a.first
        meta            = meta.clone
        data            = meta.delete(:data) || meta.delete('data')

        sum << { operation => meta }
        sum << data if data
        sum
      end.
      map { |item| Elasticsearch::API.serializer.dump(item) }
    payload << '' unless payload.empty?
  # Array of strings
  when payload.all? { |d| d.is_a? String }
    payload << ''
  # Header/Data pairs
  else
    payload = payload.map { |item| Elasticsearch::API.serializer.dump(item) }
    payload << ''
  end
  payload = payload.join("\n")
end

#escape(string) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

URL-escape a string

Examples:

escape('foo/bar') # => 'foo%2Fbar'
escape('bar^bam') # => 'bar%5Ebam'


31
32
33
34
35
# File 'lib/elasticsearch/api/utils.rb', line 31

def escape(string)
  return string if string == '*'

  ERB::Util.url_encode(string.to_s)
end

#extract_parts(arguments, _valid_parts = []) ⇒ Array<String>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Mutates the ‘arguments` argument, to prevent failures in `__validate_and_extract_params`.

Extracts the valid parts of the URL from the arguments

Examples:

Extract parts

extract_parts { :foo => true }, [:foo, :bar]
# => [:foo]

Parameters:

  • arguments (Hash)

    Hash of arguments to verify and extract, **with symbolized keys**

  • valid_parts (Array<Symbol>)

    An array of symbol with valid keys

Returns:

  • (Array<String>)

    Valid parts of the URL as an array of strings



151
152
153
# File 'lib/elasticsearch/api/utils.rb', line 151

def extract_parts(arguments, _valid_parts = [])
  Hash[arguments].reduce([]) { |sum, item| k, v = item; v.is_a?(TrueClass) ? sum << k.to_s : sum << v }
end

#listify(*list) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a “list” of values from arguments, ignoring nil values and encoding special characters.

Examples:

Create a list from array

listify(['A','B']) # => 'A,B'

Create a list from arguments

listify('A','B') # => 'A,B'

Escape values

listify('foo','bar^bam') # => 'foo,bar%5Ebam'

Do not escape the values

listify('foo','bar^bam', escape: false) # => 'foo,bar^bam'


52
53
54
55
56
57
58
59
60
61
62
# File 'lib/elasticsearch/api/utils.rb', line 52

def listify(*list)
  options = list.last.is_a?(Hash) ? list.pop : {}

  escape = options[:escape]
  Array(list)
    .flat_map { |e| e.respond_to?(:split) ? e.split(',') : e }
    .flatten
    .compact
    .map { |e| escape == false ? e : escape(e) }
    .join(',')
end

#pathify(*segments) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a path (URL part) from arguments, ignoring nil values and empty strings.

# @example Encode special characters

pathify(['foo', 'bar^bam']) # => 'foo/bar%5Ebam'

Examples:

Create a path from array

pathify(['foo', '', nil, 'bar']) # => 'foo/bar'

Create a path from arguments

pathify('foo', '', nil, 'bar') # => 'foo/bar'


76
77
78
79
80
81
82
83
# File 'lib/elasticsearch/api/utils.rb', line 76

def pathify(*segments)
  Array(segments)
    .flatten
    .compact
    .reject { |s| s.to_s.strip.empty? }
    .join('/')
    .squeeze('/')
end

#process_params(arguments) ⇒ Object



130
131
132
133
# File 'lib/elasticsearch/api/utils.rb', line 130

def process_params(arguments)
  arguments = Hash[arguments] unless arguments.is_a?(Hash)
  Hash[arguments.map { |k, v| v.is_a?(Array) ? [k, listify(v, { escape: false })] : [k, v] }] # Listify Arrays
end

#rescue_from_not_found {|block| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Calls the given block, rescuing from ‘StandardError`.

Primary use case is the ‘:ignore` parameter for API calls.

Returns ‘false` if exception contains NotFound in its class name or message, else re-raises the exception.

Yields:

  • (block)

    A block of code to be executed with exception handling.



166
167
168
169
170
171
172
173
174
# File 'lib/elasticsearch/api/utils.rb', line 166

def rescue_from_not_found(&block)
  yield
rescue StandardError => e
  if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found/i
    false
  else
    raise e
  end
end

#update_ndjson_headers!(headers, client_headers) ⇒ Object

Updates ndjson headers for msearch, bulk, and others



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/elasticsearch/api/utils.rb', line 178

def update_ndjson_headers!(headers, client_headers)
  current_content = client_headers.keys.find { |c| c.match?(/content-?_?type/i) } || 'content-type'
  current_accept = client_headers.keys.find { |c| c.match?(/accept/i) } || 'accept'
  version = client_headers[current_content].match(/compatible-with=([0-9]+)/)[1] || 9

  headers.merge!(
    {
      current_content => "application/vnd.elasticsearch+x-ndjson; compatible-with=#{version}",
      current_accept => "application/vnd.elasticsearch+x-ndjson; compatible-with=#{version}"
    }
  )
end