meilisearch-rails 0.6.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|