meilisearch-rails 0.6.0 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +43 -17
- data/lib/meilisearch/rails/configuration.rb +1 -0
- data/lib/meilisearch/rails/version.rb +5 -1
- data/lib/meilisearch-rails.rb +36 -17
- data/meilisearch-rails.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: affe6d35bf6c1c626570b32ae605e3b1e826c16c86e87d9ea4cc2e67cb4c1512
|
4
|
+
data.tar.gz: b950799c5e8296d5fcbc2e194480cbbc4fa5a60b704708db55859f7d0a6d8e4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a84a8fbbb00122c28c90c5573f1e5a93a3012a89f516ea35df68eba294aea20b7e169906400ad27b17d281359a2d3fb5933eda1338aecb2941e206b21b00002
|
7
|
+
data.tar.gz: c735267b627ef2100fc0cdd52bffa8d323d634b865c5ef5ba870d3839f8e2a0d03244e5478a056a26295fbd827c6ecbbd40a2994df8805fa194925add4c8533a
|
data/README.md
CHANGED
@@ -30,6 +30,7 @@
|
|
30
30
|
- [📖 Documentation](#-documentation)
|
31
31
|
- [🤖 Compatibility with Meilisearch](#-compatibility-with-meilisearch)
|
32
32
|
- [🚀 Getting Started](#-getting-started)
|
33
|
+
- [Compatibility](#-compatibility)
|
33
34
|
- [⚙️ Settings](#️-settings)
|
34
35
|
- [🔍 Custom search](#-custom-search)
|
35
36
|
- [🪛 Options](#-options)
|
@@ -43,6 +44,7 @@
|
|
43
44
|
- [Relations](#relations)
|
44
45
|
- [Sanitize attributes](#sanitize-attributes)
|
45
46
|
- [UTF-8 encoding](#utf-8-encoding)
|
47
|
+
- [Eager loading](#eager-loading)
|
46
48
|
- [Manual operations](#manual-operations)
|
47
49
|
- [Indexing & deletion](#indexing--deletion)
|
48
50
|
- [Access the underlying index object](#access-the-underlying-index-object)
|
@@ -58,7 +60,7 @@ To learn more about Meilisearch, check out our [Documentation](https://docs.meil
|
|
58
60
|
|
59
61
|
## 🤖 Compatibility with Meilisearch
|
60
62
|
|
61
|
-
This package only guarantees the compatibility with the [version v0.
|
63
|
+
This package only guarantees the compatibility with the [version v0.28.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.28.0).
|
62
64
|
|
63
65
|
## 🔧 Installation <!-- omit in toc -->
|
64
66
|
|
@@ -190,6 +192,10 @@ MeiliSearch::Rails.configuration = {
|
|
190
192
|
}
|
191
193
|
```
|
192
194
|
|
195
|
+
## Compatibility
|
196
|
+
|
197
|
+
If your model already has methods that meilisearch-rails defines such as `search` and `index`, they will not be redefined. You can target the meilisearch-rails-defined methods by prefixing with `ms_`, e.g. `Book.ms_search('harry potter')`.
|
198
|
+
|
193
199
|
## ⚙️ Settings
|
194
200
|
|
195
201
|
You can configure the index settings by adding them inside the `meilisearch` block as shown below:
|
@@ -262,19 +268,7 @@ end
|
|
262
268
|
|
263
269
|
#### Index UID according to the environment <!-- omit in toc -->
|
264
270
|
|
265
|
-
You can suffix the index UID with the current Rails environment
|
266
|
-
|
267
|
-
By defining directly in your model:
|
268
|
-
|
269
|
-
```ruby
|
270
|
-
class Book < ActiveRecord::Base
|
271
|
-
include MeiliSearch::Rails
|
272
|
-
|
273
|
-
meilisearch per_environment: true
|
274
|
-
end
|
275
|
-
```
|
276
|
-
|
277
|
-
Or setting it globally:
|
271
|
+
You can suffix the index UID with the current Rails environment by setting it globally:
|
278
272
|
|
279
273
|
```ruby
|
280
274
|
MeiliSearch::Rails.configuration = {
|
@@ -284,7 +278,7 @@ MeiliSearch::Rails.configuration = {
|
|
284
278
|
}
|
285
279
|
```
|
286
280
|
|
287
|
-
|
281
|
+
This way your index UID will look like this `"Book_#{Rails.env}"`.
|
288
282
|
|
289
283
|
### Index configuration
|
290
284
|
|
@@ -324,15 +318,33 @@ end
|
|
324
318
|
|
325
319
|
By default, the primary key is based on your record's id. You can change this behavior by specifying the `primary_key:` option.
|
326
320
|
|
327
|
-
Note that the primary key must
|
321
|
+
Note that the primary key must return a **unique value** otherwise your data could be overwritten.
|
328
322
|
|
329
323
|
```ruby
|
330
324
|
class Book < ActiveRecord::Base
|
331
325
|
include MeiliSearch::Rails
|
332
326
|
|
333
|
-
meilisearch primary_key:
|
327
|
+
meilisearch primary_key: :isbn # isbn is a column in your table definition.
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
You can also set the `primary_key` as a method, this method will be evaluated in runtime, and its return
|
332
|
+
will be used as the reference to the document when Meilisearch needs it.
|
333
|
+
|
334
|
+
```rb
|
335
|
+
class Book < ActiveRecord::Base
|
336
|
+
include MeiliSearch::Rails
|
337
|
+
|
338
|
+
meilisearch primary_key: :my_custom_ms_id
|
339
|
+
|
340
|
+
private
|
341
|
+
|
342
|
+
def my_custom_ms_id
|
343
|
+
"isbn_#{primary_key}" # ensure this return is unique, otherwise you'll lose data.
|
344
|
+
end
|
334
345
|
end
|
335
346
|
```
|
347
|
+
|
336
348
|
#### Conditional indexing
|
337
349
|
|
338
350
|
You can control if a record must be indexed by using the `if:` or `unless:` options.<br>
|
@@ -612,6 +624,20 @@ class Book < ActiveRecord::Base
|
|
612
624
|
end
|
613
625
|
```
|
614
626
|
|
627
|
+
#### Eager loading
|
628
|
+
|
629
|
+
You can eager load associations using `meilisearch_import` scope.
|
630
|
+
|
631
|
+
```ruby
|
632
|
+
class Author < ActiveRecord::Base
|
633
|
+
include MeiliSearch::Rails
|
634
|
+
|
635
|
+
has_many :books
|
636
|
+
|
637
|
+
scope :meilisearch_import, -> { includes(:books) }
|
638
|
+
end
|
639
|
+
```
|
640
|
+
|
615
641
|
### Manual operations
|
616
642
|
|
617
643
|
#### Indexing & deletion
|
data/lib/meilisearch-rails.rb
CHANGED
@@ -233,9 +233,13 @@ module MeiliSearch
|
|
233
233
|
def initialize(index_uid, raise_on_failure, options)
|
234
234
|
client = MeiliSearch::Rails.client
|
235
235
|
primary_key = options[:primary_key] || MeiliSearch::Rails::IndexSettings::DEFAULT_PRIMARY_KEY
|
236
|
-
client.create_index(index_uid, { primaryKey: primary_key })
|
237
|
-
@index = client.index(index_uid)
|
238
236
|
@raise_on_failure = raise_on_failure.nil? || raise_on_failure
|
237
|
+
|
238
|
+
SafeIndex.log_or_throw(nil, @raise_on_failure) do
|
239
|
+
client.create_index(index_uid, { primary_key: primary_key })
|
240
|
+
end
|
241
|
+
|
242
|
+
@index = client.index(index_uid)
|
239
243
|
end
|
240
244
|
|
241
245
|
::MeiliSearch::Index.instance_methods(false).each do |m|
|
@@ -273,7 +277,7 @@ module MeiliSearch
|
|
273
277
|
|
274
278
|
def self.log_or_throw(method, raise_on_failure, &block)
|
275
279
|
yield
|
276
|
-
rescue ::MeiliSearch::ApiError => e
|
280
|
+
rescue ::MeiliSearch::TimeoutError, ::MeiliSearch::ApiError => e
|
277
281
|
raise e if raise_on_failure
|
278
282
|
|
279
283
|
# log the error
|
@@ -282,7 +286,7 @@ module MeiliSearch
|
|
282
286
|
case method.to_s
|
283
287
|
when 'search'
|
284
288
|
# some attributes are required
|
285
|
-
{ 'hits' => [], 'hitsPerPage' => 0, 'page' => 0, '
|
289
|
+
{ 'hits' => [], 'hitsPerPage' => 0, 'page' => 0, 'facetDistribution' => {}, 'error' => e }
|
286
290
|
else
|
287
291
|
# empty answer
|
288
292
|
{ 'error' => e }
|
@@ -460,7 +464,7 @@ module MeiliSearch
|
|
460
464
|
end
|
461
465
|
last_task = index.add_documents(documents)
|
462
466
|
end
|
463
|
-
index.wait_for_task(last_task['
|
467
|
+
index.wait_for_task(last_task['taskUid']) if last_task && (synchronous || options[:synchronous])
|
464
468
|
end
|
465
469
|
nil
|
466
470
|
end
|
@@ -476,7 +480,7 @@ module MeiliSearch
|
|
476
480
|
|
477
481
|
index = SafeIndex.new(ms_index_uid(options), true, options)
|
478
482
|
task = index.update_settings(final_settings)
|
479
|
-
index.wait_for_task(task['
|
483
|
+
index.wait_for_task(task['taskUid']) if synchronous
|
480
484
|
end
|
481
485
|
end
|
482
486
|
|
@@ -486,7 +490,7 @@ module MeiliSearch
|
|
486
490
|
|
487
491
|
index = ms_ensure_init(options, settings)
|
488
492
|
task = index.add_documents(documents.map { |d| settings.get_attributes(d).merge ms_pk(options) => ms_primary_key_of(d, options) })
|
489
|
-
index.wait_for_task(task['
|
493
|
+
index.wait_for_task(task['taskUid']) if synchronous || options[:synchronous]
|
490
494
|
end
|
491
495
|
end
|
492
496
|
|
@@ -583,7 +587,7 @@ module MeiliSearch
|
|
583
587
|
end
|
584
588
|
|
585
589
|
def ms_facets_distribution
|
586
|
-
@ms_json['
|
590
|
+
@ms_json['facetDistribution']
|
587
591
|
end
|
588
592
|
|
589
593
|
private
|
@@ -595,23 +599,20 @@ module MeiliSearch
|
|
595
599
|
|
596
600
|
def ms_search(query, params = {})
|
597
601
|
if MeiliSearch::Rails.configuration[:pagination_backend]
|
598
|
-
|
599
602
|
page = params[:page].nil? ? params[:page] : params[:page].to_i
|
600
603
|
hits_per_page = params[:hitsPerPage].nil? ? params[:hitsPerPage] : params[:hitsPerPage].to_i
|
604
|
+
hits_per_page ||= params[:hits_per_page].nil? ? params[:hits_per_page] : params[:hits_per_page].to_i
|
605
|
+
|
606
|
+
%i[page hitsPerPage hits_per_page].each { |param| params.delete(param) }
|
601
607
|
|
602
|
-
params.delete(:page)
|
603
|
-
params.delete(:hitsPerPage)
|
604
608
|
params[:limit] = 200
|
605
609
|
end
|
606
610
|
|
607
611
|
# Returns raw json hits as follows:
|
608
|
-
# {"hits"=>[{"id"=>"13", "href"=>"apple", "name"=>"iphone"}], "offset"=>0, "limit"=>|| 20, "
|
609
|
-
# "
|
612
|
+
# {"hits"=>[{"id"=>"13", "href"=>"apple", "name"=>"iphone"}], "offset"=>0, "limit"=>|| 20, "estimatedTotalHits"=>1,
|
613
|
+
# "processingTimeMs"=>0, "query"=>"iphone"}
|
610
614
|
json = ms_raw_search(query, params)
|
611
615
|
|
612
|
-
# Returns the ids of the hits: 13
|
613
|
-
hit_ids = json['hits'].map { |hit| hit[ms_pk(meilisearch_options).to_s] }
|
614
|
-
|
615
616
|
# condition_key gets the primary key of the document; looks for "id" on the options
|
616
617
|
condition_key = if defined?(::Mongoid::Document) && include?(::Mongoid::Document)
|
617
618
|
ms_primary_key_method.in
|
@@ -619,6 +620,23 @@ module MeiliSearch
|
|
619
620
|
ms_primary_key_method
|
620
621
|
end
|
621
622
|
|
623
|
+
# The condition_key must be a valid column otherwise, the `.where` below will not work
|
624
|
+
# Since we provide a way to customize the primary_key value, `ms_pk(meilisearch_options)` may not
|
625
|
+
# respond with a valid database column. The blocks below prevent that from happening.
|
626
|
+
has_virtual_column_as_pk = if defined?(::Sequel::Model) && self < Sequel::Model
|
627
|
+
meilisearch_options[:type].columns.map(&:to_s).exclude?(condition_key.to_s)
|
628
|
+
else
|
629
|
+
meilisearch_options[:type].columns.map(&:name).map(&:to_s).exclude?(condition_key.to_s)
|
630
|
+
end
|
631
|
+
|
632
|
+
condition_key = meilisearch_options[:type].primary_key if has_virtual_column_as_pk
|
633
|
+
|
634
|
+
hit_ids = if has_virtual_column_as_pk
|
635
|
+
json['hits'].map { |hit| hit[condition_key] }
|
636
|
+
else
|
637
|
+
json['hits'].map { |hit| hit[ms_pk(meilisearch_options).to_s] }
|
638
|
+
end
|
639
|
+
|
622
640
|
# meilisearch_options[:type] refers to the Model name (e.g. Product)
|
623
641
|
# results_by_id creates a hash with the primaryKey of the document (id) as the key and doc itself as the value
|
624
642
|
# {"13"=>#<Product id: 13, name: "iphone", href: "apple", tags: nil, type: nil,
|
@@ -827,7 +845,8 @@ module MeiliSearch
|
|
827
845
|
|
828
846
|
def ms_find_in_batches(batch_size, &block)
|
829
847
|
if (defined?(::ActiveRecord) && ancestors.include?(::ActiveRecord::Base)) || respond_to?(:find_in_batches)
|
830
|
-
|
848
|
+
scope = respond_to?(:meilisearch_import) ? meilisearch_import : all
|
849
|
+
scope.find_in_batches(batch_size: batch_size, &block)
|
831
850
|
elsif defined?(::Sequel::Model) && self < Sequel::Model
|
832
851
|
dataset.extension(:pagination).each_page(batch_size, &block)
|
833
852
|
else
|
data/meilisearch-rails.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meilisearch-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Meili
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: meilisearch
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.19.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.19.2
|
27
27
|
description: Meilisearch integration for Ruby on Rails. See https://github.com/meilisearch/meilisearch
|
28
28
|
email: bonjour@meilisearch.com
|
29
29
|
executables: []
|