meilisearch 0.16.0 → 0.17.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c67baca928880c0efd95580e84a4b3f11f8fbab279a8eec5e6a7ffd64467ce85
4
- data.tar.gz: ee39b314f6607c5ccd219d16bb6e0cb88d971b7113fa1c9091b11634b34e5062
3
+ metadata.gz: 276a1136bc7d85d5c0eaafa7475732990502af66a37859589dea606cffde3c97
4
+ data.tar.gz: e45996c09a5140cf5c66c9f1e30163ca91f37e3e469c00d396c88c318b9541ca
5
5
  SHA512:
6
- metadata.gz: aa7d0a46d608c88ac58786f70d95001c845123c5df29fe3644ddfe8669f87744102076a6610b993b05dd733512922def3ece255fcd562dac103696f07c779a66
7
- data.tar.gz: e6b254f4fc93e8e9f4a0f6aa8df701fbd30cc6565021c0c61f81e709fc96b3423ca0eb4cc6097eb2abba91c76ea6298128e4765c9f2f1f3ce58ba807a8d93bb7
6
+ metadata.gz: '09377cb9cd2eba0800459c57c229db29b9d497716248141125067b97026dabce8f1a6725b0a66336b98700e6cead512c0879e3d5162f402d04fd65277e373711'
7
+ data.tar.gz: 62f69c26b9516074cff7e97a4dde7a45261f511d762aef0ecbd933a5810b4ed3ec4136bb6ef3a9f0b04f9d6dd22699453a823014dd203a172d83d5bbc52f7993
@@ -6,15 +6,22 @@ module MeiliSearch
6
6
  class Client < HTTPRequest
7
7
  ### INDEXES
8
8
 
9
+ def raw_indexes
10
+ http_get('/indexes')
11
+ end
12
+
9
13
  def indexes
10
- http_get '/indexes'
14
+ raw_indexes.map do |index_hash|
15
+ index_object(index_hash['uid'], index_hash['primaryKey'])
16
+ end
11
17
  end
12
18
 
13
19
  # Usage:
14
20
  # client.create_index('indexUID')
15
21
  # client.create_index('indexUID', primaryKey: 'id')
16
22
  def create_index(index_uid, options = {})
17
- body = options.merge(uid: index_uid)
23
+ body = Utils.transform_attributes(options.merge(uid: index_uid))
24
+
18
25
  index_hash = http_post '/indexes', body
19
26
  index_object(index_hash['uid'], index_hash['primaryKey'])
20
27
  end
@@ -34,6 +41,17 @@ module MeiliSearch
34
41
  index_object(index_uid).delete
35
42
  end
36
43
 
44
+ # Usage:
45
+ # client.delete_index_if_exists('indexUID')
46
+ def delete_index_if_exists(index_uid)
47
+ index_object(index_uid).delete
48
+ true
49
+ rescue ApiError => e
50
+ raise e if e.code != 'index_not_found'
51
+
52
+ false
53
+ end
54
+
37
55
  # Usage:
38
56
  # client.index('indexUID')
39
57
  def index(index_uid)
@@ -44,6 +62,10 @@ module MeiliSearch
44
62
  index_object(index_uid).fetch_info
45
63
  end
46
64
 
65
+ def fetch_raw_index(index_uid)
66
+ index_object(index_uid).fetch_raw_info
67
+ end
68
+
47
69
  ### KEYS
48
70
 
49
71
  def keys
@@ -29,10 +29,15 @@ module MeiliSearch
29
29
 
30
30
  def get_meilisearch_error_info(http_body)
31
31
  @http_body = JSON.parse(http_body)
32
- @ms_code = @http_body['errorCode']
32
+ @ms_code = @http_body['code']
33
33
  @ms_message = @http_body['message']
34
- @ms_type = @http_body['errorType']
35
- @ms_link = @http_body['errorLink']
34
+ @ms_type = @http_body['type']
35
+ @ms_link = @http_body['link']
36
+ rescue JSON::ParserError
37
+ # We might receive a JSON::ParserError when, for example, MeiliSearch is running behind
38
+ # some proxy (ELB or Nginx, for example), and the request timeouts, returning us
39
+ # a raw HTML body instead of a JSON as we were expecting
40
+ @ms_message = "The server has not returned a valid JSON HTTP body: #{http_body}"
36
41
  end
37
42
 
38
43
  def details
@@ -17,13 +17,17 @@ module MeiliSearch
17
17
  'Content-Type' => 'application/json',
18
18
  'X-Meili-API-Key' => api_key
19
19
  }.compact
20
+ @headers_no_body = {
21
+ 'X-Meili-API-Key' => api_key
22
+ }.compact
20
23
  end
21
24
 
22
25
  def http_get(relative_path = '', query_params = {})
23
26
  send_request(
24
27
  proc { |path, config| self.class.get(path, config) },
25
28
  relative_path,
26
- query_params
29
+ query_params: query_params,
30
+ headers: @headers_no_body
27
31
  )
28
32
  end
29
33
 
@@ -31,8 +35,9 @@ module MeiliSearch
31
35
  send_request(
32
36
  proc { |path, config| self.class.post(path, config) },
33
37
  relative_path,
34
- query_params,
35
- body
38
+ query_params: query_params,
39
+ body: body,
40
+ headers: @headers
36
41
  )
37
42
  end
38
43
 
@@ -40,22 +45,24 @@ module MeiliSearch
40
45
  send_request(
41
46
  proc { |path, config| self.class.put(path, config) },
42
47
  relative_path,
43
- query_params,
44
- body
48
+ query_params: query_params,
49
+ body: body,
50
+ headers: @headers
45
51
  )
46
52
  end
47
53
 
48
54
  def http_delete(relative_path = '')
49
55
  send_request(
50
56
  proc { |path, config| self.class.delete(path, config) },
51
- relative_path
57
+ relative_path,
58
+ headers: @headers_no_body
52
59
  )
53
60
  end
54
61
 
55
62
  private
56
63
 
57
- def send_request(http_method, relative_path, query_params = nil, body = nil)
58
- config = http_config(query_params, body)
64
+ def send_request(http_method, relative_path, query_params: nil, body: nil, headers: nil)
65
+ config = http_config(query_params, body, headers)
59
66
  begin
60
67
  response = http_method.call(@base_url + relative_path, config)
61
68
  rescue Errno::ECONNREFUSED => e
@@ -64,12 +71,11 @@ module MeiliSearch
64
71
  validate(response)
65
72
  end
66
73
 
67
- def http_config(query_params, body)
68
- body = body.to_json
74
+ def http_config(query_params, body, headers)
69
75
  {
70
- headers: @headers,
76
+ headers: headers,
71
77
  query: query_params,
72
- body: body,
78
+ body: body.to_json,
73
79
  timeout: @options[:timeout] || 1,
74
80
  max_retries: @options[:max_retries] || 0
75
81
  }.compact
@@ -5,7 +5,7 @@ require 'timeout'
5
5
 
6
6
  module MeiliSearch
7
7
  class Index < HTTPRequest
8
- attr_reader :uid, :primary_key
8
+ attr_reader :uid, :primary_key, :created_at, :updated_at
9
9
 
10
10
  def initialize(index_uid, url, api_key = nil, primary_key = nil, options = {})
11
11
  @uid = index_uid
@@ -14,27 +14,47 @@ module MeiliSearch
14
14
  end
15
15
 
16
16
  def fetch_info
17
- index_hash = http_get "/indexes/#{@uid}"
18
- @primary_key = index_hash['primaryKey']
17
+ index_hash = http_get indexes_path(id: @uid)
18
+ set_base_properties index_hash
19
19
  self
20
20
  end
21
21
 
22
+ def fetch_primary_key
23
+ fetch_info.primary_key
24
+ end
25
+ alias get_primary_key fetch_primary_key
26
+
27
+ def fetch_raw_info
28
+ index_hash = http_get indexes_path(id: @uid)
29
+ set_base_properties index_hash
30
+ index_hash
31
+ end
32
+
22
33
  def update(body)
23
- index_hash = http_put "/indexes/#{@uid}", body
24
- @primary_key = index_hash['primaryKey']
34
+ index_hash = http_put indexes_path(id: @uid), Utils.transform_attributes(body)
35
+ set_base_properties index_hash
36
+
25
37
  self
26
38
  end
39
+
27
40
  alias update_index update
28
41
 
29
42
  def delete
30
- http_delete "/indexes/#{@uid}"
43
+ http_delete indexes_path(id: @uid)
31
44
  end
32
45
  alias delete_index delete
33
46
 
34
- def fetch_primary_key
35
- fetch_info.primary_key
47
+ def indexes_path(id: nil)
48
+ "/indexes/#{id}"
36
49
  end
37
- alias get_primary_key fetch_primary_key
50
+ private :indexes_path
51
+
52
+ def set_base_properties(index_hash)
53
+ @primary_key = index_hash['primaryKey']
54
+ @created_at = Time.parse(index_hash['createdAt'])
55
+ @updated_at = Time.parse(index_hash['updatedAt'])
56
+ end
57
+ private :set_base_properties
38
58
 
39
59
  ### DOCUMENTS
40
60
 
@@ -46,7 +66,7 @@ module MeiliSearch
46
66
  alias get_one_document document
47
67
 
48
68
  def documents(options = {})
49
- http_get "/indexes/#{@uid}/documents", options
69
+ http_get "/indexes/#{@uid}/documents", Utils.transform_attributes(options)
50
70
  end
51
71
  alias get_documents documents
52
72
 
@@ -76,6 +96,40 @@ module MeiliSearch
76
96
  end
77
97
  alias add_or_update_documents! update_documents!
78
98
 
99
+ def add_documents_in_batches(documents, batch_size = 1000, primary_key = nil)
100
+ update_ids = []
101
+ documents.each_slice(batch_size) do |batch|
102
+ update_ids.append(add_documents(batch, primary_key))
103
+ end
104
+ update_ids
105
+ end
106
+
107
+ def add_documents_in_batches!(documents, batch_size = 1000, primary_key = nil)
108
+ update_ids = add_documents_in_batches(documents, batch_size, primary_key)
109
+ responses = []
110
+ update_ids.each do |update_object|
111
+ responses.append(wait_for_pending_update(update_object['updateId']))
112
+ end
113
+ responses
114
+ end
115
+
116
+ def update_documents_in_batches(documents, batch_size = 1000, primary_key = nil)
117
+ update_ids = []
118
+ documents.each_slice(batch_size) do |batch|
119
+ update_ids.append(update_documents(batch, primary_key))
120
+ end
121
+ update_ids
122
+ end
123
+
124
+ def update_documents_in_batches!(documents, batch_size = 1000, primary_key = nil)
125
+ update_ids = update_documents_in_batches(documents, batch_size, primary_key)
126
+ responses = []
127
+ update_ids.each do |update_object|
128
+ responses.append(wait_for_pending_update(update_object['updateId']))
129
+ end
130
+ responses
131
+ end
132
+
79
133
  def delete_documents(documents_ids)
80
134
  if documents_ids.is_a?(Array)
81
135
  http_post "/indexes/#{@uid}/documents/delete-batch", documents_ids
@@ -115,8 +169,9 @@ module MeiliSearch
115
169
  ### SEARCH
116
170
 
117
171
  def search(query, options = {})
118
- parsed_options = options.compact
119
- http_post "/indexes/#{@uid}/search", { q: query.to_s }.merge(parsed_options)
172
+ parsed_options = Utils.transform_attributes({ q: query.to_s }.merge(options.compact))
173
+
174
+ http_post "/indexes/#{@uid}/search", parsed_options
120
175
  end
121
176
 
122
177
  ### UPDATES
@@ -176,7 +231,7 @@ module MeiliSearch
176
231
  alias get_settings settings
177
232
 
178
233
  def update_settings(settings)
179
- http_post "/indexes/#{@uid}/settings", settings
234
+ http_post "/indexes/#{@uid}/settings", Utils.transform_attributes(settings)
180
235
  end
181
236
  alias settings= update_settings
182
237
 
@@ -296,5 +351,21 @@ module MeiliSearch
296
351
  def reset_filterable_attributes
297
352
  http_delete "/indexes/#{@uid}/settings/filterable-attributes"
298
353
  end
354
+
355
+ ### SETTINGS - SORTABLE ATTRIBUTES
356
+
357
+ def sortable_attributes
358
+ http_get "/indexes/#{@uid}/settings/sortable-attributes"
359
+ end
360
+ alias get_sortable_attributes sortable_attributes
361
+
362
+ def update_sortable_attributes(sortable_attributes)
363
+ http_post "/indexes/#{@uid}/settings/sortable-attributes", sortable_attributes
364
+ end
365
+ alias sortable_attributes= update_sortable_attributes
366
+
367
+ def reset_sortable_attributes
368
+ http_delete "/indexes/#{@uid}/settings/sortable-attributes"
369
+ end
299
370
  end
300
371
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ module Utils
5
+ SNAKE_CASE = /[^a-zA-Z0-9]+(.)/.freeze
6
+
7
+ def self.transform_attributes(body)
8
+ case body
9
+ when Array
10
+ body.map { |item| transform_attributes(item) }
11
+ when Hash
12
+ parse(body)
13
+ else
14
+ body
15
+ end
16
+ end
17
+
18
+ def self.parse(body)
19
+ body
20
+ .transform_keys(&:to_s)
21
+ .transform_keys do |key|
22
+ key.include?('_') ? key.downcase.gsub(SNAKE_CASE, &:upcase).gsub('_', '') : key
23
+ end
24
+ end
25
+
26
+ private_class_method :parse
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MeiliSearch
4
- VERSION = '0.16.0'
4
+ VERSION = '0.17.2'
5
5
  end
data/lib/meilisearch.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'meilisearch/version'
4
+ require 'meilisearch/utils'
4
5
  require 'meilisearch/client'
5
6
  require 'meilisearch/index'
6
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meilisearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meili
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-24 00:00:00.000000000 Z
11
+ date: 2021-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 0.17.1
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 0.19.0
22
+ version: 0.21.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: 0.17.1
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.19.0
32
+ version: 0.21.0
33
33
  description: An easy-to-use ruby client for Meilisearch API. See https://github.com/meilisearch/MeiliSearch
34
34
  email: bonjour@meilisearch.com
35
35
  executables: []
@@ -41,6 +41,7 @@ files:
41
41
  - lib/meilisearch/error.rb
42
42
  - lib/meilisearch/http_request.rb
43
43
  - lib/meilisearch/index.rb
44
+ - lib/meilisearch/utils.rb
44
45
  - lib/meilisearch/version.rb
45
46
  homepage: https://github.com/meilisearch/meilisearch-ruby
46
47
  licenses: