elastify 0.2.2 → 0.2.3
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/lib/elastify/active_record_extensions.rb +5 -4
- data/lib/elastify/configurators/model.rb +5 -1
- data/lib/elastify/helpers/elastic_search/connector.rb +28 -19
- data/lib/elastify/helpers/elastic_search/document.rb +4 -4
- data/lib/elastify/helpers/query_builder.rb +106 -0
- data/lib/elastify/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9390c61d979851afb2b3ad0fbbdfc7f101ee60e7
|
4
|
+
data.tar.gz: f7cb608d84f1f8be941b3f31ede57a22f354e628
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fce9c0bd9ff7830fa362ade0403963580a5428c2bc6a964178fa01756c84b995112df8cc0adc99aee56378c02af9aaf335ea1add2188a2bb739492a1a531aeb
|
7
|
+
data.tar.gz: 752e3f93e04c8624eec5ef23f73af6fa2c06e1485e6de0988ca53bdd027bd3b3522cfa88c873153d826087998f44be28fbe00c3385c783937449c8ae53765561
|
data/.gitignore
CHANGED
@@ -22,14 +22,15 @@ module Elastify::ActiveRecordExtensions
|
|
22
22
|
self.elastify_options[:map] = config.opt_mapping if config.opt_mapping.present?
|
23
23
|
self.elastify_options[:decode] = config.opt_decode if config.opt_decode.present?
|
24
24
|
self.elastify_options[:encode] = config.opt_encode if config.opt_encode.present?
|
25
|
+
self.elastify_options[:scroll_timeout] = config.opt_scroll_timeout if config.opt_scroll_timeout.present?
|
25
26
|
end
|
26
27
|
|
27
|
-
def elastify_search(dsl: nil,
|
28
|
-
return Elastify::Helpers::ElasticSearch::Document.new(self.elastify_options).search(dsl,
|
28
|
+
def elastify_search(dsl: nil, scroll_timeout: nil)
|
29
|
+
return Elastify::Helpers::ElasticSearch::Document.new(self.elastify_options).search(dsl, scroll_timeout)
|
29
30
|
end
|
30
31
|
|
31
|
-
def elastify_scroll(scroll_id: nil,
|
32
|
-
return Elastify::Helpers::ElasticSearch::Document.new(self.elastify_options).scroll(scroll_id,
|
32
|
+
def elastify_scroll(scroll_id: nil, scroll_timeout: nil)
|
33
|
+
return Elastify::Helpers::ElasticSearch::Document.new(self.elastify_options).scroll(scroll_id, scroll_timeout)
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
@@ -2,7 +2,7 @@ module Elastify
|
|
2
2
|
module Configurators
|
3
3
|
class Model
|
4
4
|
|
5
|
-
attr_accessor :opt_index, :opt_type, :opt_mapping, :opt_encode, :opt_decode
|
5
|
+
attr_accessor :opt_index, :opt_type, :opt_mapping, :opt_encode, :opt_decode, :opt_scroll_timeout
|
6
6
|
|
7
7
|
def index(index)
|
8
8
|
@opt_index = index
|
@@ -23,6 +23,10 @@ module Elastify
|
|
23
23
|
def decode(&block)
|
24
24
|
@opt_decode = block if block_given?
|
25
25
|
end
|
26
|
+
|
27
|
+
def scroll_timeout(scroll_timeout)
|
28
|
+
@opt_scroll_timeout = scroll_timeout
|
29
|
+
end
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -2,6 +2,7 @@ module Elastify
|
|
2
2
|
module Helpers
|
3
3
|
module ElasticSearch
|
4
4
|
class Connector
|
5
|
+
|
5
6
|
def self.create(options, data)
|
6
7
|
if data.blank?
|
7
8
|
raise :elastify__create__required_data
|
@@ -10,9 +11,10 @@ module Elastify
|
|
10
11
|
raise :elastify__create__required_data_id
|
11
12
|
end
|
12
13
|
url = "#{options[:base_url]}/#{options[:index]}/#{options[:type]}/#{data[:id]}"
|
13
|
-
|
14
|
+
JSON.parse(RestClient.put(url, data.to_json, {}))
|
14
15
|
end
|
15
|
-
|
16
|
+
|
17
|
+
def self.update(options, data)
|
16
18
|
if data.blank?
|
17
19
|
raise :elastify__update__required_data
|
18
20
|
end
|
@@ -20,9 +22,10 @@ module Elastify
|
|
20
22
|
raise :elastify__update__required_data_id
|
21
23
|
end
|
22
24
|
url = "#{options[:base_url]}/#{options[:index]}/#{options[:type]}/#{data[:id]}"
|
23
|
-
|
25
|
+
JSON.parse(RestClient.put(url, data.to_json, {})).to_hash
|
24
26
|
end
|
25
|
-
|
27
|
+
|
28
|
+
def self.destroy(options, data)
|
26
29
|
if data.blank?
|
27
30
|
raise :elastify__delete__required_data
|
28
31
|
end
|
@@ -30,38 +33,44 @@ module Elastify
|
|
30
33
|
raise :elastify__delete__required_data_id
|
31
34
|
end
|
32
35
|
url = "#{options[:base_url]}/#{options[:index]}/#{options[:type]}/#{data[:id]}"
|
33
|
-
|
36
|
+
JSON.parse(RestClient.delete(url)).to_hash
|
34
37
|
end
|
35
|
-
|
38
|
+
|
39
|
+
def self.search(options, dsl, scroll_timeout)
|
36
40
|
if dsl.blank?
|
37
41
|
raise :elastify__search__required_dsl
|
38
42
|
end
|
39
43
|
url = "#{options[:base_url]}/#{options[:index]}/#{options[:type]}/_search"
|
40
|
-
|
41
|
-
|
42
|
-
|
44
|
+
scroll_timeout ||= options[:scroll_timeout]
|
45
|
+
url += "?scroll=#{scroll_timeout}" if scroll_timeout.present?
|
46
|
+
Elastify::Helpers::ElasticSearch::SearchResultCollection.new(RestClient.post(url, dsl.to_json, {}), options)
|
43
47
|
end
|
44
|
-
|
48
|
+
|
49
|
+
def self.scroll(options, scroll_id, scroll_timeout)
|
45
50
|
if scroll_id.blank?
|
46
51
|
raise :elastify__search__required_scroll_id
|
47
52
|
end
|
48
53
|
url = "#{options[:base_url]}/_search/scroll"
|
49
|
-
dsl = {
|
50
|
-
|
51
|
-
|
54
|
+
dsl = { scroll_id: scroll_id }
|
55
|
+
scroll_timeout ||= options[:scroll_timeout]
|
56
|
+
dsl[:scroll] = scroll_timeout if scroll_timeout.present?
|
57
|
+
Elastify::Helpers::ElasticSearch::SearchResultCollection.new(RestClient.post(url, dsl.to_json, {}), options)
|
52
58
|
end
|
53
|
-
|
59
|
+
|
60
|
+
def self.create_index(options)
|
54
61
|
url = "#{options[:base_url]}/#{options[:index]}"
|
55
|
-
|
62
|
+
JSON.parse(RestClient.put(url, {}.to_json, {})).to_hash
|
56
63
|
end
|
57
|
-
|
64
|
+
|
65
|
+
def self.destroy_index(options)
|
58
66
|
url = "#{options[:base_url]}/#{options[:index]}"
|
59
|
-
|
67
|
+
JSON.parse(RestClient.delete(url)).to_hash
|
60
68
|
end
|
61
|
-
|
69
|
+
|
70
|
+
def self.create_mapping(options)
|
62
71
|
url = "#{options[:base_url]}/#{options[:index]}/_mappings/#{options[:type]}"
|
63
72
|
puts options[:map]
|
64
|
-
|
73
|
+
JSON.parse(RestClient.put(url, options[:map].squish, {})).to_hash
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
@@ -15,11 +15,11 @@ module Elastify
|
|
15
15
|
def destroy(model)
|
16
16
|
Connector.destroy(@options, model)
|
17
17
|
end
|
18
|
-
def search(dsl,
|
19
|
-
Connector.search(@options, dsl,
|
18
|
+
def search(dsl, scroll_timeout = nil)
|
19
|
+
Connector.search(@options, dsl, scroll_timeout)
|
20
20
|
end
|
21
|
-
def scroll(scroll_id,
|
22
|
-
Connector.scroll(@options, scroll_id,
|
21
|
+
def scroll(scroll_id, scroll_timeout = nil)
|
22
|
+
Connector.scroll(@options, scroll_id, scroll_timeout)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Elastify
|
2
|
+
module Helpers
|
3
|
+
class QueryBuilder
|
4
|
+
|
5
|
+
attr_accessor :queries, :filters, :sort, :scroll_size, :scroll_timeout
|
6
|
+
|
7
|
+
def initialize(scroll_size: 15, scroll_timeout: '1m')
|
8
|
+
@queries = []
|
9
|
+
@filters = []
|
10
|
+
@sort = {}
|
11
|
+
@scroll_size = scroll_size
|
12
|
+
@scroll_timeout = scroll_timeout
|
13
|
+
end
|
14
|
+
|
15
|
+
def search_term(fields, term)
|
16
|
+
@queries << { term: term, fields: fields.instance_of?(Array) ? fields : [fields] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def filter(*args)
|
20
|
+
must_filter(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def must_filter(fields, field_rules)
|
24
|
+
@filters << { type: :must, field_rules: field_rules, fields: fields.instance_of?(Array) ? fields : [fields] }
|
25
|
+
end
|
26
|
+
|
27
|
+
def should_filter(fields, field_rules)
|
28
|
+
@filters << { type: :should, field_rules: field_rules, fields: fields.instance_of?(Array) ? fields : [fields] }
|
29
|
+
end
|
30
|
+
|
31
|
+
def sort(field, direction)
|
32
|
+
@sort[field] = { order: direction }
|
33
|
+
end
|
34
|
+
|
35
|
+
def scroll(scroll_size, scroll_timeout)
|
36
|
+
@scroll_size = scroll_size
|
37
|
+
@scroll_timeout = scroll_timeout
|
38
|
+
end
|
39
|
+
|
40
|
+
def scroll_size(size)
|
41
|
+
@scroll_size = size
|
42
|
+
end
|
43
|
+
|
44
|
+
def scroll_timeout(timeout)
|
45
|
+
@scroll_timeout = timeout
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_dsl
|
49
|
+
max_scroll_size = 100; @scroll_size ||= 15
|
50
|
+
@scroll_size = @scroll_size.to_i <= max_scroll_size ? @scroll_size : max_scroll_size
|
51
|
+
if @sort.blank?
|
52
|
+
@sort = @queries.blank? ? { id: { order: :desc } } : { _score: { order: :desc } }
|
53
|
+
end
|
54
|
+
dsl = { sort: @sort, size: @scroll_size, query: {} }
|
55
|
+
if @queries.blank? and @filters.blank?
|
56
|
+
dsl[:query][:match_all] = {}
|
57
|
+
return dsl
|
58
|
+
end
|
59
|
+
dsl[:query] = { bool: { must: [], must_not: [], should: [] } }
|
60
|
+
if @queries.present?
|
61
|
+
dsl[:query][:bool][:must] += @queries.map do |query|
|
62
|
+
{ multi_match: { query: "#{query[:term].sanitize}", fields: query[:fields], operator: :and } }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
if @filters.present?
|
66
|
+
@filters.select { |filter| filter[:type].equal?(:must) }.each do |filter|
|
67
|
+
filter[:fields].each do |field|
|
68
|
+
dsl[:query][:bool][:must] += map_has(field, filter[:field_rules][:has]) if filter[:field_rules][:has].present?
|
69
|
+
dsl[:query][:bool][:must] << map_in(field, filter[:field_rules][:in]) if filter[:field_rules][:in].present?
|
70
|
+
dsl[:query][:bool][:must_not] << map_in(field, filter[:field_rules][:not_in]) if filter[:field_rules][:not_in].present?
|
71
|
+
dsl[:query][:bool][:must] << map_range(field, filter[:field_rules][:range]) if filter[:field_rules][:range].present?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@filters.select { |filter| filter[:type].equal?(:should) }.each do |filter|
|
75
|
+
filter[:fields].each_with_index do |field, index|
|
76
|
+
dsl[:query][:bool][:should][index] ||= { bool: { must: [], must_not: [] } }
|
77
|
+
dsl[:query][:bool][:should][index][:bool][:must] += map_has(field, filter[:field_rules][:has]) if filter[:field_rules][:has].present?
|
78
|
+
dsl[:query][:bool][:should][index][:bool][:must] << map_in(field, filter[:field_rules][:in]) if filter[:field_rules][:in].present?
|
79
|
+
dsl[:query][:bool][:should][index][:bool][:must_not] << map_in(field, filter[:field_rules][:not_in]) if filter[:field_rules][:not_in].present?
|
80
|
+
dsl[:query][:bool][:should][index][:bool][:must] << map_range(field, filter[:field_rules][:range]) if filter[:field_rules][:range].present?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
dsl[:query][:bool][:minimum_number_should_match] = 1 if dsl[:query][:bool][:should].present?
|
84
|
+
end
|
85
|
+
return dsl
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def map_has(field, data)
|
90
|
+
data.map { |value| { term: { field.to_s => value } } }
|
91
|
+
end
|
92
|
+
|
93
|
+
def map_in(field, data)
|
94
|
+
{ terms: { field.to_s => data } }
|
95
|
+
end
|
96
|
+
|
97
|
+
def map_not_in(field, data)
|
98
|
+
{ terms: { field.to_s => data } }
|
99
|
+
end
|
100
|
+
|
101
|
+
def map_range(field, data)
|
102
|
+
{ range: { field.to_s => { gte: data.first, lte: data.last, format: 'yyyy-MM-dd\'T\'HH:mm:ssZ' } } }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/elastify/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno Bortolotti Ribeiro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -182,6 +182,7 @@ files:
|
|
182
182
|
- lib/elastify/helpers/elastic_search/document.rb
|
183
183
|
- lib/elastify/helpers/elastic_search/search_result.rb
|
184
184
|
- lib/elastify/helpers/elastic_search/search_result_collection.rb
|
185
|
+
- lib/elastify/helpers/query_builder.rb
|
185
186
|
- lib/elastify/version.rb
|
186
187
|
homepage: https://github.com/brunobortolotti/elastify.git
|
187
188
|
licenses:
|