search_flip 4.0.0.beta1 → 4.0.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +2 -1
- data/.rubocop.yml +12 -4
- data/CHANGELOG.md +11 -0
- data/README.md +35 -31
- data/lib/search_flip/bulk.rb +1 -1
- data/lib/search_flip/config.rb +7 -1
- data/lib/search_flip/connection.rb +56 -14
- data/lib/search_flip/filterable.rb +16 -0
- data/lib/search_flip/index.rb +6 -4
- data/lib/search_flip/json.rb +3 -3
- data/lib/search_flip/result.rb +0 -4
- data/lib/search_flip/to_json.rb +1 -29
- data/lib/search_flip/version.rb +1 -1
- data/spec/search_flip/connection_spec.rb +29 -0
- data/spec/search_flip/criteria_spec.rb +12 -0
- data/spec/search_flip/index_spec.rb +17 -4
- data/spec/search_flip/json_spec.rb +16 -2
- data/spec/search_flip/null_instrumenter_spec.rb +2 -2
- metadata +3 -5
- data/spec/search_flip/to_json_spec.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb9f652fcf2d89715a4ac400906e2b4702bae052b721f671e31caaceca01fd37
|
4
|
+
data.tar.gz: c1bca6110c7e40a223462f183021763ce3dc89f538e5d492099cee751988292d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79c607032410d675a0663b13a6af21a64501a587ec1c07852e92e459b4034043121187016aabdab3672e0013fd1b86731b2c3f3a0d4484f08d39134328e3adc3
|
7
|
+
data.tar.gz: a06b1866d3322185692cab6ddd2c8a9dd88bb7eb46b955a732bf6e70fae174dbbd4f658b51cddc051c8d512f5f48619147bd32620fa24623393338360d9ed4e6
|
data/.github/workflows/test.yml
CHANGED
@@ -11,7 +11,7 @@ jobs:
|
|
11
11
|
- elasticsearch:5.4
|
12
12
|
- docker.elastic.co/elasticsearch/elasticsearch:6.7.0
|
13
13
|
- docker.elastic.co/elasticsearch/elasticsearch:7.0.0
|
14
|
-
- docker.elastic.co/elasticsearch/elasticsearch:7.
|
14
|
+
- docker.elastic.co/elasticsearch/elasticsearch:7.11.2
|
15
15
|
ruby:
|
16
16
|
- 2.5
|
17
17
|
- 2.6
|
@@ -28,6 +28,7 @@ jobs:
|
|
28
28
|
- uses: actions/setup-ruby@v1
|
29
29
|
with:
|
30
30
|
ruby-version: ${{ matrix.ruby }}
|
31
|
+
- run: gem install bundler
|
31
32
|
- run: bundle
|
32
33
|
- run: sleep 10
|
33
34
|
- run: bundle exec rspec
|
data/.rubocop.yml
CHANGED
@@ -1,16 +1,24 @@
|
|
1
1
|
AllCops:
|
2
2
|
NewCops: enable
|
3
|
-
TargetRubyVersion: 2.
|
4
|
-
|
5
|
-
Gemspec/RequiredRubyVersion:
|
6
|
-
Enabled: false
|
3
|
+
TargetRubyVersion: 2.5
|
4
|
+
SuggestExtensions: false
|
7
5
|
|
8
6
|
Style/CaseLikeIf:
|
9
7
|
Enabled: false
|
10
8
|
|
9
|
+
Layout/EmptyLineBetweenDefs:
|
10
|
+
EmptyLineBetweenClassDefs: false
|
11
|
+
|
12
|
+
Lint/EmptyBlock:
|
13
|
+
Exclude:
|
14
|
+
- spec/**/*.rb
|
15
|
+
|
11
16
|
Style/ExplicitBlockArgument:
|
12
17
|
Enabled: false
|
13
18
|
|
19
|
+
Gemspec/RequiredRubyVersion:
|
20
|
+
Enabled: false
|
21
|
+
|
14
22
|
Style/HashTransformValues:
|
15
23
|
Enabled: false
|
16
24
|
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,17 @@
|
|
8
8
|
* It no longer supports symbol based access like `result[:id]`
|
9
9
|
* It no longer supports question mark methods like `result.title?`
|
10
10
|
* It no longer supports method based assignment like `result.some_key = "value"`
|
11
|
+
* Added `SearchFlip::Connection#get_cluster_settings` and
|
12
|
+
`#update_cluster_settings`
|
13
|
+
|
14
|
+
## v3.2.1
|
15
|
+
|
16
|
+
* Fix `refresh` having a empty body breaking in elasticsearch 7.11
|
17
|
+
|
18
|
+
## v3.2.0
|
19
|
+
|
20
|
+
* Fix `index_scope` not being passed in `each_record` without block
|
21
|
+
* Added `SearchFlip::Criteria#match_none`
|
11
22
|
|
12
23
|
## v3.1.2
|
13
24
|
|
data/README.md
CHANGED
@@ -418,6 +418,14 @@ Simply matches all documents:
|
|
418
418
|
CommentIndex.match_all
|
419
419
|
```
|
420
420
|
|
421
|
+
* `match_none`
|
422
|
+
|
423
|
+
Simply matches none documents at all:
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
CommentIndex.match_none
|
427
|
+
```
|
428
|
+
|
421
429
|
* `all`
|
422
430
|
|
423
431
|
Simply returns the criteria as is or an empty criteria when called on the index
|
@@ -874,57 +882,53 @@ Thus, if your ORM supports `.find_each`, `#id` and `#where` you are already
|
|
874
882
|
good to go. Otherwise, simply add your custom implementation of those methods
|
875
883
|
that work with whatever ORM you use.
|
876
884
|
|
877
|
-
##
|
885
|
+
## JSON
|
878
886
|
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
However, `JSON.generate` in ruby by default outputs something like:
|
887
|
+
SearchFlip is using the [Oj gem](https://github.com/ohler55/oj) to generate
|
888
|
+
and parse JSON. More concretely, SearchFlip is using:
|
883
889
|
|
884
890
|
```ruby
|
885
|
-
|
886
|
-
|
891
|
+
Oj.dump({ key: "value" }, mode: :custom, use_to_json: true, time_format: :xmlschema, bigdecimal_as_decimal: false)
|
892
|
+
Oj.load('{"key":"value"}', mode: :custom, use_to_json: true, time_format: :xmlschema, bigdecimal_as_decimal: false)
|
887
893
|
```
|
888
894
|
|
889
|
-
|
890
|
-
|
891
|
-
However,
|
892
|
-
|
895
|
+
The `use_to_json` option is used for maximum compatibility, most importantly
|
896
|
+
when using rails `ActiveSupport::TimeWithZone` timestamps, which `oj` can not
|
897
|
+
serialize natively. However, `use_to_json` adds performance overhead. You can
|
898
|
+
change the json options via:
|
893
899
|
|
894
900
|
```ruby
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
901
|
+
SearchFlip::Config[:json_options] = {
|
902
|
+
mode: :custom,
|
903
|
+
use_to_json: false,
|
904
|
+
time_format: :xmlschema,
|
905
|
+
bigdecimal_as_decimal: false
|
906
|
+
}
|
900
907
|
```
|
901
908
|
|
902
|
-
|
903
|
-
JSON. More concretely, SearchFlip is using:
|
909
|
+
However, you then have to convert timestamps manually for indexation via e.g.:
|
904
910
|
|
905
911
|
```ruby
|
906
|
-
|
907
|
-
|
912
|
+
class MyIndex
|
913
|
+
# ...
|
908
914
|
|
909
|
-
|
915
|
+
def self.serialize(model)
|
916
|
+
{
|
917
|
+
# ...
|
910
918
|
|
911
|
-
|
912
|
-
|
913
|
-
|
919
|
+
created_at: model.created_at.to_time
|
920
|
+
}
|
921
|
+
end
|
922
|
+
end
|
914
923
|
```
|
915
924
|
|
916
|
-
|
917
|
-
`Date` and `DateTime` to get proper serialization. You can either add them on
|
918
|
-
your own, via other libraries or by simply using:
|
919
|
-
|
920
|
-
```ruby
|
921
|
-
require "search_flip/to_json"
|
922
|
-
```
|
925
|
+
Please check out the oj docs for more details.
|
923
926
|
|
924
927
|
## Feature Support
|
925
928
|
|
926
929
|
* for Elasticsearch 2.x, the delete-by-query plugin is required to delete
|
927
930
|
records via queries
|
931
|
+
* `#match_none` is only available with Elasticsearch >= 5
|
928
932
|
* `#track_total_hits` is only available with Elasticsearch >= 7
|
929
933
|
|
930
934
|
## Keeping your Models and Indices in Sync
|
data/lib/search_flip/bulk.rb
CHANGED
data/lib/search_flip/config.rb
CHANGED
@@ -5,6 +5,12 @@ module SearchFlip
|
|
5
5
|
bulk_limit: 1_000,
|
6
6
|
bulk_max_mb: 100,
|
7
7
|
auto_refresh: false,
|
8
|
-
instrumenter: NullInstrumenter.new
|
8
|
+
instrumenter: NullInstrumenter.new,
|
9
|
+
json_options: {
|
10
|
+
mode: :custom,
|
11
|
+
use_to_json: true,
|
12
|
+
time_format: :xmlschema,
|
13
|
+
bigdecimal_as_decimal: false
|
14
|
+
}
|
9
15
|
}
|
10
16
|
end
|
@@ -19,6 +19,35 @@ module SearchFlip
|
|
19
19
|
@version_mutex = Mutex.new
|
20
20
|
end
|
21
21
|
|
22
|
+
# Queries the cluster settings from Elasticsearch
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# connection.get_cluster_settings
|
26
|
+
# # => { "persistent" => { ... }, ... }
|
27
|
+
#
|
28
|
+
# @return [Hash] The cluster settings
|
29
|
+
|
30
|
+
def get_cluster_settings
|
31
|
+
response = http_client.get("#{base_url}/_cluster/settings")
|
32
|
+
|
33
|
+
SearchFlip::JSON.parse(response.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Updates the cluster settings according to the specified payload
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# connection.update_cluster_settings(persistent: { action: { auto_create_index: false } })
|
40
|
+
#
|
41
|
+
# @param cluster_settings [Hash] The cluster settings
|
42
|
+
#
|
43
|
+
# @return [Boolean] Returns true or raises SearchFlip::ResponseError
|
44
|
+
|
45
|
+
def update_cluster_settings(cluster_settings)
|
46
|
+
http_client.put("#{base_url}/_cluster/settings", json: cluster_settings)
|
47
|
+
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
22
51
|
# Queries and returns the Elasticsearch version used.
|
23
52
|
#
|
24
53
|
# @example
|
@@ -28,7 +57,11 @@ module SearchFlip
|
|
28
57
|
|
29
58
|
def version
|
30
59
|
@version_mutex.synchronize do
|
31
|
-
@version ||=
|
60
|
+
@version ||= begin
|
61
|
+
response = http_client.headers(accept: "application/json").get("#{base_url}/")
|
62
|
+
|
63
|
+
SearchFlip::JSON.parse(response.to_s)["version"]["number"]
|
64
|
+
end
|
32
65
|
end
|
33
66
|
end
|
34
67
|
|
@@ -40,7 +73,9 @@ module SearchFlip
|
|
40
73
|
# @return [Hash] The raw response
|
41
74
|
|
42
75
|
def cluster_health
|
43
|
-
http_client.headers(accept: "application/json").get("#{base_url}/_cluster/health")
|
76
|
+
response = http_client.headers(accept: "application/json").get("#{base_url}/_cluster/health")
|
77
|
+
|
78
|
+
SearchFlip::JSON.parse(response.to_s)
|
44
79
|
end
|
45
80
|
|
46
81
|
# Uses the Elasticsearch Multi Search API to execute multiple search requests
|
@@ -90,10 +125,11 @@ module SearchFlip
|
|
90
125
|
# @return [Hash] The raw response
|
91
126
|
|
92
127
|
def update_aliases(payload)
|
93
|
-
http_client
|
128
|
+
response = http_client
|
94
129
|
.headers(accept: "application/json", content_type: "application/json")
|
95
130
|
.post("#{base_url}/_aliases", body: SearchFlip::JSON.generate(payload))
|
96
|
-
|
131
|
+
|
132
|
+
SearchFlip::JSON.parse(response.to_s)
|
97
133
|
end
|
98
134
|
|
99
135
|
# Sends an analyze request to Elasticsearch. Raises
|
@@ -105,10 +141,11 @@ module SearchFlip
|
|
105
141
|
# @return [Hash] The raw response
|
106
142
|
|
107
143
|
def analyze(request, params = {})
|
108
|
-
http_client
|
144
|
+
response = http_client
|
109
145
|
.headers(accept: "application/json")
|
110
146
|
.post("#{base_url}/_analyze", json: request, params: params)
|
111
|
-
|
147
|
+
|
148
|
+
SearchFlip::JSON.parse(response.to_s)
|
112
149
|
end
|
113
150
|
|
114
151
|
# Fetches information about the specified index aliases. Raises
|
@@ -124,10 +161,11 @@ module SearchFlip
|
|
124
161
|
# @return [Hash] The raw response
|
125
162
|
|
126
163
|
def get_aliases(index_name: "*", alias_name: "*")
|
127
|
-
http_client
|
164
|
+
response = http_client
|
128
165
|
.headers(accept: "application/json", content_type: "application/json")
|
129
166
|
.get("#{base_url}/#{index_name}/_alias/#{alias_name}")
|
130
|
-
|
167
|
+
|
168
|
+
SearchFlip::JSON.parse(response.to_s)
|
131
169
|
end
|
132
170
|
|
133
171
|
# Returns whether or not the associated Elasticsearch alias already
|
@@ -159,10 +197,11 @@ module SearchFlip
|
|
159
197
|
# @return [Array] The raw response
|
160
198
|
|
161
199
|
def get_indices(name = "*", params: {})
|
162
|
-
http_client
|
200
|
+
response = http_client
|
163
201
|
.headers(accept: "application/json", content_type: "application/json")
|
164
202
|
.get("#{base_url}/_cat/indices/#{name}", params: params)
|
165
|
-
|
203
|
+
|
204
|
+
SearchFlip::JSON.parse(response.to_s)
|
166
205
|
end
|
167
206
|
|
168
207
|
alias_method :cat_indices, :get_indices
|
@@ -259,10 +298,11 @@ module SearchFlip
|
|
259
298
|
# @return [Hash] The index settings
|
260
299
|
|
261
300
|
def get_index_settings(index_name)
|
262
|
-
http_client
|
301
|
+
response = http_client
|
263
302
|
.headers(accept: "application/json")
|
264
303
|
.get("#{index_url(index_name)}/_settings")
|
265
|
-
|
304
|
+
|
305
|
+
SearchFlip::JSON.parse(response.to_s)
|
266
306
|
end
|
267
307
|
|
268
308
|
# Sends a refresh request to Elasticsearch. Raises
|
@@ -272,7 +312,7 @@ module SearchFlip
|
|
272
312
|
# @return [Boolean] Returns true or raises SearchFlip::ResponseError
|
273
313
|
|
274
314
|
def refresh(index_names = nil)
|
275
|
-
http_client.post("#{index_names ? index_url(Array(index_names).join(",")) : base_url}/_refresh"
|
315
|
+
http_client.post("#{index_names ? index_url(Array(index_names).join(",")) : base_url}/_refresh")
|
276
316
|
|
277
317
|
true
|
278
318
|
end
|
@@ -310,7 +350,9 @@ module SearchFlip
|
|
310
350
|
url = type_name ? type_url(index_name, type_name) : index_url(index_name)
|
311
351
|
params = type_name && version.to_f >= 6.7 ? { include_type_name: true } : {}
|
312
352
|
|
313
|
-
http_client.headers(accept: "application/json").get("#{url}/_mapping", params: params)
|
353
|
+
response = http_client.headers(accept: "application/json").get("#{url}/_mapping", params: params)
|
354
|
+
|
355
|
+
SearchFlip::JSON.parse(response.to_s)
|
314
356
|
end
|
315
357
|
|
316
358
|
# Deletes the specified index from Elasticsearch. Raises
|
@@ -235,6 +235,22 @@ module SearchFlip
|
|
235
235
|
filter(match_all: options)
|
236
236
|
end
|
237
237
|
|
238
|
+
# Adds a match none filter to the criteria, which simply matches none
|
239
|
+
# documents at all. Check out the Elasticsearch docs for further details.
|
240
|
+
#
|
241
|
+
# @example Basic usage
|
242
|
+
# CommentIndex.match_none
|
243
|
+
#
|
244
|
+
# @example Filter chaining
|
245
|
+
# query = CommentIndex.search("...")
|
246
|
+
# query = query.match_none unless current_user.admin?
|
247
|
+
#
|
248
|
+
# @return [SearchFlip::Criteria] A newly created extended criteria
|
249
|
+
|
250
|
+
def match_none
|
251
|
+
filter(match_none: {})
|
252
|
+
end
|
253
|
+
|
238
254
|
# Adds an exists filter to the criteria, which selects all documents for
|
239
255
|
# which the specified field has a non-null value.
|
240
256
|
#
|
data/lib/search_flip/index.rb
CHANGED
@@ -153,7 +153,7 @@ module SearchFlip
|
|
153
153
|
# scope to be applied to the scope
|
154
154
|
|
155
155
|
def each_record(scope, index_scope: false)
|
156
|
-
return enum_for(:each_record, scope) unless block_given?
|
156
|
+
return enum_for(:each_record, scope, index_scope: index_scope) unless block_given?
|
157
157
|
|
158
158
|
if scope.respond_to?(:find_each)
|
159
159
|
(index_scope ? self.index_scope(scope) : scope).find_each do |record|
|
@@ -247,8 +247,8 @@ module SearchFlip
|
|
247
247
|
SearchFlip::Criteria.new(target: self)
|
248
248
|
end
|
249
249
|
|
250
|
-
def_delegators :criteria, :all, :profile, :where, :where_not, :filter, :range, :match_all, :
|
251
|
-
:exists_not, :post_where, :post_where_not, :post_range, :post_exists, :post_exists_not,
|
250
|
+
def_delegators :criteria, :all, :profile, :where, :where_not, :filter, :range, :match_all, :match_none,
|
251
|
+
:exists, :exists_not, :post_where, :post_where_not, :post_range, :post_exists, :post_exists_not,
|
252
252
|
:post_filter, :post_must, :post_must_not, :post_should, :aggregate, :scroll, :source,
|
253
253
|
:includes, :eager_load, :preload, :sort, :resort, :order, :reorder, :offset, :limit, :paginate,
|
254
254
|
:page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_results_in_batches,
|
@@ -487,7 +487,9 @@ module SearchFlip
|
|
487
487
|
# @return [Hash] The raw response
|
488
488
|
|
489
489
|
def analyze(request, params = {})
|
490
|
-
connection.http_client.headers(accept: "application/json").post("#{index_url}/_analyze", json: request, params: params)
|
490
|
+
response = connection.http_client.headers(accept: "application/json").post("#{index_url}/_analyze", json: request, params: params)
|
491
|
+
|
492
|
+
SearchFlip::JSON.parse(response.to_s)
|
491
493
|
end
|
492
494
|
|
493
495
|
# Sends a index refresh request to Elasticsearch. Raises
|
data/lib/search_flip/json.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module SearchFlip
|
2
2
|
class JSON
|
3
3
|
def self.generate(obj)
|
4
|
-
Oj.dump(obj,
|
4
|
+
Oj.dump(obj, SearchFlip::Config[:json_options])
|
5
5
|
end
|
6
6
|
|
7
|
-
def self.parse(
|
8
|
-
Oj.load(
|
7
|
+
def self.parse(json)
|
8
|
+
Oj.load(json, SearchFlip::Config[:json_options])
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/search_flip/result.rb
CHANGED
@@ -34,14 +34,10 @@ module SearchFlip
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
# rubocop:disable Lint/MissingSuper
|
38
|
-
|
39
37
|
def method_missing(name, *args, &block)
|
40
38
|
self[name.to_s]
|
41
39
|
end
|
42
40
|
|
43
|
-
# rubocop:enable Lint/MissingSuper
|
44
|
-
|
45
41
|
def respond_to_missing?(name, include_private = false)
|
46
42
|
key?(name.to_s) || super
|
47
43
|
end
|
data/lib/search_flip/to_json.rb
CHANGED
@@ -1,29 +1 @@
|
|
1
|
-
|
2
|
-
require "date"
|
3
|
-
require "json"
|
4
|
-
|
5
|
-
class Time
|
6
|
-
def to_json(*args)
|
7
|
-
iso8601(6).to_json
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class Date
|
12
|
-
def to_json(*args)
|
13
|
-
iso8601.to_json
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class DateTime
|
18
|
-
def to_json(*args)
|
19
|
-
iso8601(6).to_json
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
if defined?(ActiveSupport)
|
24
|
-
class ActiveSupport::TimeWithZone
|
25
|
-
def to_json(*args)
|
26
|
-
iso8601(6).to_json
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
1
|
+
warn "[DEPRECATION] Using search_flip/to_json is not neccessary anymore"
|
data/lib/search_flip/version.rb
CHANGED
@@ -19,6 +19,35 @@ RSpec.describe SearchFlip::Connection do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
describe "#get_cluster_settings" do
|
23
|
+
it "returns the cluster settings" do
|
24
|
+
expect(SearchFlip::Connection.new.get_cluster_settings).to be_kind_of(Hash)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#update_cluster_settings" do
|
29
|
+
let(:connection) { SearchFlip::Connection.new }
|
30
|
+
|
31
|
+
after do
|
32
|
+
connection.update_cluster_settings(persistent: { action: { auto_create_index: false } }) if connection.version.to_i > 2
|
33
|
+
end
|
34
|
+
|
35
|
+
it "updates the cluster settings" do
|
36
|
+
if connection.version.to_i > 2
|
37
|
+
connection.update_cluster_settings(persistent: { action: { auto_create_index: false } })
|
38
|
+
connection.update_cluster_settings(persistent: { action: { auto_create_index: true } })
|
39
|
+
|
40
|
+
expect(connection.get_cluster_settings["persistent"]["action"]["auto_create_index"]).to eq("true")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns true" do
|
45
|
+
if connection.version.to_i > 2
|
46
|
+
expect(connection.update_cluster_settings(persistent: { action: { auto_create_index: false } })).to eq(true)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
22
51
|
describe "#msearch" do
|
23
52
|
it "sends multiple queries and returns all responses" do
|
24
53
|
ProductIndex.import create(:product)
|
@@ -416,6 +416,18 @@ RSpec.describe SearchFlip::Criteria do
|
|
416
416
|
end
|
417
417
|
end
|
418
418
|
|
419
|
+
describe "#match_none" do
|
420
|
+
it "does not match any documents" do
|
421
|
+
if ProductIndex.connection.version.to_i >= 5
|
422
|
+
ProductIndex.import create(:product)
|
423
|
+
|
424
|
+
query = ProductIndex.match_none
|
425
|
+
|
426
|
+
expect(query.records).to eq([])
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
419
431
|
describe "#exists" do
|
420
432
|
it "sets up the constraints correctly and is chainable" do
|
421
433
|
product1 = create(:product, title: "title1", description: "description1")
|
@@ -5,8 +5,8 @@ RSpec.describe SearchFlip::Index do
|
|
5
5
|
subject { ProductIndex }
|
6
6
|
|
7
7
|
methods = [
|
8
|
-
:all, :profile, :where, :where_not, :filter, :range, :match_all, :
|
9
|
-
:exists_not, :post_where, :post_where_not, :post_filter, :post_must,
|
8
|
+
:all, :profile, :where, :where_not, :filter, :range, :match_all, :match_none,
|
9
|
+
:exists, :exists_not, :post_where, :post_where_not, :post_filter, :post_must,
|
10
10
|
:post_must_not, :post_should, :post_range, :post_exists, :post_exists_not,
|
11
11
|
:aggregate, :scroll, :source, :includes, :eager_load, :preload, :sort, :resort,
|
12
12
|
:order, :reorder, :offset, :limit, :paginate, :page, :per, :search,
|
@@ -211,12 +211,18 @@ RSpec.describe SearchFlip::Index do
|
|
211
211
|
mapping = { properties: { id: { type: "long" } } }
|
212
212
|
|
213
213
|
allow(TestIndex).to receive(:mapping).and_return(mapping)
|
214
|
-
allow(TestIndex.connection).to receive(:update_mapping)
|
214
|
+
allow(TestIndex.connection).to receive(:update_mapping)
|
215
215
|
|
216
216
|
TestIndex.update_mapping
|
217
217
|
|
218
218
|
expect(TestIndex.connection).to have_received(:update_mapping).with("test", { "test" => mapping }, type_name: "test")
|
219
219
|
end
|
220
|
+
|
221
|
+
it "updates the mapping" do
|
222
|
+
TestIndex.create_index
|
223
|
+
|
224
|
+
expect(TestIndex.update_mapping).to eq(true)
|
225
|
+
end
|
220
226
|
end
|
221
227
|
end
|
222
228
|
|
@@ -258,12 +264,19 @@ RSpec.describe SearchFlip::Index do
|
|
258
264
|
TestIndex.create_index
|
259
265
|
TestIndex.update_mapping
|
260
266
|
|
261
|
-
allow(TestIndex.connection).to receive(:get_mapping)
|
267
|
+
allow(TestIndex.connection).to receive(:get_mapping)
|
262
268
|
|
263
269
|
TestIndex.get_mapping
|
264
270
|
|
265
271
|
expect(TestIndex.connection).to have_received(:get_mapping).with("test", type_name: "test")
|
266
272
|
end
|
273
|
+
|
274
|
+
it "returns the mapping" do
|
275
|
+
TestIndex.create_index
|
276
|
+
TestIndex.update_mapping
|
277
|
+
|
278
|
+
expect(TestIndex.get_mapping).to be_present
|
279
|
+
end
|
267
280
|
end
|
268
281
|
end
|
269
282
|
|
@@ -2,6 +2,16 @@ require File.expand_path("../spec_helper", __dir__)
|
|
2
2
|
|
3
3
|
RSpec.describe SearchFlip::JSON do
|
4
4
|
describe ".generate" do
|
5
|
+
it "encodes timestamps correctly" do
|
6
|
+
Timecop.freeze "2020-06-01 12:00:00 UTC" do
|
7
|
+
expect(described_class.generate(timestamp: Time.now.utc)).to eq('{"timestamp":"2020-06-01T12:00:00.000Z"}')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "encodes bigdecimals as string" do
|
12
|
+
expect(described_class.generate(value: BigDecimal(1))).to eq('{"value":"1.0"}')
|
13
|
+
end
|
14
|
+
|
5
15
|
it "delegates to Oj" do
|
6
16
|
allow(Oj).to receive(:dump)
|
7
17
|
|
@@ -9,7 +19,7 @@ RSpec.describe SearchFlip::JSON do
|
|
9
19
|
|
10
20
|
described_class.generate(payload)
|
11
21
|
|
12
|
-
expect(Oj).to have_received(:dump).with(payload, mode: :custom, use_to_json: true)
|
22
|
+
expect(Oj).to have_received(:dump).with(payload, mode: :custom, use_to_json: true, time_format: :xmlschema, bigdecimal_as_decimal: false)
|
13
23
|
end
|
14
24
|
|
15
25
|
it "generates json" do
|
@@ -18,6 +28,10 @@ RSpec.describe SearchFlip::JSON do
|
|
18
28
|
end
|
19
29
|
|
20
30
|
describe ".parse" do
|
31
|
+
it "returns the parsed json payload" do
|
32
|
+
expect(described_class.parse('{"key":"value"}')).to eq("key" => "value")
|
33
|
+
end
|
34
|
+
|
21
35
|
it "delegates to Oj" do
|
22
36
|
allow(Oj).to receive(:load)
|
23
37
|
|
@@ -25,7 +39,7 @@ RSpec.describe SearchFlip::JSON do
|
|
25
39
|
|
26
40
|
described_class.parse(payload)
|
27
41
|
|
28
|
-
expect(Oj).to have_received(:load).with(payload, mode: :
|
42
|
+
expect(Oj).to have_received(:load).with(payload, mode: :custom, use_to_json: true, time_format: :xmlschema, bigdecimal_as_decimal: false)
|
29
43
|
end
|
30
44
|
end
|
31
45
|
end
|
@@ -7,7 +7,7 @@ RSpec.describe SearchFlip::NullInstrumenter do
|
|
7
7
|
it "calls start" do
|
8
8
|
allow(subject).to receive(:start)
|
9
9
|
|
10
|
-
subject.instrument("name", { key: "value" }) {}
|
10
|
+
subject.instrument("name", { key: "value" }) { true }
|
11
11
|
|
12
12
|
expect(subject).to have_received(:start)
|
13
13
|
end
|
@@ -15,7 +15,7 @@ RSpec.describe SearchFlip::NullInstrumenter do
|
|
15
15
|
it "calls finish" do
|
16
16
|
allow(subject).to receive(:finish)
|
17
17
|
|
18
|
-
subject.instrument("name", { key: "value" }) {}
|
18
|
+
subject.instrument("name", { key: "value" }) { true }
|
19
19
|
|
20
20
|
expect(subject).to have_received(:finish)
|
21
21
|
end
|
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: 4.0.0.
|
4
|
+
version: 4.0.0.beta6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Vetter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -250,7 +250,6 @@ files:
|
|
250
250
|
- spec/search_flip/null_instrumenter_spec.rb
|
251
251
|
- spec/search_flip/response_spec.rb
|
252
252
|
- spec/search_flip/result_spec.rb
|
253
|
-
- spec/search_flip/to_json_spec.rb
|
254
253
|
- spec/spec_helper.rb
|
255
254
|
homepage: https://github.com/mrkamel/search_flip
|
256
255
|
licenses:
|
@@ -274,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
274
273
|
- !ruby/object:Gem::Version
|
275
274
|
version: 1.3.1
|
276
275
|
requirements: []
|
277
|
-
rubygems_version: 3.
|
276
|
+
rubygems_version: 3.2.3
|
278
277
|
signing_key:
|
279
278
|
specification_version: 4
|
280
279
|
summary: Full-Featured Elasticsearch Ruby Client with a Chainable DSL
|
@@ -292,5 +291,4 @@ test_files:
|
|
292
291
|
- spec/search_flip/null_instrumenter_spec.rb
|
293
292
|
- spec/search_flip/response_spec.rb
|
294
293
|
- spec/search_flip/result_spec.rb
|
295
|
-
- spec/search_flip/to_json_spec.rb
|
296
294
|
- spec/spec_helper.rb
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require File.expand_path("../spec_helper", __dir__)
|
2
|
-
require "search_flip/to_json"
|
3
|
-
|
4
|
-
RSpec.describe "to_json" do
|
5
|
-
it "uses the correct format for Time" do
|
6
|
-
Timecop.freeze Time.parse("2018-01-01 12:00:00 UTC") do
|
7
|
-
expect(Time.now.utc.to_json).to eq("\"2018-01-01T12:00:00.000000Z\"")
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
it "uses the correct format for Date" do
|
12
|
-
Timecop.freeze Time.parse("2018-01-01 12:00:00 UTC") do
|
13
|
-
expect(Date.today.to_json).to eq("\"2018-01-01\"")
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "uses the correct format for DateTime" do
|
18
|
-
Timecop.freeze Time.parse("2018-01-01 12:00:00 UTC") do
|
19
|
-
expect(Time.now.utc.to_json).to eq("\"2018-01-01T12:00:00.000000Z\"")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
it "uses the correct format for TimeWithZone" do
|
24
|
-
Timecop.freeze Time.parse("2018-01-01 12:00:00 UTC") do
|
25
|
-
expect(Time.find_zone("UTC").now.to_json).to eq("\"2018-01-01T12:00:00.000000Z\"")
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|