meilisearch 0.16.1 → 0.17.3

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: 3c90df98b1b08039b339c49b47bfd052639e1301e9e7e3b25989b9ce6e3d1e67
4
+ data.tar.gz: 3f200a9de09db7a47780b01aa20a8ce5b2b1d0d0579954cd8842cb208b06b4dc
5
5
  SHA512:
6
- metadata.gz: a005a9271b2f926746fee1294a467f2d319af5bbd75677c3532ec4ec2fe6337ac970eda70e55cbaf6584b98235b8e27801088bfa5aff96d111251ce1b5f426a6
7
- data.tar.gz: 55fc4b9f2754928d72251c4f88ff5dbb6534d9a209eaa3b1ce5bfd5a39941640f68b3a9c2058eecb0396693bc4b0dfa8708f8c9420700ddd56cd4a40578392e3
6
+ metadata.gz: b3b38312517176303e9fdc49af5c38647ea4d719d8988cb1e1fd60839e7c593226fd9369febd24a326d214dbb606acd201464fd6590f46438383cf25f3e7e934
7
+ data.tar.gz: 494fa30322be3d624851117e460c31046c51ea3ef4d00326f4be969a76f5f056a15147c065b1ef02a56f3a589643e137ac4af1a05a088bab606cdf6d31bc8abc
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019-2021 Meili
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,222 @@
1
+ <p align="center">
2
+ <img src="https://res.cloudinary.com/meilisearch/image/upload/v1587402338/SDKs/meilisearch_ruby.svg" alt="MeiliSearch-Ruby" width="200" height="200" />
3
+ </p>
4
+
5
+ <h1 align="center">MeiliSearch Ruby</h1>
6
+
7
+ <h4 align="center">
8
+ <a href="https://github.com/meilisearch/MeiliSearch">MeiliSearch</a> |
9
+ <a href="https://docs.meilisearch.com">Documentation</a> |
10
+ <a href="https://slack.meilisearch.com">Slack</a> |
11
+ <a href="https://roadmap.meilisearch.com/tabs/1-under-consideration">Roadmap</a> |
12
+ <a href="https://www.meilisearch.com">Website</a> |
13
+ <a href="https://docs.meilisearch.com/faq">FAQ</a>
14
+ </h4>
15
+
16
+ <p align="center">
17
+ <a href="https://badge.fury.io/rb/meilisearch"><img src="https://badge.fury.io/rb/meilisearch.svg" alt="Latest Stable Version"></a>
18
+ <a href="https://github.com/meilisearch/meilisearch-ruby/actions"><img src="https://github.com/meilisearch/meilisearch-ruby/workflows/Tests/badge.svg" alt="Test"></a>
19
+ <a href="https://github.com/meilisearch/meilisearch-ruby/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-informational" alt="License"></a>
20
+ <a href="https://app.bors.tech/repositories/28781"><img src="https://bors.tech/images/badge_small.svg" alt="Bors enabled"></a>
21
+ </p>
22
+
23
+ <p align="center">⚡ The MeiliSearch API client written for Ruby 💎</p>
24
+
25
+ **MeiliSearch Ruby** is the MeiliSearch API client for Ruby developers.
26
+
27
+ **MeiliSearch** is an open-source search engine. [Discover what MeiliSearch is!](https://github.com/meilisearch/MeiliSearch)
28
+
29
+ ## Table of Contents <!-- omit in toc -->
30
+
31
+ - [📖 Documentation](#-documentation)
32
+ - [🔧 Installation](#-installation)
33
+ - [🚀 Getting Started](#-getting-started)
34
+ - [🤖 Compatibility with MeiliSearch](#-compatibility-with-meilisearch)
35
+ - [💡 Learn More](#-learn-more)
36
+ - [⚙️ Development Workflow and Contributing](#️-development-workflow-and-contributing)
37
+
38
+ ## 📖 Documentation
39
+
40
+ See our [Documentation](https://docs.meilisearch.com/learn/tutorials/getting_started.html) or our [API References](https://docs.meilisearch.com/reference/api/).
41
+
42
+ ## 🔧 Installation
43
+
44
+ This package requires Ruby version 2.6.0 or later.
45
+
46
+ With `gem` in command line:
47
+ ```bash
48
+ gem install meilisearch
49
+ ```
50
+
51
+ In your `Gemfile` with [bundler](https://bundler.io/):
52
+ ```ruby
53
+ source 'https://rubygems.org'
54
+
55
+ gem 'meilisearch'
56
+ ```
57
+
58
+ ### Run MeiliSearch <!-- omit in toc -->
59
+
60
+ There are many easy ways to [download and run a MeiliSearch instance](https://docs.meilisearch.com/reference/features/installation.html#download-and-launch).
61
+
62
+ For example, using the `curl` command in your [Terminal](https://itconnect.uw.edu/learn/workshops/online-tutorials/web-publishing/what-is-a-terminal/):
63
+
64
+ ```sh
65
+ #Install MeiliSearch
66
+ curl -L https://install.meilisearch.com | sh
67
+
68
+ # Launch MeiliSearch
69
+ ./meilisearch --master-key=masterKey
70
+ ```
71
+
72
+ NB: you can also download MeiliSearch from **Homebrew** or **APT** or even run it using **Docker**.
73
+
74
+ ## 🚀 Getting Started
75
+
76
+ #### Add documents <!-- omit in toc -->
77
+
78
+ ```ruby
79
+ require 'meilisearch'
80
+
81
+ client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey')
82
+
83
+ # An index is where the documents are stored.
84
+ index = client.index('movies')
85
+
86
+ documents = [
87
+ { id: 1, title: 'Carol', genres: ['Romance', 'Drama'] },
88
+ { id: 2, title: 'Wonder Woman', genres: ['Action', 'Adventure'] },
89
+ { id: 3, title: 'Life of Pi', genres: ['Adventure', 'Drama'] },
90
+ { id: 4, title: 'Mad Max: Fury Road', genres: ['Adventure', 'Science Fiction'] },
91
+ { id: 5, title: 'Moana', genres: ['Fantasy', 'Action']},
92
+ { id: 6, title: 'Philadelphia', genres: ['Drama'] },
93
+ ]
94
+ # If the index 'movies' does not exist, MeiliSearch creates it when you first add the documents.
95
+ index.add_documents(documents) # => { "updateId": 0 }
96
+ ```
97
+
98
+ With the `updateId`, you can check the status (`enqueued`, `processing`, `processed` or `failed`) of your documents addition using the [update endpoint](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status).
99
+
100
+ 💡 To customize the `Client`, for example, increasing the default timeout, please check out [this section](https://github.com/meilisearch/meilisearch-ruby/wiki/Client-Options) of the Wiki.
101
+
102
+ #### Basic Search <!-- omit in toc -->
103
+
104
+ ``` ruby
105
+ # MeiliSearch is typo-tolerant:
106
+ puts index.search('carlo')
107
+ ```
108
+ Output:
109
+
110
+ ```ruby
111
+ {
112
+ "hits" => [{
113
+ "id" => 1,
114
+ "title" => "Carol"
115
+ }],
116
+ "offset" => 0,
117
+ "limit" => 20,
118
+ "processingTimeMs" => 1,
119
+ "query" => "carlo"
120
+ }
121
+ ```
122
+
123
+ #### Custom search <!-- omit in toc -->
124
+
125
+ All the supported options are described in the [search parameters](https://docs.meilisearch.com/reference/features/search_parameters.html) section of the documentation.
126
+
127
+ ```ruby
128
+ index.search(
129
+ 'wonder',
130
+ attributes_to_highlight: ['*']
131
+ )
132
+ ```
133
+
134
+ JSON output:
135
+
136
+ ```json
137
+ {
138
+ "hits": [
139
+ {
140
+ "id": 2,
141
+ "title": "Wonder Woman",
142
+ "_formatted": {
143
+ "id": 2,
144
+ "title": "<em>Wonder</em> Woman"
145
+ }
146
+ }
147
+ ],
148
+ "offset": 0,
149
+ "limit": 20,
150
+ "processingTimeMs": 0,
151
+ "query": "wonder"
152
+ }
153
+ ```
154
+
155
+ #### Custom Search With Filters <!-- omit in toc -->
156
+
157
+ If you want to enable filtering, you must add your attributes to the `filterableAttributes` index setting.
158
+
159
+ ```ruby
160
+ index.update_filterable_attributes([
161
+ 'id',
162
+ 'genres'
163
+ ])
164
+ ```
165
+
166
+ You only need to perform this operation once.
167
+
168
+ Note that MeiliSearch will rebuild your index whenever you update `filterableAttributes`. Depending on the size of your dataset, this might take time. You can track the process using the [update status](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status).
169
+
170
+ Then, you can perform the search:
171
+
172
+ ```ruby
173
+ index.search('wonder', { filter: ['id > 1 AND genres = Action'] })
174
+ ```
175
+
176
+ JSON output:
177
+
178
+ ```json
179
+ {
180
+ "hits": [
181
+ {
182
+ "id": 2,
183
+ "title": "Wonder Woman",
184
+ "genres": [
185
+ "Action",
186
+ "Adventure"
187
+ ]
188
+ }
189
+ ],
190
+ "nbHits": 1,
191
+ "exhaustiveNbHits": false,
192
+ "query": "wonder",
193
+ "limit": 20,
194
+ "offset": 0,
195
+ "processingTimeMs": 0
196
+ }
197
+ ```
198
+
199
+ ## 🤖 Compatibility with MeiliSearch
200
+
201
+ This package only guarantees the compatibility with the [version v0.24.0 of MeiliSearch](https://github.com/meilisearch/MeiliSearch/releases/tag/v0.24.0).
202
+
203
+ ## 💡 Learn More
204
+
205
+ The following sections may interest you:
206
+
207
+ - **Manipulate documents**: see the [API references](https://docs.meilisearch.com/reference/api/documents.html) or read more about [documents](https://docs.meilisearch.com/learn/core_concepts/documents.html).
208
+ - **Search**: see the [API references](https://docs.meilisearch.com/reference/api/search.html) or follow our guide on [search parameters](https://docs.meilisearch.com/reference/features/search_parameters.html).
209
+ - **Manage the indexes**: see the [API references](https://docs.meilisearch.com/reference/api/indexes.html) or read more about [indexes](https://docs.meilisearch.com/learn/core_concepts/indexes.html).
210
+ - **Configure the index settings**: see the [API references](https://docs.meilisearch.com/reference/api/settings.html) or follow our guide on [settings parameters](https://docs.meilisearch.com/reference/features/settings.html).
211
+
212
+ 📖 Also, check out the [Wiki](https://github.com/meilisearch/meilisearch-ruby/wiki) of this repository to know what this SDK provdes!
213
+
214
+ ## ⚙️ Development Workflow and Contributing
215
+
216
+ Any new contribution is more than welcome in this project!
217
+
218
+ If you want to know more about the development workflow or want to contribute, please visit our [contributing guidelines](/CONTRIBUTING.md) for detailed instructions!
219
+
220
+ <hr>
221
+
222
+ **MeiliSearch** provides and maintains many **SDKs and Integration tools** like this one. We want to provide everyone with an **amazing search experience for any kind of project**. If you want to contribute, make suggestions, or just know what's going on right now, visit us in the [integration-guides](https://github.com/meilisearch/integration-guides) repository.
@@ -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
@@ -12,27 +12,30 @@ module MeiliSearch
12
12
  def initialize(url, api_key = nil, options = {})
13
13
  @base_url = url
14
14
  @api_key = api_key
15
- @options = options
16
- @headers = {
17
- 'Content-Type' => 'application/json',
18
- 'X-Meili-API-Key' => api_key
19
- }.compact
15
+ @options = merge_options({
16
+ timeout: 1,
17
+ max_retries: 0,
18
+ headers: build_default_options_headers(api_key),
19
+ convert_body?: true
20
+ }, options)
20
21
  end
21
22
 
22
23
  def http_get(relative_path = '', query_params = {})
23
24
  send_request(
24
25
  proc { |path, config| self.class.get(path, config) },
25
26
  relative_path,
26
- query_params
27
+ query_params: query_params,
28
+ options: remove_options_header(@options, 'Content-Type')
27
29
  )
28
30
  end
29
31
 
30
- def http_post(relative_path = '', body = nil, query_params = nil)
32
+ def http_post(relative_path = '', body = nil, query_params = nil, options = {})
31
33
  send_request(
32
34
  proc { |path, config| self.class.post(path, config) },
33
35
  relative_path,
34
- query_params,
35
- body
36
+ query_params: query_params,
37
+ body: body,
38
+ options: merge_options(@options, options)
36
39
  )
37
40
  end
38
41
 
@@ -40,22 +43,50 @@ module MeiliSearch
40
43
  send_request(
41
44
  proc { |path, config| self.class.put(path, config) },
42
45
  relative_path,
43
- query_params,
44
- body
46
+ query_params: query_params,
47
+ body: body,
48
+ options: @options
45
49
  )
46
50
  end
47
51
 
48
52
  def http_delete(relative_path = '')
49
53
  send_request(
50
54
  proc { |path, config| self.class.delete(path, config) },
51
- relative_path
55
+ relative_path,
56
+ options: remove_options_header(@options, 'Content-Type')
52
57
  )
53
58
  end
54
59
 
55
60
  private
56
61
 
57
- def send_request(http_method, relative_path, query_params = nil, body = nil)
58
- config = http_config(query_params, body)
62
+ def build_default_options_headers(api_key = nil)
63
+ {
64
+ 'Content-Type' => 'application/json',
65
+ 'X-Meili-API-Key' => api_key
66
+ }.compact
67
+ end
68
+
69
+ def merge_options(default_options, added_options = {})
70
+ default_cloned_headers = default_options[:headers].clone
71
+ merged_options = default_options.merge(added_options)
72
+ merged_options[:headers] = default_cloned_headers.merge(added_options[:headers]) if added_options.key?(:headers)
73
+ merged_options
74
+ end
75
+
76
+ def remove_options_header(options, key)
77
+ cloned_options = clone_options(options)
78
+ cloned_options[:headers].tap { |headers| headers.delete(key) }
79
+ cloned_options
80
+ end
81
+
82
+ def clone_options(options)
83
+ cloned_options = options.clone
84
+ cloned_options[:headers] = options[:headers].clone
85
+ cloned_options
86
+ end
87
+
88
+ def send_request(http_method, relative_path, query_params: nil, body: nil, options: {})
89
+ config = http_config(query_params, body, options)
59
90
  begin
60
91
  response = http_method.call(@base_url + relative_path, config)
61
92
  rescue Errno::ECONNREFUSED => e
@@ -64,14 +95,14 @@ module MeiliSearch
64
95
  validate(response)
65
96
  end
66
97
 
67
- def http_config(query_params, body)
68
- body = body.to_json
98
+ def http_config(query_params, body, options)
99
+ body = body.to_json if options[:convert_body?] == true
69
100
  {
70
- headers: @headers,
101
+ headers: options[:headers],
71
102
  query: query_params,
72
103
  body: body,
73
- timeout: @options[:timeout] || 1,
74
- max_retries: @options[:max_retries] || 0
104
+ timeout: options[:timeout],
105
+ max_retries: options[:max_retries]
75
106
  }.compact
76
107
  end
77
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,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
 
@@ -64,6 +84,27 @@ module MeiliSearch
64
84
  alias replace_documents! add_documents!
65
85
  alias add_or_replace_documents! add_documents!
66
86
 
87
+ def add_documents_json(documents, primary_key = nil)
88
+ options = { headers: { 'Content-Type' => 'application/json' }, convert_body?: false }
89
+ http_post "/indexes/#{@uid}/documents", documents, { primaryKey: primary_key }.compact, options
90
+ end
91
+ alias replace_documents_json add_documents_json
92
+ alias add_or_replace_documents_json add_documents_json
93
+
94
+ def add_documents_ndjson(documents, primary_key = nil)
95
+ options = { headers: { 'Content-Type' => 'application/x-ndjson' }, convert_body?: false }
96
+ http_post "/indexes/#{@uid}/documents", documents, { primaryKey: primary_key }.compact, options
97
+ end
98
+ alias replace_documents_ndjson add_documents_ndjson
99
+ alias add_or_replace_documents_ndjson add_documents_ndjson
100
+
101
+ def add_documents_csv(documents, primary_key = nil)
102
+ options = { headers: { 'Content-Type' => 'text/csv' }, convert_body?: false }
103
+ http_post "/indexes/#{@uid}/documents", documents, { primaryKey: primary_key }.compact, options
104
+ end
105
+ alias replace_documents_csv add_documents_csv
106
+ alias add_or_replace_documents_csv add_documents_csv
107
+
67
108
  def update_documents(documents, primary_key = nil)
68
109
  documents = [documents] if documents.is_a?(Hash)
69
110
  http_put "/indexes/#{@uid}/documents", documents, { primaryKey: primary_key }.compact
@@ -76,6 +117,40 @@ module MeiliSearch
76
117
  end
77
118
  alias add_or_update_documents! update_documents!
78
119
 
120
+ def add_documents_in_batches(documents, batch_size = 1000, primary_key = nil)
121
+ update_ids = []
122
+ documents.each_slice(batch_size) do |batch|
123
+ update_ids.append(add_documents(batch, primary_key))
124
+ end
125
+ update_ids
126
+ end
127
+
128
+ def add_documents_in_batches!(documents, batch_size = 1000, primary_key = nil)
129
+ update_ids = add_documents_in_batches(documents, batch_size, primary_key)
130
+ responses = []
131
+ update_ids.each do |update_object|
132
+ responses.append(wait_for_pending_update(update_object['updateId']))
133
+ end
134
+ responses
135
+ end
136
+
137
+ def update_documents_in_batches(documents, batch_size = 1000, primary_key = nil)
138
+ update_ids = []
139
+ documents.each_slice(batch_size) do |batch|
140
+ update_ids.append(update_documents(batch, primary_key))
141
+ end
142
+ update_ids
143
+ end
144
+
145
+ def update_documents_in_batches!(documents, batch_size = 1000, primary_key = nil)
146
+ update_ids = update_documents_in_batches(documents, batch_size, primary_key)
147
+ responses = []
148
+ update_ids.each do |update_object|
149
+ responses.append(wait_for_pending_update(update_object['updateId']))
150
+ end
151
+ responses
152
+ end
153
+
79
154
  def delete_documents(documents_ids)
80
155
  if documents_ids.is_a?(Array)
81
156
  http_post "/indexes/#{@uid}/documents/delete-batch", documents_ids
@@ -115,8 +190,9 @@ module MeiliSearch
115
190
  ### SEARCH
116
191
 
117
192
  def search(query, options = {})
118
- parsed_options = options.compact
119
- http_post "/indexes/#{@uid}/search", { q: query.to_s }.merge(parsed_options)
193
+ parsed_options = Utils.transform_attributes({ q: query.to_s }.merge(options.compact))
194
+
195
+ http_post "/indexes/#{@uid}/search", parsed_options
120
196
  end
121
197
 
122
198
  ### UPDATES
@@ -176,7 +252,7 @@ module MeiliSearch
176
252
  alias get_settings settings
177
253
 
178
254
  def update_settings(settings)
179
- http_post "/indexes/#{@uid}/settings", settings
255
+ http_post "/indexes/#{@uid}/settings", Utils.transform_attributes(settings)
180
256
  end
181
257
  alias settings= update_settings
182
258
 
@@ -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.1'
4
+ VERSION = '0.17.3'
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.1
4
+ version: 0.17.3
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-12-13 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,18 +29,21 @@ 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: []
36
36
  extensions: []
37
37
  extra_rdoc_files: []
38
38
  files:
39
+ - LICENSE
40
+ - README.md
39
41
  - lib/meilisearch.rb
40
42
  - lib/meilisearch/client.rb
41
43
  - lib/meilisearch/error.rb
42
44
  - lib/meilisearch/http_request.rb
43
45
  - lib/meilisearch/index.rb
46
+ - lib/meilisearch/utils.rb
44
47
  - lib/meilisearch/version.rb
45
48
  homepage: https://github.com/meilisearch/meilisearch-ruby
46
49
  licenses: