searchkick 4.5.0 → 4.6.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62e2797b9ad2290378febadeaab675b745b0318cd86a8219cada4774b529e290
4
- data.tar.gz: 8f0956287e802ce93a67940f6283f914b58b38aee2240f3ef101ae08e7428966
3
+ metadata.gz: d1d925c63766341731235f39ccc55ff9c897927692bd36e0cfd6038a1d371d29
4
+ data.tar.gz: c3b2f3597751a87b1498919c210fb25f5f14a0514632a5e4e351d54bc799cb63
5
5
  SHA512:
6
- metadata.gz: 34a3bf2400766d7a2e95c3ba430a42c08dc1cfeb6c2d26b4d6d2a04828fd5ee296f3b121b076f00502f7c0c849ff27e1e622635a70885ef7f1336f0b4b8709de
7
- data.tar.gz: 1c190e32fa87aa03a025a349dfc200ced4c28069c524acaa7b3c220628c58b9da2742ae4c924a87bc354f920a7486cae176d2bd7078a72a98568a068b20df290
6
+ metadata.gz: e33b43ba33b0e832a7db8d65ffce7d83b5ca6e293b9d3049d1b8a4fee18c35a60a3353a8132e4baa5b77fca00b4d2eb383c5b4adfa8a089282befe19925aca82
7
+ data.tar.gz: 2e16bd24df683e543d81b1f272d8f67d42ef273c42de9d21f4366e001f39133161d714007aa0306077747d925c03c008f74b2b5ae5f0b4fe586daeba1aa8df66
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## 4.6.1 (2021-09-25)
2
+
3
+ - Added `ilike` operator for Elasticsearch 7.10+
4
+ - Fixed missing methods with `multi_search`
5
+
6
+ ## 4.6.0 (2021-08-22)
7
+
8
+ - Added support for case-insensitive regular expressions with Elasticsearch 7.10+
9
+ - Added support for `OPENSEARCH_URL`
10
+ - Fixed error with `debug` option
11
+
12
+ ## 4.5.2 (2021-08-05)
13
+
14
+ - Fixed error with reindex queue
15
+ - Fixed error with `model_name` method with multiple models
16
+ - Fixed error with `debug` option with elasticsearch-ruby 7.14
17
+
18
+ ## 4.5.1 (2021-08-03)
19
+
20
+ - Improved performance of reindex queue
21
+
1
22
  ## 4.5.0 (2021-06-07)
2
23
 
3
24
  - Added experimental support for OpenSearch
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2020 Andrew Kane
1
+ Copyright (c) 2013-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -20,7 +20,7 @@ Plus:
20
20
  - autocomplete
21
21
  - “Did you mean” suggestions
22
22
  - supports many languages
23
- - works with ActiveRecord, Mongoid, and NoBrainer
23
+ - works with Active Record, Mongoid, and NoBrainer
24
24
 
25
25
  Check out [Searchjoy](https://github.com/ankane/searchjoy) for analytics and [Autosuggest](https://github.com/ankane/autosuggest) for query suggestions
26
26
 
@@ -45,11 +45,11 @@ Check out [Searchjoy](https://github.com/ankane/searchjoy) for analytics and [Au
45
45
 
46
46
  ## Getting Started
47
47
 
48
- [Install Elasticsearch](https://www.elastic.co/downloads/elasticsearch). For Homebrew, use:
48
+ Install [Elasticsearch](https://www.elastic.co/downloads/elasticsearch) or [OpenSearch](https://opensearch.org/downloads.html). For Homebrew, use:
49
49
 
50
50
  ```sh
51
- brew install elasticsearch
52
- brew services start elasticsearch
51
+ brew install elasticsearch # or opensearch
52
+ brew services start elasticsearch # or opensearch
53
53
  ```
54
54
 
55
55
  Add this line to your application’s Gemfile:
@@ -58,7 +58,7 @@ Add this line to your application’s Gemfile:
58
58
  gem 'searchkick'
59
59
  ```
60
60
 
61
- The latest version works with Elasticsearch 6 and 7. For Elasticsearch 5, use version 3.1.3 and [this readme](https://github.com/ankane/searchkick/blob/v3.1.3/README.md).
61
+ The latest version works with Elasticsearch 6 and 7 and OpenSearch 1. For Elasticsearch 5, use version 3.1.3 and [this readme](https://github.com/ankane/searchkick/blob/v3.1.3/README.md).
62
62
 
63
63
  Add searchkick to models you want to search.
64
64
 
@@ -103,19 +103,20 @@ Where
103
103
 
104
104
  ```ruby
105
105
  where: {
106
- expires_at: {gt: Time.now}, # lt, gte, lte also available
107
- orders_count: 1..10, # equivalent to {gte: 1, lte: 10}
108
- aisle_id: [25, 30], # in
109
- store_id: {not: 2}, # not
110
- aisle_id: {not: [25, 30]}, # not in
111
- user_ids: {all: [1, 3]}, # all elements in array
112
- category: {like: "%frozen%"}, # like
113
- category: /frozen .+/, # regexp
114
- category: {prefix: "frozen"}, # prefix
115
- store_id: {exists: true}, # exists
106
+ expires_at: {gt: Time.now}, # lt, gte, lte also available
107
+ orders_count: 1..10, # equivalent to {gte: 1, lte: 10}
108
+ aisle_id: [25, 30], # in
109
+ store_id: {not: 2}, # not
110
+ aisle_id: {not: [25, 30]}, # not in
111
+ user_ids: {all: [1, 3]}, # all elements in array
112
+ category: {like: "%frozen%"}, # like
113
+ category: {ilike: "%frozen%"}, # ilike
114
+ category: /frozen .+/, # regexp
115
+ category: {prefix: "frozen"}, # prefix
116
+ store_id: {exists: true}, # exists
116
117
  _or: [{in_stock: true}, {backordered: true}],
117
118
  _and: [{in_stock: true}, {backordered: true}],
118
- _not: {store_id: 1} # negate a condition
119
+ _not: {store_id: 1} # negate a condition
119
120
  }
120
121
  ```
121
122
 
@@ -125,7 +126,7 @@ Order
125
126
  order: {_score: :desc} # most relevant first - default
126
127
  ```
127
128
 
128
- [All of these sort options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html)
129
+ [All of these sort options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html)
129
130
 
130
131
  Limit / offset
131
132
 
@@ -139,7 +140,7 @@ Select
139
140
  select: [:name]
140
141
  ```
141
142
 
142
- [These source filtering options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-source-filtering)
143
+ [These source filtering options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#source-filtering)
143
144
 
144
145
  ### Results
145
146
 
@@ -392,7 +393,7 @@ search_synonyms: "synonyms.txt"
392
393
  Add [elasticsearch-xpack](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-xpack) to your Gemfile:
393
394
 
394
395
  ```ruby
395
- gem 'elasticsearch-xpack', '>= 7.8.0'
396
+ gem 'elasticsearch-xpack', '>= 7.8', '< 7.14'
396
397
  ```
397
398
 
398
399
  And use:
@@ -401,7 +402,7 @@ And use:
401
402
  Product.search_index.reload_synonyms
402
403
  ```
403
404
 
404
- #### Elasticsearch < 7.3
405
+ #### Elasticsearch < 7.3 or OpenSearch
405
406
 
406
407
  You can use a library like [ActsAsTaggableOn](https://github.com/mbleigh/acts-as-taggable-on) and do:
407
408
 
@@ -649,7 +650,7 @@ class Product < ApplicationRecord
649
650
  def search_data
650
651
  {
651
652
  name: name,
652
- conversions: searches.group(:query).uniq.count(:user_id)
653
+ conversions: searches.group(:query).distinct.count(:user_id)
653
654
  # {"ice cream" => 234, "chocolate" => 67, "cream" => 2}
654
655
  }
655
656
  end
@@ -899,7 +900,7 @@ Additional options can be specified for each field:
899
900
  Band.search "cinema", fields: [:name], highlight: {fields: {name: {fragment_size: 200}}}
900
901
  ```
901
902
 
902
- You can find available highlight options in the [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html#_highlighted_fragments).
903
+ You can find available highlight options in the [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html).
903
904
 
904
905
  ## Similar Items
905
906
 
@@ -950,7 +951,7 @@ Boost results by distance - closer results are boosted more
950
951
  Restaurant.search "noodles", boost_by_distance: {location: {origin: {lat: 37, lon: -122}}}
951
952
  ```
952
953
 
953
- Also supports [additional options](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#_decay_functions)
954
+ Also supports [additional options](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay)
954
955
 
955
956
  ```ruby
956
957
  Restaurant.search "wings", boost_by_distance: {location: {origin: {lat: 37, lon: -122}, function: "linear", scale: "30mi", decay: 0.5}}
@@ -1212,19 +1213,25 @@ FactoryBot.create(:product, :some_trait, :reindex, some_attribute: "foo")
1212
1213
 
1213
1214
  ### GitHub Actions
1214
1215
 
1215
- Check out [setup-elasticsearch](https://github.com/ankane/setup-elasticsearch) for an easy way to install Elasticsearch.
1216
+ Check out [setup-elasticsearch](https://github.com/ankane/setup-elasticsearch) for an easy way to install Elasticsearch:
1216
1217
 
1217
1218
  ```yml
1218
1219
  - uses: ankane/setup-elasticsearch@v1
1219
1220
  ```
1220
1221
 
1222
+ And [setup-opensearch](https://github.com/ankane/setup-opensearch) for an easy way to install OpenSearch:
1223
+
1224
+ ```yml
1225
+ - uses: ankane/setup-opensearch@v1
1226
+ ```
1227
+
1221
1228
  ## Deployment
1222
1229
 
1223
1230
  Searchkick uses `ENV["ELASTICSEARCH_URL"]` for the Elasticsearch server. This defaults to `http://localhost:9200`.
1224
1231
 
1225
1232
  - [Elastic Cloud](#elastic-cloud)
1226
1233
  - [Heroku](#heroku)
1227
- - [Amazon Elasticsearch Service](#amazon-elasticsearch-service)
1234
+ - [Amazon OpenSearch Service](#amazon-opensearch-service)
1228
1235
  - [Self-Hosted and Other](#self-hosted-and-other)
1229
1236
 
1230
1237
  ### Elastic Cloud
@@ -1248,7 +1255,7 @@ Choose an add-on: [Bonsai](https://elements.heroku.com/addons/bonsai), [SearchBo
1248
1255
  For Bonsai:
1249
1256
 
1250
1257
  ```sh
1251
- heroku addons:create bonsai
1258
+ heroku addons:create bonsai # use --engine=opensearch for OpenSearch
1252
1259
  heroku config:set ELASTICSEARCH_URL=`heroku config:get BONSAI_URL`
1253
1260
  ```
1254
1261
 
@@ -1284,7 +1291,7 @@ Then deploy and reindex:
1284
1291
  heroku run rake searchkick:reindex:all
1285
1292
  ```
1286
1293
 
1287
- ### Amazon Elasticsearch Service
1294
+ ### Amazon OpenSearch Service
1288
1295
 
1289
1296
  Create an initializer `config/initializers/elasticsearch.rb` with:
1290
1297
 
@@ -1580,14 +1587,14 @@ class ReindexConversionsJob < ApplicationJob
1580
1587
  # get records that have a recent conversion
1581
1588
  recently_converted_ids =
1582
1589
  Searchjoy::Search.where("convertable_type = ? AND converted_at > ?", class_name, 1.day.ago)
1583
- .order(:convertable_id).uniq.pluck(:convertable_id)
1590
+ .order(:convertable_id).distinct.pluck(:convertable_id)
1584
1591
 
1585
1592
  # split into groups
1586
1593
  recently_converted_ids.in_groups_of(1000, false) do |ids|
1587
1594
  # fetch conversions
1588
1595
  conversions =
1589
1596
  Searchjoy::Search.where(convertable_id: ids, convertable_type: class_name)
1590
- .group(:convertable_id, :query).uniq.count(:user_id)
1597
+ .group(:convertable_id, :query).distinct.count(:user_id)
1591
1598
 
1592
1599
  # group conversions by record
1593
1600
  conversions_by_record = {}
@@ -1711,7 +1718,7 @@ Check out [this great post](https://www.tiagoamaro.com.br/2014/12/11/multi-tenan
1711
1718
 
1712
1719
  ## Scroll API
1713
1720
 
1714
- Searchkick also supports the [scroll API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html). Scrolling is not intended for real time user requests, but rather for processing large amounts of data.
1721
+ Searchkick also supports the [scroll API](https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html#scroll-search-results). Scrolling is not intended for real time user requests, but rather for processing large amounts of data.
1715
1722
 
1716
1723
  ```ruby
1717
1724
  Product.search("*", scroll: "1m").scroll do |batch|
@@ -1839,7 +1846,7 @@ class Product < ApplicationRecord
1839
1846
  def search_data
1840
1847
  {
1841
1848
  name: name,
1842
- unique_user_conversions: searches.group(:query).uniq.count(:user_id),
1849
+ unique_user_conversions: searches.group(:query).distinct.count(:user_id),
1843
1850
  # {"ice cream" => 234, "chocolate" => 67, "cream" => 2}
1844
1851
  total_conversions: searches.group(:query).count
1845
1852
  # {"ice cream" => 412, "chocolate" => 117, "cream" => 6}
@@ -1964,7 +1971,7 @@ products = Product.search("carrots", execute: false)
1964
1971
  products.each { ... } # search not executed until here
1965
1972
  ```
1966
1973
 
1967
- Add [request parameters](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html), like `search_type` and `query_cache`
1974
+ Add [request parameters](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html#search-search-api-query-params) like `search_type`
1968
1975
 
1969
1976
  ```ruby
1970
1977
  Product.search("carrots", request_params: {search_type: "dfs_query_then_fetch"})
@@ -363,7 +363,7 @@ module Searchkick
363
363
  end
364
364
  rescue Elasticsearch::Transport::Transport::Errors::BadRequest => e
365
365
  if e.message.include?("No handler for type [text]")
366
- raise UnsupportedVersionError, "This version of Searchkick requires Elasticsearch 5 or greater"
366
+ raise UnsupportedVersionError, "This version of Searchkick requires Elasticsearch 6 or greater"
367
367
  end
368
368
 
369
369
  raise e
@@ -11,7 +11,7 @@ module Searchkick
11
11
  if record_ids.any?
12
12
  batch_options = {
13
13
  class_name: class_name,
14
- record_ids: record_ids,
14
+ record_ids: record_ids.uniq,
15
15
  index_name: index_name
16
16
  }
17
17
 
@@ -1,5 +1,6 @@
1
1
  module Searchkick
2
2
  class Query
3
+ include Enumerable
3
4
  extend Forwardable
4
5
 
5
6
  @@metric_aggs = [:avg, :cardinality, :max, :min, :sum]
@@ -12,7 +13,8 @@ module Searchkick
12
13
  :took, :error, :model_name, :entry_name, :total_count, :total_entries,
13
14
  :current_page, :per_page, :limit_value, :padding, :total_pages, :num_pages,
14
15
  :offset_value, :offset, :previous_page, :prev_page, :next_page, :first_page?, :last_page?,
15
- :out_of_range?, :hits, :response, :to_a, :first, :scroll
16
+ :out_of_range?, :hits, :response, :to_a, :first, :scroll, :highlights, :with_highlights,
17
+ :with_score, :misspellings?, :scroll_id, :clear_scroll, :missing_records, :with_hit
16
18
 
17
19
  def initialize(klass, term = "*", **options)
18
20
  unknown_keywords = options.keys - [:aggs, :block, :body, :body_options, :boost,
@@ -109,7 +111,12 @@ module Searchkick
109
111
  request_params = query.except(:index, :type, :body)
110
112
 
111
113
  # no easy way to tell which host the client will use
112
- host = Searchkick.client.transport.hosts.first
114
+ host =
115
+ if Gem::Version.new(Elasticsearch::VERSION) >= Gem::Version.new("7.14.0")
116
+ Searchkick.client.transport.transport.hosts.first
117
+ else
118
+ Searchkick.client.transport.hosts.first
119
+ end
113
120
  credentials = host[:user] || host[:password] ? "#{host[:user]}:#{host[:password]}@" : nil
114
121
  params = ["pretty"]
115
122
  request_params.each do |k, v|
@@ -864,10 +871,11 @@ module Searchkick
864
871
  }
865
872
  end
866
873
 
867
- # TODO id transformation for arrays
868
874
  def set_order(payload)
869
875
  order = options[:order].is_a?(Enumerable) ? options[:order] : {options[:order] => :asc}
870
876
  id_field = :_id
877
+ # TODO no longer map id to _id in Searchkick 5
878
+ # since sorting on _id is deprecated in Elasticsearch
871
879
  payload[:sort] = order.is_a?(Array) ? order : Hash[order.map { |k, v| [k.to_s == "id" ? id_field : k, v] }]
872
880
  end
873
881
 
@@ -953,7 +961,7 @@ module Searchkick
953
961
  }
954
962
  }
955
963
  }
956
- when :like
964
+ when :like, :ilike
957
965
  # based on Postgres
958
966
  # https://www.postgresql.org/docs/current/functions-matching.html
959
967
  # % matches zero or more characters
@@ -967,7 +975,16 @@ module Searchkick
967
975
  regex.gsub!(v, "\\" + v)
968
976
  end
969
977
  regex = regex.gsub(/(?<!\\)%/, ".*").gsub(/(?<!\\)_/, ".").gsub("\\%", "%").gsub("\\_", "_")
970
- filters << {regexp: {field => {value: regex, flags: "NONE"}}}
978
+
979
+ if op == :ilike
980
+ if below710?
981
+ raise ArgumentError, "ilike requires Elasticsearch 7.10+"
982
+ else
983
+ filters << {regexp: {field => {value: regex, flags: "NONE", case_insensitive: true}}}
984
+ end
985
+ else
986
+ filters << {regexp: {field => {value: regex, flags: "NONE"}}}
987
+ end
971
988
  when :prefix
972
989
  filters << {prefix: {field => {value: op_value}}}
973
990
  when :regexp # support for regexp queries without using a regexp ruby object
@@ -1022,10 +1039,6 @@ module Searchkick
1022
1039
  elsif value.nil?
1023
1040
  {bool: {must_not: {exists: {field: field}}}}
1024
1041
  elsif value.is_a?(Regexp)
1025
- if value.casefold?
1026
- Searchkick.warn("Case-insensitive flag does not work with Elasticsearch")
1027
- end
1028
-
1029
1042
  source = value.source
1030
1043
  unless source.start_with?("\\A") && source.end_with?("\\z")
1031
1044
  # https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html
@@ -1047,7 +1060,14 @@ module Searchkick
1047
1060
  # source = "#{source}.*"
1048
1061
  end
1049
1062
 
1050
- {regexp: {field => {value: source, flags: "NONE"}}}
1063
+ if below710?
1064
+ if value.casefold?
1065
+ Searchkick.warn("Case-insensitive flag does not work with Elasticsearch < 7.10")
1066
+ end
1067
+ {regexp: {field => {value: source, flags: "NONE"}}}
1068
+ else
1069
+ {regexp: {field => {value: source, flags: "NONE", case_insensitive: value.casefold?}}}
1070
+ end
1051
1071
  else
1052
1072
  # TODO add this for other values
1053
1073
  if value.as_json.is_a?(Enumerable)
@@ -1145,5 +1165,9 @@ module Searchkick
1145
1165
  def below75?
1146
1166
  Searchkick.server_below?("7.5.0")
1147
1167
  end
1168
+
1169
+ def below710?
1170
+ Searchkick.server_below?("7.10.0")
1171
+ end
1148
1172
  end
1149
1173
  end
@@ -14,11 +14,17 @@ module Searchkick
14
14
 
15
15
  # TODO use reliable queuing
16
16
  def reserve(limit: 1000)
17
- record_ids = Set.new
18
- while record_ids.size < limit && (record_id = Searchkick.with_redis { |r| r.rpop(redis_key) })
19
- record_ids << record_id
17
+ if supports_rpop_with_count?
18
+ Searchkick.with_redis { |r| r.call("rpop", redis_key, limit) }.to_a
19
+ else
20
+ record_ids = []
21
+ Searchkick.with_redis do |r|
22
+ while record_ids.size < limit && (record_id = r.rpop(redis_key))
23
+ record_ids << record_id
24
+ end
25
+ end
26
+ record_ids
20
27
  end
21
- record_ids.to_a
22
28
  end
23
29
 
24
30
  def clear
@@ -34,5 +40,13 @@ module Searchkick
34
40
  def redis_key
35
41
  "searchkick:reindex_queue:#{name}"
36
42
  end
43
+
44
+ def supports_rpop_with_count?
45
+ redis_version >= Gem::Version.new("6.2")
46
+ end
47
+
48
+ def redis_version
49
+ @redis_version ||= Searchkick.with_redis { |r| Gem::Version.new(r.info["redis_version"]) }
50
+ end
37
51
  end
38
52
  end
@@ -71,7 +71,11 @@ module Searchkick
71
71
  end
72
72
 
73
73
  def model_name
74
- klass.model_name
74
+ if klass.nil?
75
+ ActiveModel::Name.new(self.class, nil, 'Result')
76
+ else
77
+ klass.model_name
78
+ end
75
79
  end
76
80
 
77
81
  def entry_name(options = {})
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "4.5.0"
2
+ VERSION = "4.6.1"
3
3
  end
data/lib/searchkick.rb CHANGED
@@ -56,7 +56,7 @@ module Searchkick
56
56
  require "typhoeus/adapters/faraday" if defined?(Typhoeus) && Gem::Version.new(Faraday::VERSION) < Gem::Version.new("0.14.0")
57
57
 
58
58
  Elasticsearch::Client.new({
59
- url: ENV["ELASTICSEARCH_URL"],
59
+ url: ENV["ELASTICSEARCH_URL"] || ENV["OPENSEARCH_URL"],
60
60
  transport_options: {request: {timeout: timeout}, headers: {content_type: "application/json"}},
61
61
  retry_on_failure: 2
62
62
  }.deep_merge(client_options)) do |f|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchkick
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.0
4
+ version: 4.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-07 00:00:00.000000000 Z
11
+ date: 2021-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -31,6 +31,9 @@ dependencies:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '6'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '7.14'
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,6 +41,9 @@ dependencies:
38
41
  - - ">="
39
42
  - !ruby/object:Gem::Version
40
43
  version: '6'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '7.14'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: hashie
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +59,7 @@ dependencies:
53
59
  - !ruby/object:Gem::Version
54
60
  version: '0'
55
61
  description:
56
- email: andrew@chartkick.com
62
+ email: andrew@ankane.org
57
63
  executables: []
58
64
  extensions: []
59
65
  extra_rdoc_files: []
@@ -102,8 +108,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
108
  - !ruby/object:Gem::Version
103
109
  version: '0'
104
110
  requirements: []
105
- rubygems_version: 3.2.3
111
+ rubygems_version: 3.2.22
106
112
  signing_key:
107
113
  specification_version: 4
108
- summary: Intelligent search made easy with Rails and Elasticsearch
114
+ summary: Intelligent search made easy with Rails and Elasticsearch or OpenSearch
109
115
  test_files: []