meilisearch 0.16.1 → 0.17.0

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: 5c898ee113e0f0a16da0b80ab6b0a079021eaa8ead536da8dfe283b7613dc27a
4
- data.tar.gz: 29eed6b1c4a3de9efbe54dd766718d70699c5dca5c31dab5b2f901bc5a48c68c
3
+ metadata.gz: c6e2e138205c88de9e5a82459a9a9648c1170380eb977ca839b8ed25aa238a8f
4
+ data.tar.gz: 642d60688d0000f6ae2d6f2ea64de47236eff9af6b34d71ec5bde38a2e76cc83
5
5
  SHA512:
6
- metadata.gz: a005a9271b2f926746fee1294a467f2d319af5bbd75677c3532ec4ec2fe6337ac970eda70e55cbaf6584b98235b8e27801088bfa5aff96d111251ce1b5f426a6
7
- data.tar.gz: 55fc4b9f2754928d72251c4f88ff5dbb6534d9a209eaa3b1ce5bfd5a39941640f68b3a9c2058eecb0396693bc4b0dfa8708f8c9420700ddd56cd4a40578392e3
6
+ metadata.gz: 76f796decd057670599f0cbd8e3c921f73457717b0e49e4a58ee9a7faabbefeae5819ba701c59aff27b4bd22fe449d60623b68e7be47e99d70379caa140097c1
7
+ data.tar.gz: 43734101c23e8fd5ab2fcf1b8044b5005b4e809f9947e16519e0f099e82491e75cce33499329faffb73fec91a589bf5de776566498b2c53054c793cbee7f0891
@@ -6,8 +6,14 @@ 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:
@@ -34,6 +40,17 @@ module MeiliSearch
34
40
  index_object(index_uid).delete
35
41
  end
36
42
 
43
+ # Usage:
44
+ # client.delete_index_if_exists('indexUID')
45
+ def delete_index_if_exists(index_uid)
46
+ index_object(index_uid).delete
47
+ true
48
+ rescue ApiError => e
49
+ raise e if e.code != 'index_not_found'
50
+
51
+ false
52
+ end
53
+
37
54
  # Usage:
38
55
  # client.index('indexUID')
39
56
  def index(index_uid)
@@ -44,6 +61,10 @@ module MeiliSearch
44
61
  index_object(index_uid).fetch_info
45
62
  end
46
63
 
64
+ def fetch_raw_index(index_uid)
65
+ index_object(index_uid).fetch_raw_info
66
+ end
67
+
47
68
  ### KEYS
48
69
 
49
70
  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,26 @@ 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
+ SNAKE_CASE = /[^a-zA-Z0-9]+(.)/.freeze
65
+
66
+ def send_request(http_method, relative_path, query_params: nil, body: nil, headers: nil)
67
+ config = http_config(query_params, body, headers)
59
68
  begin
60
69
  response = http_method.call(@base_url + relative_path, config)
61
70
  rescue Errno::ECONNREFUSED => e
@@ -64,10 +73,10 @@ module MeiliSearch
64
73
  validate(response)
65
74
  end
66
75
 
67
- def http_config(query_params, body)
68
- body = body.to_json
76
+ def http_config(query_params, body, headers)
77
+ body = transform_attributes(body).to_json
69
78
  {
70
- headers: @headers,
79
+ headers: headers,
71
80
  query: query_params,
72
81
  body: body,
73
82
  timeout: @options[:timeout] || 1,
@@ -75,6 +84,25 @@ module MeiliSearch
75
84
  }.compact
76
85
  end
77
86
 
87
+ def transform_attributes(body)
88
+ case body
89
+ when Array
90
+ body.map { |item| transform_attributes(item) }
91
+ when Hash
92
+ parse(body)
93
+ else
94
+ body
95
+ end
96
+ end
97
+
98
+ def parse(body)
99
+ body
100
+ .transform_keys(&:to_s)
101
+ .transform_keys do |key|
102
+ key.include?('_') ? key.downcase.gsub(SNAKE_CASE, &:upcase).gsub('_', '') : key
103
+ end
104
+ end
105
+
78
106
  def validate(response)
79
107
  raise ApiError.new(response.code, response.message, response.body) unless response.success?
80
108
 
@@ -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,46 @@ 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), body
35
+ set_base_properties index_hash
25
36
  self
26
37
  end
38
+
27
39
  alias update_index update
28
40
 
29
41
  def delete
30
- http_delete "/indexes/#{@uid}"
42
+ http_delete indexes_path(id: @uid)
31
43
  end
32
44
  alias delete_index delete
33
45
 
34
- def fetch_primary_key
35
- fetch_info.primary_key
46
+ def indexes_path(id: nil)
47
+ "/indexes/#{id}"
36
48
  end
37
- alias get_primary_key fetch_primary_key
49
+ private :indexes_path
50
+
51
+ def set_base_properties(index_hash)
52
+ @primary_key = index_hash['primaryKey']
53
+ @created_at = Time.parse(index_hash['createdAt'])
54
+ @updated_at = Time.parse(index_hash['updatedAt'])
55
+ end
56
+ private :set_base_properties
38
57
 
39
58
  ### DOCUMENTS
40
59
 
@@ -76,6 +95,40 @@ module MeiliSearch
76
95
  end
77
96
  alias add_or_update_documents! update_documents!
78
97
 
98
+ def add_documents_in_batches(documents, batch_size = 1000, primary_key = nil)
99
+ update_ids = []
100
+ documents.each_slice(batch_size) do |batch|
101
+ update_ids.append(add_documents(batch, primary_key))
102
+ end
103
+ update_ids
104
+ end
105
+
106
+ def add_documents_in_batches!(documents, batch_size = 1000, primary_key = nil)
107
+ update_ids = add_documents_in_batches(documents, batch_size, primary_key)
108
+ responses = []
109
+ update_ids.each do |update_object|
110
+ responses.append(wait_for_pending_update(update_object['updateId']))
111
+ end
112
+ responses
113
+ end
114
+
115
+ def update_documents_in_batches(documents, batch_size = 1000, primary_key = nil)
116
+ update_ids = []
117
+ documents.each_slice(batch_size) do |batch|
118
+ update_ids.append(update_documents(batch, primary_key))
119
+ end
120
+ update_ids
121
+ end
122
+
123
+ def update_documents_in_batches!(documents, batch_size = 1000, primary_key = nil)
124
+ update_ids = update_documents_in_batches(documents, batch_size, primary_key)
125
+ responses = []
126
+ update_ids.each do |update_object|
127
+ responses.append(wait_for_pending_update(update_object['updateId']))
128
+ end
129
+ responses
130
+ end
131
+
79
132
  def delete_documents(documents_ids)
80
133
  if documents_ids.is_a?(Array)
81
134
  http_post "/indexes/#{@uid}/documents/delete-batch", documents_ids
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MeiliSearch
4
- VERSION = '0.16.1'
4
+ VERSION = '0.17.0'
5
5
  end
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.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meili
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-13 00:00:00.000000000 Z
11
+ date: 2021-11-17 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.20.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.20.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: []