Skip to content

Commit dbd4a3a

Browse files
committed
Add Elasticsearch 9.x support
Elasticsearch 9.x introduced breaking changes to the elasticsearch-ruby client gem that prevent Chewy from working with ES 9 clusters: 1. The scroll API now requires scroll_id nested under a body: key ({scroll: '1m', body: {scroll_id: '...'}}) rather than as a top-level parameter. Without this, scroll requests raise an ArgumentError in elasticsearch-ruby 9.x. 2. API responses are now wrapped in Elasticsearch::API::Response objects instead of returning raw hashes/arrays. Code that calls .map or other Enumerable methods directly on responses (e.g. cat.indices) must now call .body first to access the underlying data. 3. The '_type' field was removed from search responses in ES 7+ and the elasticsearch-ruby 9.x client no longer includes it. Mock response helpers that included '_type' => '_doc' produced responses that diverged from actual ES behavior. Changes: - Widen elasticsearch gem dependency from < 9.0 to < 10.0 - Restructure perform_scroll to nest scroll_id under body:, which is compatible with both elasticsearch-ruby 8.x and 9.x - Access .body on cat.indices response in the drop_indices test helper - Remove '_type' => '_doc' from Minitest and RSpec mock response helpers - Add elasticsearch version matrix to CI (9.3.1 default with 8.15.0 spot-checks) using dynamic service container images - Default docker-compose ES image to 9.3.1 - Bump version to 9.0.0
1 parent f4afb4c commit dbd4a3a

10 files changed

Lines changed: 32 additions & 12 deletions

File tree

.github/workflows/ruby.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,15 @@ jobs:
2727
matrix:
2828
ruby: [ '3.2', '3.3', '3.4', '4.0' ]
2929
gemfile: [rails.7.2.activerecord, rails.8.0.activerecord, rails.8.1.activerecord]
30-
name: ${{ matrix.ruby }}-${{ matrix.gemfile }}
30+
elasticsearch: ['9.3.1']
31+
include:
32+
- ruby: '3.2'
33+
gemfile: rails.7.2.activerecord
34+
elasticsearch: '8.15.0'
35+
- ruby: '4.0'
36+
gemfile: rails.8.1.activerecord
37+
elasticsearch: '8.15.0'
38+
name: ${{ matrix.ruby }}-${{ matrix.gemfile }}-es${{ matrix.elasticsearch }}
3139

3240
env:
3341
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
@@ -45,7 +53,7 @@ jobs:
4553
--health-timeout 5s
4654
--health-retries 5
4755
elasticsearch:
48-
image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
56+
image: docker.elastic.co/elasticsearch/elasticsearch:${{ matrix.elasticsearch }}
4957
ports:
5058
- '9250:9200'
5159
env:

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## 9.0.0 (unreleased)
4+
5+
### New Features
6+
7+
* [#1009](https://github.com/toptal/chewy/pull/1009): Add Elasticsearch 9.x support while retaining ES 8.x compatibility. The `elasticsearch` gem dependency now allows `>= 8.14, < 10.0`. ([@mattmenefee][])
8+
9+
### Changes
10+
11+
* [#1009](https://github.com/toptal/chewy/pull/1009): **(Breaking)** The `search_query.chewy` notification payload for scroll requests now nests `scroll_id` under `body:` (i.e. `{scroll: '1m', body: {scroll_id: '...'}}` instead of `{scroll: '1m', scroll_id: '...'}`). Update any application code that subscribes to scroll notification payloads. ([@mattmenefee][])
12+
* [#1009](https://github.com/toptal/chewy/pull/1009): Remove `'_type' => '_doc'` from mock response helpers in `Chewy::Minitest::Helpers` and `Chewy::Rspec::Helpers` to match actual ES response format (ES 7+ no longer returns `_type`). ([@mattmenefee][])
13+
14+
### Bugs Fixed
15+
316
## 8.0.2 (unreleased)
417

518
### Changes

chewy.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
1818
spec.require_paths = ['lib']
1919

2020
spec.add_dependency 'activesupport', '>= 7.2'
21-
spec.add_dependency 'elasticsearch', '>= 8.14', '< 9.0'
21+
spec.add_dependency 'elasticsearch', '>= 8.14', '< 10.0'
2222
spec.add_dependency 'elasticsearch-dsl'
2323
spec.metadata['rubygems_mfa_required'] = 'true'
2424
end

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
elasticsearch_test:
3-
image: "docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION:-8.15.0}"
3+
image: "docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION:-9.3.1}"
44
environment:
55
- bootstrap.memory_lock=${ES_MEMORY_LOCK:-false}
66
- "ES_JAVA_OPTS=-Xms${TEST_ES_HEAP_SIZE:-500m} -Xmx${TEST_ES_HEAP_SIZE:-500m}"

lib/chewy/minitest/helpers.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ def mock_elasticsearch_response_sources(index, hits, &block)
9696
'hits' => hits.each_with_index.map do |hit, i|
9797
{
9898
'_index' => index.index_name,
99-
'_type' => '_doc',
10099
'_id' => hit[:id] || (i + 1).to_s,
101100
'_score' => 3.14,
102101
'_source' => hit

lib/chewy/rspec/helpers.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def mock_elasticsearch_response_sources(index, hits)
3939
'hits' => hits.each_with_index.map do |hit, i|
4040
{
4141
'_index' => index.index_name,
42-
'_type' => '_doc',
4342
'_id' => (i + 1).to_s,
4443
'_score' => 3.14,
4544
'_source' => hit

lib/chewy/search/scrolling.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,10 @@ def scroll_objects(**options, &block)
128128

129129
private
130130

131-
def perform_scroll(body)
132-
ActiveSupport::Notifications.instrument 'search_query.chewy', notification_payload(request: body) do
133-
Chewy.client.scroll(body)
131+
def perform_scroll(scroll:, scroll_id:)
132+
request = {scroll: scroll, body: {scroll_id: scroll_id}}
133+
ActiveSupport::Notifications.instrument 'search_query.chewy', notification_payload(request: request) do
134+
Chewy.client.scroll(request)
134135
end
135136
end
136137
end

lib/chewy/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Chewy
2-
VERSION = '8.0.1'.freeze
2+
VERSION = '9.0.0'.freeze
33
end

spec/chewy/search/scrolling_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
hash_including(
127127
index: [CitiesIndex, CountriesIndex],
128128
indexes: [CitiesIndex, CountriesIndex],
129-
request: {scroll: '1m', scroll_id: an_instance_of(String)}
129+
request: {scroll: '1m', body: {scroll_id: an_instance_of(String)}}
130130
)
131131
])
132132
end

spec/spec_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
# Low-level substitute for now-obsolete drop_indices
4747
def drop_indices
4848
indices = Chewy.client.cat.indices(format: 'json')
49-
.map { |entry| entry['index'] }
49+
.body.map { |entry| entry['index'] }
5050
.reject { |name| name.start_with?('.') }
5151
return if indices.blank?
5252

0 commit comments

Comments
 (0)