search_flip 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +6 -4
- data/CHANGELOG.md +10 -0
- data/README.md +16 -2
- data/lib/search_flip/criteria.rb +40 -10
- data/lib/search_flip/index.rb +2 -1
- data/lib/search_flip/version.rb +1 -1
- data/lib/search_flip.rb +1 -1
- data/search_flip.gemspec +1 -2
- data/test/search_flip/criteria_test.rb +13 -0
- data/test/search_flip/index_test.rb +1 -1
- data/test/test_helper.rb +7 -8
- metadata +4 -4
- data/irb.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62b02c26a3579fdda9d1eca222c6c1eb19b28382
|
4
|
+
data.tar.gz: fc3fe009dc1c8d84d03ab497c5302922474282c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6cee1c3258c0ff0662cec18d72313552706054e55a08c2f14003999c6d0d4bb910112507da340ad9dc1510b9f3f4b422ce11b0ec1b7eea8481450d430436bfc
|
7
|
+
data.tar.gz: 9062e11098ab36c5063f992284a1d94ea27b422fabb0d4e94aa5b1c5b37da8c0508326d20566ab155f649034e2f924e739795b4ab89ab06ca6b2fa107f0e3bd3
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
-
|
5
|
-
- 2.3.1
|
3
|
+
- 2.3.3
|
4
|
+
- ruby-head
|
6
5
|
|
7
6
|
dist: trusty
|
8
7
|
|
@@ -13,9 +12,12 @@ env:
|
|
13
12
|
- ES_VERSION=1
|
14
13
|
- ES_VERSION=2
|
15
14
|
- ES_VERSION=5
|
15
|
+
- ES_VERSION=6
|
16
16
|
|
17
17
|
install:
|
18
18
|
- travis_retry bundle install
|
19
|
+
- sh -c "if [ '$ES_VERSION' = '6' ]; then (curl -s https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.2.tar.gz | tar xz -C /tmp); fi"
|
20
|
+
- sh -c "if [ '$ES_VERSION' = '6' ]; then /tmp/elasticsearch-6.2.2/bin/elasticsearch -d; fi"
|
19
21
|
- sh -c "if [ '$ES_VERSION' = '5' ]; then (curl -s https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.4.0.tar.gz | tar xz -C /tmp); fi"
|
20
22
|
- sh -c "if [ '$ES_VERSION' = '5' ]; then /tmp/elasticsearch-5.4.0/bin/elasticsearch -d; fi"
|
21
23
|
- sh -c "if [ '$ES_VERSION' = '2' ]; then (curl -s https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.4.1/elasticsearch-2.4.1.tar.gz | tar xz -C /tmp); fi"
|
@@ -28,7 +30,7 @@ before_script:
|
|
28
30
|
- sleep 30
|
29
31
|
|
30
32
|
script:
|
31
|
-
-
|
33
|
+
- rake test --trace
|
32
34
|
|
33
35
|
sudo: false
|
34
36
|
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
|
2
|
+
# CHANGELOG
|
3
|
+
|
4
|
+
* Version 1.1.0
|
5
|
+
|
6
|
+
- Added `Criteria#find_results_in_batches` to scroll through the raw results
|
7
|
+
- Fixed bug in `Criteria#find_in_batches` which possibly stopped scrolling too early
|
8
|
+
- Added delegation for `should`, `should_not`, `must` and `must_not`
|
9
|
+
- Migrated To FactoryBot
|
10
|
+
|
data/README.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
|
2
2
|
# SearchFlip
|
3
3
|
|
4
|
+
**Full-Featured ElasticSearch Ruby Client with a Chainable DSL**
|
5
|
+
|
4
6
|
[![Build Status](https://secure.travis-ci.org/mrkamel/search_flip.png?branch=master)](http://travis-ci.org/mrkamel/search_flip)
|
7
|
+
[![Gem Version](https://badge.fury.io/rb/search_flip.svg)](http://badge.fury.io/rb/search_flip)
|
5
8
|
|
6
9
|
Using SearchFlip it is dead-simple to create index classes that correspond to
|
7
10
|
[ElasticSearch](https://www.elastic.co/) indices and to manipulate, query and
|
@@ -338,7 +341,7 @@ query.results[0].highlight.title # => "<em>hello</em> world"
|
|
338
341
|
|
339
342
|
There are even more methods to make your life easier, namely `source`,
|
340
343
|
`scroll`, `profile`, `includes`, `preload`, `find_in_batches`, `find_each`,
|
341
|
-
`failsafe` and `unscope` to name just a few:
|
344
|
+
`find_results_in_batches`, `failsafe` and `unscope` to name just a few:
|
342
345
|
|
343
346
|
* `source`
|
344
347
|
|
@@ -378,7 +381,7 @@ end
|
|
378
381
|
|
379
382
|
* `profile`
|
380
383
|
|
381
|
-
Use `#profile`
|
384
|
+
Use `#profile` to enable query profiling:
|
382
385
|
|
383
386
|
```ruby
|
384
387
|
query = CommentIndex.profile(true)
|
@@ -424,6 +427,17 @@ CommentIndex.search("hello world").find_in_batches(batch_size: 100) do |batch|
|
|
424
427
|
end
|
425
428
|
```
|
426
429
|
|
430
|
+
* `find_results_in_batches`
|
431
|
+
|
432
|
+
Used like `find_in_batches`, but yielding the raw results instead of database
|
433
|
+
records. Again, the batch size and scroll API timeout can be specified.
|
434
|
+
|
435
|
+
```ruby
|
436
|
+
CommentIndex.search("hello world").find_results_in_batches(batch_size: 100) do |batch|
|
437
|
+
# ...
|
438
|
+
end
|
439
|
+
```
|
440
|
+
|
427
441
|
* `find_each`
|
428
442
|
|
429
443
|
Like `#find_in_batches`, use `#find_each` to fetch records in batches, but yields
|
data/lib/search_flip/criteria.rb
CHANGED
@@ -590,21 +590,36 @@ module SearchFlip
|
|
590
590
|
# batch. Uses #limit to control the batch size.
|
591
591
|
# @option options timeout [String] The timeout per scroll request, ie how
|
592
592
|
# long ElasticSearch will keep the request handle open.
|
593
|
-
#
|
594
|
-
# @return [SearchFlip::Criteria] A newly created extended criteria
|
595
593
|
|
596
594
|
def find_in_batches(options = {})
|
597
595
|
return enum_for(:find_in_batches, options) unless block_given?
|
598
596
|
|
599
|
-
|
600
|
-
|
597
|
+
yield_in_batches(options) do |criteria|
|
598
|
+
yield(criteria.records) if criteria.records.size > 0
|
599
|
+
end
|
600
|
+
end
|
601
601
|
|
602
|
-
|
602
|
+
# Fetches the results specified by the criteria in batches using the
|
603
|
+
# ElasticSearch scroll API and yields each batch. The batch size and scroll
|
604
|
+
# API timeout can be specified. Checkout out the ElasticSearch docs for
|
605
|
+
# further details.
|
606
|
+
#
|
607
|
+
# @example
|
608
|
+
# CommentIndex.search("hello world").find_results_in_batches(batch_size: 100) do |batch|
|
609
|
+
# # ...
|
610
|
+
# end
|
611
|
+
#
|
612
|
+
# @param options [Hash] The options to control the fetching of batches
|
613
|
+
# @option options batch_size [Fixnum] The number of records to fetch per
|
614
|
+
# batch. Uses #limit to control the batch size.
|
615
|
+
# @option options timeout [String] The timeout per scroll request, ie how
|
616
|
+
# long ElasticSearch will keep the request handle open.
|
603
617
|
|
604
|
-
|
605
|
-
|
618
|
+
def find_results_in_batches(options = {})
|
619
|
+
return enum_for(:find_results_in_batches, options) unless block_given?
|
606
620
|
|
607
|
-
|
621
|
+
yield_in_batches(options) do |criteria|
|
622
|
+
yield criteria.results
|
608
623
|
end
|
609
624
|
end
|
610
625
|
|
@@ -623,8 +638,6 @@ module SearchFlip
|
|
623
638
|
# batch. Uses #limit to control the batch size.
|
624
639
|
# @option options timeout [String] The timeout per scroll request, ie how
|
625
640
|
# long ElasticSearch will keep the request handle open.
|
626
|
-
#
|
627
|
-
# @return [SearchFlip::Criteria] A newly created extended criteria
|
628
641
|
|
629
642
|
def find_each(options = {})
|
630
643
|
return enum_for(:find_each, options) unless block_given?
|
@@ -732,6 +745,23 @@ module SearchFlip
|
|
732
745
|
|
733
746
|
def_delegators :response, :total_entries, :total_count, :current_page, :previous_page, :prev_page, :next_page, :first_page?, :last_page?, :out_of_range?, :total_pages,
|
734
747
|
:hits, :ids, :count, :size, :length, :took, :aggregations, :suggestions, :scope, :results, :records, :scroll_id, :raw_response
|
748
|
+
|
749
|
+
private
|
750
|
+
|
751
|
+
def yield_in_batches(options = {})
|
752
|
+
return enum_for(:yield_in_batches, options) unless block_given?
|
753
|
+
|
754
|
+
batch_size = options[:batch_size] || 1_000
|
755
|
+
timeout = options[:timeout] || "1m"
|
756
|
+
|
757
|
+
criteria = limit(batch_size).scroll(timeout: timeout)
|
758
|
+
|
759
|
+
until criteria.ids.empty?
|
760
|
+
yield criteria.response
|
761
|
+
|
762
|
+
criteria = criteria.scroll(id: criteria.scroll_id, timeout: timeout)
|
763
|
+
end
|
764
|
+
end
|
735
765
|
end
|
736
766
|
end
|
737
767
|
|
data/lib/search_flip/index.rb
CHANGED
@@ -216,7 +216,8 @@ module SearchFlip
|
|
216
216
|
|
217
217
|
def_delegators :criteria, :profile, :where, :where_not, :filter, :range, :match_all, :exists, :exists_not, :post_where, :post_where_not, :post_filter, :post_range,
|
218
218
|
:post_exists, :post_exists_not, :aggregate, :scroll, :source, :includes, :eager_load, :preload, :sort, :resort, :order, :reorder, :offset, :limit, :paginate,
|
219
|
-
:page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_each, :failsafe, :total_entries, :total_count, :timeout,
|
219
|
+
:page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_results_in_batches, :find_each, :failsafe, :total_entries, :total_count, :timeout,
|
220
|
+
:terminate_after, :records, :should, :should_not, :must, :must_not
|
220
221
|
|
221
222
|
# Override to specify the type name used within ElasticSearch. Recap,
|
222
223
|
# this gem uses an individual index for each index class, because
|
data/lib/search_flip/version.rb
CHANGED
data/lib/search_flip.rb
CHANGED
@@ -76,7 +76,7 @@ module SearchFlip
|
|
76
76
|
# @return [SearchFlip::Response] The raw response
|
77
77
|
|
78
78
|
def self.aliases(payload)
|
79
|
-
SearchFlip::HTTPClient.headers(accept: "application/json").post("#{SearchFlip::Config[:base_url]}/_aliases", body: SearchFlip::JSON.generate(payload))
|
79
|
+
SearchFlip::HTTPClient.headers(accept: "application/json", content_type: "application/json").post("#{SearchFlip::Config[:base_url]}/_aliases", body: SearchFlip::JSON.generate(payload))
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
data/search_flip.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "minitest"
|
24
24
|
spec.add_development_dependency "mocha"
|
25
|
-
spec.add_development_dependency "
|
25
|
+
spec.add_development_dependency "factory_bot"
|
26
26
|
spec.add_development_dependency "sqlite3"
|
27
27
|
spec.add_development_dependency "activerecord", ">= 3.0"
|
28
28
|
spec.add_development_dependency "webmock"
|
@@ -32,4 +32,3 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_dependency "hashie"
|
33
33
|
spec.add_dependency "oj"
|
34
34
|
end
|
35
|
-
|
@@ -755,6 +755,19 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
755
755
|
assert_equal [[expected1, expected2], [expected3]], ProductIndex.where(title: "expected").sort(:rank).find_in_batches(batch_size: 2).to_a
|
756
756
|
end
|
757
757
|
|
758
|
+
def test_find_results_in_batches
|
759
|
+
expected1 = create(:product, title: "expected", rank: 1)
|
760
|
+
expected2 = create(:product, title: "expected", rank: 2)
|
761
|
+
expected3 = create(:product, title: "expected", rank: 3)
|
762
|
+
rejected = create(:product, title: "rejected")
|
763
|
+
|
764
|
+
create :product, title: "rejected"
|
765
|
+
|
766
|
+
ProductIndex.import [expected1, expected2, expected3, rejected]
|
767
|
+
|
768
|
+
assert_equal [[expected1.id, expected2.id], [expected3.id]], ProductIndex.where(title: "expected").sort(:rank).find_results_in_batches(batch_size: 2).map { |batch| batch.map(&:id) }
|
769
|
+
end
|
770
|
+
|
758
771
|
def test_find_each
|
759
772
|
expected1 = create(:product, title: "expected", rank: 1)
|
760
773
|
expected2 = create(:product, title: "expected", rank: 2)
|
@@ -6,7 +6,7 @@ class SearchFlip::IndexTest < SearchFlip::TestCase
|
|
6
6
|
:post_where_not, :post_filter, :post_range, :post_exists, :post_exists_not, :aggregate, :scroll, :source, :includes,
|
7
7
|
:eager_load, :preload, :sort, :resort, :order, :reorder, :offset, :limit, :paginate, :page, :per, :search,
|
8
8
|
:find_in_batches, :highlight, :suggest, :custom, :find_each, :failsafe, :total_entries, :total_count, :terminate_after,
|
9
|
-
:timeout, to: :criteria, subject: ProductIndex
|
9
|
+
:timeout, :should, :should_not, :must, :must_not, to: :criteria, subject: ProductIndex
|
10
10
|
|
11
11
|
def test_create_index
|
12
12
|
assert TestIndex.create_index
|
data/test/test_helper.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
require "minitest"
|
3
3
|
require "minitest/autorun"
|
4
4
|
require "webmock/minitest"
|
5
|
-
require "mocha/
|
5
|
+
require "mocha/minitest"
|
6
6
|
require "search_flip"
|
7
7
|
require "active_record"
|
8
|
-
require "
|
8
|
+
require "factory_bot"
|
9
9
|
require "timecop"
|
10
10
|
require "yaml"
|
11
11
|
|
@@ -35,7 +35,7 @@ class Product < ActiveRecord::Base
|
|
35
35
|
has_many :comments
|
36
36
|
end
|
37
37
|
|
38
|
-
|
38
|
+
FactoryBot.define do
|
39
39
|
factory :product
|
40
40
|
end
|
41
41
|
|
@@ -50,7 +50,7 @@ class User < ActiveRecord::Base
|
|
50
50
|
has_many :products
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
FactoryBot.define do
|
54
54
|
factory :user
|
55
55
|
end
|
56
56
|
|
@@ -68,7 +68,7 @@ class Comment < ActiveRecord::Base
|
|
68
68
|
belongs_to :product
|
69
69
|
end
|
70
70
|
|
71
|
-
|
71
|
+
FactoryBot.define do
|
72
72
|
factory :comment
|
73
73
|
end
|
74
74
|
|
@@ -156,7 +156,7 @@ class TestIndex
|
|
156
156
|
{
|
157
157
|
test: {
|
158
158
|
properties: {
|
159
|
-
test_field: { type: "
|
159
|
+
test_field: { type: "date" }
|
160
160
|
}
|
161
161
|
}
|
162
162
|
}
|
@@ -170,7 +170,7 @@ end
|
|
170
170
|
TestIndex.delete_index if TestIndex.index_exists?
|
171
171
|
|
172
172
|
class SearchFlip::TestCase < MiniTest::Test
|
173
|
-
include
|
173
|
+
include FactoryBot::Syntax::Methods
|
174
174
|
|
175
175
|
def self.should_delegate_method(method, to:, subject:, as: method)
|
176
176
|
define_method :"test_delegate_#{method}_to_#{to}" do
|
@@ -240,4 +240,3 @@ class SearchFlip::TestCase < MiniTest::Test
|
|
240
240
|
Product.delete_all
|
241
241
|
end
|
242
242
|
end
|
243
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_flip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Vetter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: factory_bot
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -187,11 +187,11 @@ extra_rdoc_files: []
|
|
187
187
|
files:
|
188
188
|
- ".gitignore"
|
189
189
|
- ".travis.yml"
|
190
|
+
- CHANGELOG.md
|
190
191
|
- Gemfile
|
191
192
|
- LICENSE.txt
|
192
193
|
- README.md
|
193
194
|
- Rakefile
|
194
|
-
- irb.rb
|
195
195
|
- lib/search_flip.rb
|
196
196
|
- lib/search_flip/aggregatable.rb
|
197
197
|
- lib/search_flip/aggregation.rb
|