searchkick 4.5.0 → 4.6.1

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: 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: []