search_flip 3.0.0.beta4 → 3.0.0.beta5
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 +4 -4
- data/CHANGELOG.md +1 -0
- data/README.md +25 -1
- data/lib/search_flip/aggregation.rb +2 -1
- data/lib/search_flip/config.rb +2 -1
- data/lib/search_flip/criteria.rb +72 -59
- data/lib/search_flip/null_instrumenter.rb +21 -0
- data/lib/search_flip/version.rb +1 -1
- data/lib/search_flip.rb +1 -0
- data/spec/search_flip/criteria_spec.rb +42 -0
- data/spec/search_flip/null_instrumenter_spec.rb +43 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fae82bf67967306afbb6bfb0f2f321b8993fa364710b24dc7b3860f2bb6ace0
|
4
|
+
data.tar.gz: a060faa2ea3b06233dc132b65df0e4c2bc18ab51ea5cfe92eadd96aaa7c8ddbf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15aa25cab455dfadead099deb59594580f9c09f71476818f28d483a7d7e8cb3decfd7c4126ecfaf438b92ed19ded8edfe01566d4cffcd1a03394608b66db9ebb
|
7
|
+
data.tar.gz: 3a57bc2cecc98641c32f33c688576c7c808482bde3e3f9901590c7241102ef8a01d22f1dd875bd56d60c32fc9d38d4f97fd95e2f54249ccb2699c1ddc35a1e06
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -274,7 +274,7 @@ CommentIndex.create(Comment.first, { bulk_max_mb: 100 }, routing: "routing_key")
|
|
274
274
|
CommentIndex.update(Comment.first, ...)
|
275
275
|
```
|
276
276
|
|
277
|
-
Checkout the
|
277
|
+
Checkout the Elasticsearch [Bulk API] docs for more info as well as
|
278
278
|
[SearchFlip::Bulk](http://www.rubydoc.info/github/mrkamel/search_flip/SearchFlip/Bulk)
|
279
279
|
for a complete list of available options to control the bulk indexing of
|
280
280
|
SearchFlip.
|
@@ -790,6 +790,30 @@ end
|
|
790
790
|
|
791
791
|
These options will be passed whenever records get indexed, deleted, etc.
|
792
792
|
|
793
|
+
## Instrumentation
|
794
|
+
|
795
|
+
SearchFlip supports instrumentation for request execution via
|
796
|
+
`ActiveSupport::Notifications` compatible instrumenters to e.g. allow global
|
797
|
+
performance tracing, etc.
|
798
|
+
|
799
|
+
To use instrumentation, configure the instrumenter:
|
800
|
+
|
801
|
+
```ruby
|
802
|
+
SearchFlip::Config[:instrumenter] = ActiveSupport::Notifications.notifier
|
803
|
+
```
|
804
|
+
|
805
|
+
Subsequently, you can subscribe to notifcations for `request.search_flip`:
|
806
|
+
|
807
|
+
```ruby
|
808
|
+
ActiveSupport::Notifications.subscribe("request.search_flip") do |name, start, finish, id, payload|
|
809
|
+
payload[:index] # the index class
|
810
|
+
payload[:request] # the request hash sent to Elasticsearch
|
811
|
+
payload[:response] # the SearchFlip::Response object or nil in case of errors
|
812
|
+
end
|
813
|
+
```
|
814
|
+
|
815
|
+
A notification will be send for every request that is sent to Elasticsearch.
|
816
|
+
|
793
817
|
## Non-ActiveRecord models
|
794
818
|
|
795
819
|
SearchFlip ships with built-in support for ActiveRecord models, but using
|
@@ -73,7 +73,8 @@ module SearchFlip
|
|
73
73
|
unsupported_methods = [
|
74
74
|
:profile_value, :failsafe_value, :terminate_after_value, :timeout_value, :scroll_args,
|
75
75
|
:suggest_values, :includes_values, :preload_values, :eager_load_values, :post_must_values,
|
76
|
-
:post_must_not_values, :post_filter_values, :preference_value, :search_type_value,
|
76
|
+
:post_must_not_values, :post_filter_values, :preference_value, :search_type_value,
|
77
|
+
:routing_value
|
77
78
|
]
|
78
79
|
|
79
80
|
unsupported_methods.each do |unsupported_method|
|
data/lib/search_flip/config.rb
CHANGED
data/lib/search_flip/criteria.rb
CHANGED
@@ -219,45 +219,47 @@ module SearchFlip
|
|
219
219
|
# @return [Hash] The generated request object
|
220
220
|
|
221
221
|
def request
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
222
|
+
@request ||= begin
|
223
|
+
res = {}
|
224
|
+
|
225
|
+
if must_values || must_not_values || filter_values
|
226
|
+
res[:query] = {
|
227
|
+
bool: {
|
228
|
+
must: must_values.to_a,
|
229
|
+
must_not: must_not_values.to_a,
|
230
|
+
filter: filter_values.to_a
|
231
|
+
}.reject { |_, value| value.empty? }
|
232
|
+
}
|
233
|
+
end
|
233
234
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
235
|
+
res.update(from: offset_value_with_default, size: limit_value_with_default)
|
236
|
+
|
237
|
+
res[:track_total_hits] = track_total_hits_value unless track_total_hits_value.nil?
|
238
|
+
res[:explain] = explain_value unless explain_value.nil?
|
239
|
+
res[:timeout] = timeout_value if timeout_value
|
240
|
+
res[:terminate_after] = terminate_after_value if terminate_after_value
|
241
|
+
res[:highlight] = highlight_values if highlight_values
|
242
|
+
res[:suggest] = suggest_values if suggest_values
|
243
|
+
res[:sort] = sort_values if sort_values
|
244
|
+
res[:aggregations] = aggregation_values if aggregation_values
|
245
|
+
|
246
|
+
if post_must_values || post_must_not_values || post_filter_values
|
247
|
+
res[:post_filter] = {
|
248
|
+
bool: {
|
249
|
+
must: post_must_values.to_a,
|
250
|
+
must_not: post_must_not_values.to_a,
|
251
|
+
filter: post_filter_values.to_a
|
252
|
+
}.reject { |_, value| value.empty? }
|
253
|
+
}
|
254
|
+
end
|
254
255
|
|
255
|
-
|
256
|
-
|
256
|
+
res[:_source] = source_value unless source_value.nil?
|
257
|
+
res[:profile] = true if profile_value
|
257
258
|
|
258
|
-
|
259
|
+
res.update(custom_value) if custom_value
|
259
260
|
|
260
|
-
|
261
|
+
res
|
262
|
+
end
|
261
263
|
end
|
262
264
|
|
263
265
|
# Adds a suggestion section with the given name to the request.
|
@@ -520,30 +522,13 @@ module SearchFlip
|
|
520
522
|
|
521
523
|
def execute
|
522
524
|
@response ||= begin
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
json: { scroll: scroll_args[:timeout], scroll_id: scroll_args[:id] }
|
531
|
-
)
|
532
|
-
elsif scroll_args
|
533
|
-
http_request.post(
|
534
|
-
"#{target.type_url}/_search",
|
535
|
-
params: request_params.merge(scroll: scroll_args[:timeout]),
|
536
|
-
json: request
|
537
|
-
)
|
538
|
-
else
|
539
|
-
http_request.post("#{target.type_url}/_search", params: request_params, json: request)
|
540
|
-
end
|
541
|
-
|
542
|
-
SearchFlip::Response.new(self, http_response.parse)
|
543
|
-
rescue SearchFlip::ConnectionError, SearchFlip::ResponseError => e
|
544
|
-
raise e unless failsafe_value
|
545
|
-
|
546
|
-
SearchFlip::Response.new(self, "took" => 0, "hits" => { "total" => 0, "hits" => [] })
|
525
|
+
Config[:instrumenter].instrument("request.search_flip", index: target, request: request) do |payload|
|
526
|
+
response = execute!
|
527
|
+
|
528
|
+
payload[:response] = response
|
529
|
+
|
530
|
+
response
|
531
|
+
end
|
547
532
|
end
|
548
533
|
end
|
549
534
|
|
@@ -585,6 +570,7 @@ module SearchFlip
|
|
585
570
|
|
586
571
|
def fresh
|
587
572
|
dup.tap do |criteria|
|
573
|
+
criteria.instance_variable_set(:@request, nil)
|
588
574
|
criteria.instance_variable_set(:@response, nil)
|
589
575
|
end
|
590
576
|
end
|
@@ -610,6 +596,33 @@ module SearchFlip
|
|
610
596
|
|
611
597
|
private
|
612
598
|
|
599
|
+
def execute!
|
600
|
+
http_request = connection.http_client.headers(accept: "application/json")
|
601
|
+
|
602
|
+
http_response =
|
603
|
+
if scroll_args && scroll_args[:id]
|
604
|
+
http_request.post(
|
605
|
+
"#{connection.base_url}/_search/scroll",
|
606
|
+
params: request_params,
|
607
|
+
json: { scroll: scroll_args[:timeout], scroll_id: scroll_args[:id] }
|
608
|
+
)
|
609
|
+
elsif scroll_args
|
610
|
+
http_request.post(
|
611
|
+
"#{target.type_url}/_search",
|
612
|
+
params: request_params.merge(scroll: scroll_args[:timeout]),
|
613
|
+
json: request
|
614
|
+
)
|
615
|
+
else
|
616
|
+
http_request.post("#{target.type_url}/_search", params: request_params, json: request)
|
617
|
+
end
|
618
|
+
|
619
|
+
SearchFlip::Response.new(self, http_response.parse)
|
620
|
+
rescue SearchFlip::ConnectionError, SearchFlip::ResponseError => e
|
621
|
+
raise e unless failsafe_value
|
622
|
+
|
623
|
+
SearchFlip::Response.new(self, "took" => 0, "hits" => { "total" => 0, "hits" => [] })
|
624
|
+
end
|
625
|
+
|
613
626
|
def yield_in_batches(options = {})
|
614
627
|
return enum_for(:yield_in_batches, options) unless block_given?
|
615
628
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SearchFlip
|
2
|
+
class NullInstrumenter
|
3
|
+
def instrument(name, payload = {})
|
4
|
+
start(name, payload)
|
5
|
+
|
6
|
+
begin
|
7
|
+
yield(payload) if block_given?
|
8
|
+
ensure
|
9
|
+
finish(name, payload)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def start(_name, _payload)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def finish(_name, _payload)
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/search_flip/version.rb
CHANGED
data/lib/search_flip.rb
CHANGED
@@ -1198,9 +1198,12 @@ RSpec.describe SearchFlip::Criteria do
|
|
1198
1198
|
|
1199
1199
|
query = ProductIndex.criteria.tap(&:records)
|
1200
1200
|
|
1201
|
+
expect(query.instance_variable_get(:@request)).not_to be_nil
|
1201
1202
|
expect(query.instance_variable_get(:@response)).not_to be_nil
|
1202
1203
|
|
1203
1204
|
expect(query.object_id).not_to eq(query.fresh.object_id)
|
1205
|
+
|
1206
|
+
expect(query.fresh.instance_variable_get(:@request)).to be_nil
|
1204
1207
|
expect(query.fresh.instance_variable_get(:@response)).to be_nil
|
1205
1208
|
end
|
1206
1209
|
end
|
@@ -1234,10 +1237,49 @@ RSpec.describe SearchFlip::Criteria do
|
|
1234
1237
|
end
|
1235
1238
|
end
|
1236
1239
|
|
1240
|
+
describe "#execute" do
|
1241
|
+
around do |example|
|
1242
|
+
default_instrumenter = SearchFlip::Config[:instrumenter]
|
1243
|
+
|
1244
|
+
SearchFlip::Config[:instrumenter] = ActiveSupport::Notifications.instrumenter
|
1245
|
+
|
1246
|
+
begin
|
1247
|
+
example.run
|
1248
|
+
ensure
|
1249
|
+
SearchFlip::Config[:instrumenter] = default_instrumenter
|
1250
|
+
end
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
let(:notifications) { [] }
|
1254
|
+
|
1255
|
+
let!(:subscriber) do
|
1256
|
+
ActiveSupport::Notifications.subscribe("request.search_flip") do |*args|
|
1257
|
+
notifications << args
|
1258
|
+
end
|
1259
|
+
end
|
1260
|
+
|
1261
|
+
after { ActiveSupport::Notifications.unsubscribe(subscriber) }
|
1262
|
+
|
1263
|
+
it "instruments the request" do
|
1264
|
+
ProductIndex.match_all.execute
|
1265
|
+
|
1266
|
+
expect(notifications).to be_present
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
it "passes the index, request and response" do
|
1270
|
+
ProductIndex.match_all.execute
|
1271
|
+
|
1272
|
+
expect(notifications.first[4][:index]).to eq(ProductIndex)
|
1273
|
+
expect(notifications.first[4][:request]).to be_present
|
1274
|
+
expect(notifications.first[4][:response]).to be_present
|
1275
|
+
end
|
1276
|
+
end
|
1277
|
+
|
1237
1278
|
describe "#track_total_hits" do
|
1238
1279
|
it "is added to the request" do
|
1239
1280
|
if ProductIndex.connection.version.to_i >= 7
|
1240
1281
|
query = ProductIndex.track_total_hits(false)
|
1282
|
+
|
1241
1283
|
expect(query.request[:track_total_hits]).to eq(false)
|
1242
1284
|
expect { query.execute }.not_to raise_error
|
1243
1285
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path("../spec_helper", __dir__)
|
2
|
+
|
3
|
+
RSpec.describe SearchFlip::NullInstrumenter do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
describe "#instrument" do
|
7
|
+
it "calls start" do
|
8
|
+
allow(subject).to receive(:start)
|
9
|
+
|
10
|
+
subject.instrument("name", { key: "value" }) {}
|
11
|
+
|
12
|
+
expect(subject).to have_received(:start)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "calls finish" do
|
16
|
+
allow(subject).to receive(:finish)
|
17
|
+
|
18
|
+
subject.instrument("name", { key: "value" }) {}
|
19
|
+
|
20
|
+
expect(subject).to have_received(:finish)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "yields and passes the payload" do
|
24
|
+
yielded_payload = nil
|
25
|
+
|
26
|
+
subject.instrument("name", { key: "value" }) { |payload| yielded_payload = payload }
|
27
|
+
|
28
|
+
expect(yielded_payload).to eq(key: "value")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#start" do
|
33
|
+
it "returns true" do
|
34
|
+
expect(subject.start("name", { key: "value" })).to eq(true)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#finish" do
|
39
|
+
it "returns true" do
|
40
|
+
expect(subject.finish("name", { key: "value" })).to eq(true)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
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: 3.0.0.
|
4
|
+
version: 3.0.0.beta5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Vetter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -212,6 +212,7 @@ files:
|
|
212
212
|
- lib/search_flip/index.rb
|
213
213
|
- lib/search_flip/json.rb
|
214
214
|
- lib/search_flip/model.rb
|
215
|
+
- lib/search_flip/null_instrumenter.rb
|
215
216
|
- lib/search_flip/paginatable.rb
|
216
217
|
- lib/search_flip/post_filterable.rb
|
217
218
|
- lib/search_flip/response.rb
|
@@ -229,6 +230,7 @@ files:
|
|
229
230
|
- spec/search_flip/http_client_spec.rb
|
230
231
|
- spec/search_flip/index_spec.rb
|
231
232
|
- spec/search_flip/model_spec.rb
|
233
|
+
- spec/search_flip/null_instrumenter_spec.rb
|
232
234
|
- spec/search_flip/response_spec.rb
|
233
235
|
- spec/search_flip/result_spec.rb
|
234
236
|
- spec/search_flip/to_json_spec.rb
|
@@ -268,6 +270,7 @@ test_files:
|
|
268
270
|
- spec/search_flip/http_client_spec.rb
|
269
271
|
- spec/search_flip/index_spec.rb
|
270
272
|
- spec/search_flip/model_spec.rb
|
273
|
+
- spec/search_flip/null_instrumenter_spec.rb
|
271
274
|
- spec/search_flip/response_spec.rb
|
272
275
|
- spec/search_flip/result_spec.rb
|
273
276
|
- spec/search_flip/to_json_spec.rb
|