elastic_record 5.4.0 → 5.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -3
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/elastic_record.gemspec +1 -1
- data/lib/elastic_record/callbacks.rb +1 -5
- data/lib/elastic_record/config.rb +6 -11
- data/lib/elastic_record/from_search_hit.rb +62 -0
- data/lib/elastic_record/index/analyze.rb +0 -10
- data/lib/elastic_record/index/documents.rb +16 -5
- data/lib/elastic_record/index/settings.rb +1 -5
- data/lib/elastic_record/index.rb +16 -2
- data/lib/elastic_record/model.rb +5 -0
- data/lib/elastic_record/percolator_model.rb +8 -9
- data/lib/elastic_record/relation/batches.rb +9 -3
- data/lib/elastic_record/relation/calculations.rb +14 -0
- data/lib/elastic_record/relation.rb +2 -1
- data/lib/elastic_record/search_hits.rb +1 -12
- data/lib/elastic_record.rb +1 -0
- data/test/dummy/app/models/project.rb +38 -3
- data/test/elastic_record/aggregation_response/single_value_aggregation_test.rb +9 -0
- data/test/elastic_record/config_test.rb +1 -1
- data/test/elastic_record/from_search_hits_test.rb +55 -0
- data/test/elastic_record/index/documents_test.rb +19 -1
- data/{lib → test}/elastic_record/index/mapping_type_test.rb +0 -0
- data/test/elastic_record/index/settings_test.rb +9 -9
- data/test/elastic_record/index_test.rb +6 -0
- data/test/elastic_record/model_test.rb +7 -0
- data/test/elastic_record/relation/batches_test.rb +8 -0
- data/test/elastic_record/relation/calculations_test.rb +11 -0
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea174acd40e5c2ec841c31085fea2a2994e0d05a705042d5ddf044e8c8962376
|
4
|
+
data.tar.gz: 1adb61c8170f1e966a7acb0c7c68ac95cc5f93181a81d6118f166de0cdf45a6a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 741a6d678b18f9c373e7bc6412e98ab7ec5b97241af2fde09c84fb5b5baebac69d5236a893886c88ed73c37d81f4e426d4182f5818659cb5f675e820494e5d06
|
7
|
+
data.tar.gz: 848de3cb5054a6997aa8022721bf7dff2c40740921a127611033ec87dcda6e862945697ef19414c775b7b8c970671e19f251d6812cd193ad3eb797c52c9e95b8
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -209,7 +209,7 @@ When one model inherits from another, ElasticRecord makes some assumptions about
|
|
209
209
|
* `alias_name` - Same as parent
|
210
210
|
* `mapping` - Same as parent
|
211
211
|
* `mapping_type` - Same as parent
|
212
|
-
* `settings`
|
212
|
+
* `settings` - Same as parent
|
213
213
|
|
214
214
|
These can all be overridden. For instance, it might be desirable for the child documents to be in a separate index.
|
215
215
|
|
data/Rakefile
CHANGED
data/elastic_record.gemspec
CHANGED
@@ -4,7 +4,7 @@ module ElasticRecord
|
|
4
4
|
return unless base.respond_to?(:after_save) && base.respond_to?(:after_destroy)
|
5
5
|
|
6
6
|
base.class_eval do
|
7
|
-
after_create :
|
7
|
+
after_create :index_to_elasticsearch
|
8
8
|
after_update :update_index_document, if: -> { respond_to?(:saved_changes?) ? saved_changes? : changed? }
|
9
9
|
after_destroy :delete_index_document
|
10
10
|
end
|
@@ -12,10 +12,6 @@ module ElasticRecord
|
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
|
-
def create_index_document
|
16
|
-
self.class.elastic_index.index_record self
|
17
|
-
end
|
18
|
-
|
19
15
|
def update_index_document
|
20
16
|
method = self.class.elastic_index.partial_updates ? :update_record : :index_record
|
21
17
|
|
@@ -2,17 +2,11 @@ require 'active_support/core_ext/class/attribute'
|
|
2
2
|
|
3
3
|
module ElasticRecord
|
4
4
|
class Config
|
5
|
-
class_attribute :connection_options
|
6
|
-
|
7
|
-
|
8
|
-
class_attribute :
|
9
|
-
|
10
|
-
|
11
|
-
class_attribute :model_names
|
12
|
-
self.model_names = []
|
13
|
-
|
14
|
-
class_attribute :scroll_keep_alive
|
15
|
-
self.scroll_keep_alive = '5m'
|
5
|
+
class_attribute :connection_options, default: {}
|
6
|
+
class_attribute :default_index_settings, default: {}
|
7
|
+
class_attribute :model_names, default: []
|
8
|
+
class_attribute :scroll_keep_alive, default: '2m'
|
9
|
+
class_attribute :index_suffix
|
16
10
|
|
17
11
|
class << self
|
18
12
|
def models
|
@@ -32,6 +26,7 @@ module ElasticRecord
|
|
32
26
|
|
33
27
|
def settings=(settings)
|
34
28
|
self.servers = settings['servers']
|
29
|
+
self.index_suffix = settings['index_suffix']
|
35
30
|
self.connection_options = settings
|
36
31
|
|
37
32
|
if settings['scroll_keep_alive'].present?
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ElasticRecord
|
2
|
+
module FromSearchHit
|
3
|
+
|
4
|
+
def from_search_hit(hit)
|
5
|
+
hit = hit['_source'].merge('id' => hit['_id'])
|
6
|
+
|
7
|
+
attrs = value_from_search_hit_object(hit)
|
8
|
+
|
9
|
+
if respond_to?(:instantiate)
|
10
|
+
instantiate(attrs)
|
11
|
+
else
|
12
|
+
self.new.tap do |record|
|
13
|
+
attrs.each do |k, v|
|
14
|
+
record.send("#{k}=", v) if record.respond_to?("#{k}=")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def value_from_search_hit_object(hit)
|
23
|
+
hit.each do |field, value|
|
24
|
+
next unless value
|
25
|
+
|
26
|
+
case value
|
27
|
+
when Hash
|
28
|
+
hit[field] = value_from_search_hit(value)
|
29
|
+
when Array # type: 'nested'
|
30
|
+
value.each do |element|
|
31
|
+
if element.is_a? Hash
|
32
|
+
value_from_search_hit_object(element)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
hit
|
39
|
+
end
|
40
|
+
|
41
|
+
def value_from_search_hit(value)
|
42
|
+
case value['gte'] # the gte lower bound is never nil
|
43
|
+
when String
|
44
|
+
value_for_date_range(value)
|
45
|
+
when Integer
|
46
|
+
value_for_range(value)
|
47
|
+
else # type: 'object'
|
48
|
+
value_from_search_hit_object(value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def value_for_range(value)
|
53
|
+
value['gte'] = -Float::INFINITY if value['gte'].nil?
|
54
|
+
value['lte'] = Float::INFINITY if value['lte'].nil?
|
55
|
+
value['gte']..value['lte']
|
56
|
+
end
|
57
|
+
|
58
|
+
def value_for_date_range(value)
|
59
|
+
Date.parse(value['gte'])..Date.parse(value['lte'])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,16 +1,6 @@
|
|
1
1
|
module ElasticRecord
|
2
2
|
class Index
|
3
3
|
module Analyze
|
4
|
-
attr_accessor :analysis
|
5
|
-
|
6
|
-
def analysis
|
7
|
-
@analysis ||= {}
|
8
|
-
end
|
9
|
-
|
10
|
-
def analysis=(custom_analysis)
|
11
|
-
analysis.deep_merge!(custom_analysis)
|
12
|
-
end
|
13
|
-
|
14
4
|
def analyze(params)
|
15
5
|
json = connection.json_get "/#{alias_name}/_analyze", params
|
16
6
|
json['tokens'].map { |token_hash| token_hash['token'] }
|
@@ -3,7 +3,7 @@ require 'active_support/core_ext/object/to_query'
|
|
3
3
|
module ElasticRecord
|
4
4
|
class Index
|
5
5
|
class ScrollEnumerator
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :keep_alive, :batch_size, :scroll_id
|
7
7
|
def initialize(elastic_index, search: nil, scroll_id: nil, keep_alive:, batch_size:)
|
8
8
|
@elastic_index = elastic_index
|
9
9
|
@search = search
|
@@ -16,6 +16,8 @@ module ElasticRecord
|
|
16
16
|
while (hits = request_more_hits.hits).any?
|
17
17
|
hits.each_slice(batch_size, &block)
|
18
18
|
end
|
19
|
+
|
20
|
+
@elastic_index.delete_scroll(scroll_id)
|
19
21
|
end
|
20
22
|
|
21
23
|
def request_more_ids
|
@@ -27,13 +29,18 @@ module ElasticRecord
|
|
27
29
|
end
|
28
30
|
|
29
31
|
def request_next_scroll
|
30
|
-
if scroll_id
|
31
|
-
response = initial_search_response
|
32
|
-
else
|
32
|
+
if scroll_id
|
33
33
|
response = @elastic_index.scroll(scroll_id, keep_alive)
|
34
|
+
|
35
|
+
if response['_scroll_id'] != scroll_id
|
36
|
+
@elastic_index.delete_scroll(scroll_id)
|
37
|
+
end
|
38
|
+
else
|
39
|
+
response = initial_search_response
|
34
40
|
end
|
35
41
|
|
36
|
-
@scroll_id =
|
42
|
+
@scroll_id = response['_scroll_id']
|
43
|
+
|
37
44
|
response
|
38
45
|
end
|
39
46
|
|
@@ -167,6 +174,10 @@ module ElasticRecord
|
|
167
174
|
end
|
168
175
|
end
|
169
176
|
|
177
|
+
def delete_scroll(scroll_id)
|
178
|
+
connection.json_delete('/_search/scroll', { scroll_id: scroll_id })
|
179
|
+
end
|
180
|
+
|
170
181
|
def bulk(options = {}, &block)
|
171
182
|
if current_bulk_batch
|
172
183
|
yield
|
@@ -6,11 +6,7 @@ module ElasticRecord
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def settings
|
9
|
-
@settings ||=
|
10
|
-
result = ElasticRecord::Config.default_index_settings.deep_dup
|
11
|
-
result['analysis'] = analysis if analysis.any?
|
12
|
-
result
|
13
|
-
end
|
9
|
+
@settings ||= ElasticRecord::Config.default_index_settings.deep_dup
|
14
10
|
end
|
15
11
|
|
16
12
|
def update_settings(index_name = alias_name, settings: self.settings)
|
data/lib/elastic_record/index.rb
CHANGED
@@ -50,11 +50,11 @@ module ElasticRecord
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def alias_name=(name)
|
53
|
-
@alias_name = name
|
53
|
+
@alias_name = add_suffix(name)
|
54
54
|
end
|
55
55
|
|
56
56
|
def alias_name
|
57
|
-
@alias_name ||= model.base_class.name.demodulize.underscore.pluralize
|
57
|
+
@alias_name ||= add_suffix(model.base_class.name.demodulize.underscore.pluralize)
|
58
58
|
end
|
59
59
|
|
60
60
|
def disable!
|
@@ -68,6 +68,11 @@ module ElasticRecord
|
|
68
68
|
def load_from_source!
|
69
69
|
self.load_from_source = true
|
70
70
|
model.singleton_class.delegate :find, :find_by, :find_each, :find_in_batches, :first, to: :elastic_search
|
71
|
+
|
72
|
+
model.instance_eval do
|
73
|
+
def _insert_record(*args); end
|
74
|
+
def _update_record(*args); end
|
75
|
+
end
|
71
76
|
end
|
72
77
|
|
73
78
|
def loading_from_source(&block)
|
@@ -91,6 +96,15 @@ module ElasticRecord
|
|
91
96
|
|
92
97
|
private
|
93
98
|
|
99
|
+
def add_suffix(name)
|
100
|
+
suffix = ElasticRecord::Config.index_suffix
|
101
|
+
if suffix && !name.end_with?(suffix)
|
102
|
+
name + "_#{suffix}"
|
103
|
+
else
|
104
|
+
name
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
94
108
|
def new_index_name
|
95
109
|
"#{alias_name}_#{Time.now.utc.strftime('%Y%m%d_%H%M%S')}"
|
96
110
|
end
|
data/lib/elastic_record/model.rb
CHANGED
@@ -4,6 +4,7 @@ module ElasticRecord
|
|
4
4
|
base.class_eval do
|
5
5
|
extend Searching
|
6
6
|
extend ClassMethods
|
7
|
+
extend FromSearchHit
|
7
8
|
include Callbacks
|
8
9
|
include AsDocument
|
9
10
|
|
@@ -38,6 +39,10 @@ module ElasticRecord
|
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
42
|
+
def index_to_elasticsearch
|
43
|
+
elastic_index.index_record(self)
|
44
|
+
end
|
45
|
+
|
41
46
|
def arelastic
|
42
47
|
self.class.arelastic
|
43
48
|
end
|
@@ -16,15 +16,14 @@ module ElasticRecord
|
|
16
16
|
}
|
17
17
|
}
|
18
18
|
def elastic_index
|
19
|
-
@elastic_index ||=
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
19
|
+
@elastic_index ||= begin
|
20
|
+
index = ElasticRecord::Index.new(self)
|
21
|
+
index.mapping = DEFAULT_PERCOLATOR_MAPPING
|
22
|
+
index.mapping = percolates_model.elastic_index.mapping
|
23
|
+
index.settings = percolates_model.elastic_index.settings
|
24
|
+
index.partial_updates = false
|
25
|
+
index
|
26
|
+
end
|
28
27
|
end
|
29
28
|
|
30
29
|
def percolate(document)
|
@@ -8,14 +8,20 @@ module ElasticRecord
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def find_in_batches(options = {})
|
11
|
-
|
12
|
-
yield
|
11
|
+
find_hits_in_batches(options) do |hits|
|
12
|
+
yield hits.to_records
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def find_ids_in_batches(options = {})
|
17
|
+
find_hits_in_batches(options) do |hits|
|
18
|
+
yield hits.to_ids
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_hits_in_batches(options = {})
|
17
23
|
build_scroll_enumerator(options).each_slice do |hits|
|
18
|
-
yield SearchHits.new(klass, hits)
|
24
|
+
yield SearchHits.new(klass, hits)
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ElasticRecord
|
2
|
+
class Relation
|
3
|
+
module Calculations
|
4
|
+
# Retrieve a single aggregation:
|
5
|
+
#
|
6
|
+
# Widget.elastic_search.calculate(cardinality: {field: color'}).value
|
7
|
+
# => 3
|
8
|
+
def calculate(aggregation)
|
9
|
+
agg_name = SecureRandom.hex(6)
|
10
|
+
aggregate(agg_name => aggregation).aggregations[agg_name]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'elastic_record/relation/value_methods'
|
2
2
|
require 'elastic_record/relation/batches'
|
3
|
+
require 'elastic_record/relation/calculations'
|
3
4
|
require 'elastic_record/relation/delegation'
|
4
5
|
require 'elastic_record/relation/finder_methods'
|
5
6
|
require 'elastic_record/relation/hits'
|
@@ -9,7 +10,7 @@ require 'elastic_record/relation/search_methods'
|
|
9
10
|
|
10
11
|
module ElasticRecord
|
11
12
|
class Relation
|
12
|
-
include Batches, Delegation, FinderMethods, Hits, Merging, SearchMethods
|
13
|
+
include Batches, Calculations, Delegation, FinderMethods, Hits, Merging, SearchMethods
|
13
14
|
|
14
15
|
attr_reader :klass, :values
|
15
16
|
|
@@ -19,21 +19,10 @@ module ElasticRecord
|
|
19
19
|
|
20
20
|
def to_records
|
21
21
|
if model.elastic_index.load_from_source
|
22
|
-
hits.map { |hit|
|
22
|
+
hits.map { |hit| model.from_search_hit(hit) }
|
23
23
|
else
|
24
24
|
model.find to_ids
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def load_from_hit(hit)
|
31
|
-
model.new.tap do |record|
|
32
|
-
record.id = hit['_id']
|
33
|
-
hit['_source'].each do |k, v|
|
34
|
-
record.send("#{k}=", v) if record.respond_to?("#{k}=")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
27
|
end
|
39
28
|
end
|
data/lib/elastic_record.rb
CHANGED
@@ -8,11 +8,46 @@ class Project
|
|
8
8
|
include ActiveModel::Model
|
9
9
|
include ElasticRecord::Model
|
10
10
|
elastic_index.load_from_source!
|
11
|
+
elastic_index.mapping = {
|
12
|
+
properties: {
|
13
|
+
'name' => {
|
14
|
+
type: 'text'
|
15
|
+
},
|
16
|
+
'estimated_start_date' => {
|
17
|
+
type: 'date_range'
|
18
|
+
},
|
19
|
+
'team_members' => {
|
20
|
+
type: 'nested',
|
21
|
+
properties: {
|
22
|
+
'name' => { type: 'text' },
|
23
|
+
'estimated_age' => {
|
24
|
+
type: 'integer_range'
|
25
|
+
}
|
26
|
+
}
|
27
|
+
},
|
28
|
+
'manager' => {
|
29
|
+
type: 'object',
|
30
|
+
properties: {
|
31
|
+
'name' => { type: 'text' },
|
32
|
+
'estimated_age' => {
|
33
|
+
type: 'integer_range'
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
11
39
|
|
12
|
-
attr_accessor :id,
|
40
|
+
attr_accessor :id,
|
41
|
+
:name,
|
42
|
+
:estimated_start_date,
|
43
|
+
:team_members,
|
44
|
+
:manager
|
13
45
|
alias_method :as_json, :as_search_document
|
14
46
|
|
15
|
-
|
16
|
-
|
47
|
+
class TeamMember
|
48
|
+
include ActiveModel::Model
|
49
|
+
include ElasticRecord::Model
|
50
|
+
|
51
|
+
attr_accessor :name, :estimated_age
|
17
52
|
end
|
18
53
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class ElasticRecord::AggregationResponse::SingleValueAggregationTest < MiniTest::Test
|
4
|
+
def test_value
|
5
|
+
agg = ElasticRecord::AggregationResponse::SingleValueAggregation.new 'average_price', 'value' => 4
|
6
|
+
|
7
|
+
assert_equal 4, agg.value
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class ElasticRecord::FromSearchHitsTest < MiniTest::Test
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
@project = Project.new(
|
7
|
+
name: 'foo',
|
8
|
+
estimated_start_date: Date.new(2019, 1, 1)..Date.new(2019, 2, 1),
|
9
|
+
team_members: team_members,
|
10
|
+
manager: manager
|
11
|
+
)
|
12
|
+
Project.elastic_index.index_record(@project)
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
Project.elastic_index.delete_by_query query: { match_all: {} }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_ranges
|
20
|
+
document = Project.elastic_relation.search_hits.to_records.first
|
21
|
+
|
22
|
+
assert_equal 'foo', document.name
|
23
|
+
assert_equal @project.estimated_start_date, document.estimated_start_date
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_nested_ranges
|
27
|
+
document = Project.elastic_relation.search_hits.to_records.first
|
28
|
+
team_members = document.team_members.sort_by { |member| member['name'] }
|
29
|
+
|
30
|
+
assert_equal 26..29, team_members.first['estimated_age']
|
31
|
+
assert_equal 25..30, team_members.second['estimated_age']
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_object_ranges
|
35
|
+
document = Project.elastic_relation.search_hits.to_records.first
|
36
|
+
|
37
|
+
assert_equal 25..30, document.manager['estimated_age']
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def manager
|
43
|
+
Project::TeamMember.new(
|
44
|
+
name: 'Fred',
|
45
|
+
estimated_age: 25..30
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def team_members
|
50
|
+
[
|
51
|
+
Project::TeamMember.new(name: 'John', estimated_age: 25..30),
|
52
|
+
Project::TeamMember.new(name: 'Jill', estimated_age: 26..29)
|
53
|
+
]
|
54
|
+
end
|
55
|
+
end
|
@@ -99,7 +99,25 @@ class ElasticRecord::Index::DocumentsTest < MiniTest::Test
|
|
99
99
|
)
|
100
100
|
|
101
101
|
scroll_enumerator.request_more_hits
|
102
|
-
index.
|
102
|
+
index.delete_scroll(scroll_enumerator.scroll_id)
|
103
|
+
assert_raises ElasticRecord::ExpiredScrollError do
|
104
|
+
scroll_enumerator.request_more_hits
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_each_slice
|
109
|
+
10.times { |i| index.index_document("bob#{i}", color: 'red') }
|
110
|
+
batches = []
|
111
|
+
|
112
|
+
scroll_enumerator = index.build_scroll_enumerator(search: {'query' => {query_string: {query: 'color:red'}}}, batch_size: 1)
|
113
|
+
|
114
|
+
scroll_enumerator.each_slice do |slice|
|
115
|
+
batches << slice
|
116
|
+
end
|
117
|
+
|
118
|
+
assert_equal 10, batches.size
|
119
|
+
|
120
|
+
# Assert context was removed
|
103
121
|
assert_raises ElasticRecord::ExpiredScrollError do
|
104
122
|
scroll_enumerator.request_more_hits
|
105
123
|
end
|
File without changes
|
@@ -9,11 +9,11 @@ class ElasticRecord::Index::SettingsTest < MiniTest::Test
|
|
9
9
|
class ModelWithAnalyzers
|
10
10
|
include TestModel
|
11
11
|
|
12
|
-
elastic_index.analysis = {
|
13
|
-
"analyzer"
|
14
|
-
"my_custom_analyzer"
|
15
|
-
"type"
|
16
|
-
"tokenizer"
|
12
|
+
elastic_index.settings['analysis'] = {
|
13
|
+
"analyzer" => {
|
14
|
+
"my_custom_analyzer" => {
|
15
|
+
"type" => "custom",
|
16
|
+
"tokenizer" => "standard"
|
17
17
|
}
|
18
18
|
}
|
19
19
|
}
|
@@ -26,10 +26,10 @@ class ElasticRecord::Index::SettingsTest < MiniTest::Test
|
|
26
26
|
def test_settings
|
27
27
|
expected = {
|
28
28
|
"analysis" => {
|
29
|
-
"analyzer"
|
30
|
-
"my_custom_analyzer"
|
31
|
-
"type"
|
32
|
-
"tokenizer"
|
29
|
+
"analyzer" => {
|
30
|
+
"my_custom_analyzer" => {
|
31
|
+
"type" => "custom",
|
32
|
+
"tokenizer" => "standard"
|
33
33
|
}
|
34
34
|
}
|
35
35
|
},
|
@@ -9,6 +9,12 @@ class ElasticRecord::IndexTest < MiniTest::Test
|
|
9
9
|
|
10
10
|
def test_alias_name
|
11
11
|
assert_equal 'widgets', index.alias_name
|
12
|
+
|
13
|
+
ElasticRecord::Config.index_suffix = 'test'
|
14
|
+
index.alias_name = "other_name"
|
15
|
+
assert_equal 'other_name_test', index.alias_name
|
16
|
+
ensure
|
17
|
+
ElasticRecord::Config.index_suffix = nil
|
12
18
|
end
|
13
19
|
|
14
20
|
def test_disable
|
@@ -24,4 +24,11 @@ class ElasticRecord::ModelTest < MiniTest::Test
|
|
24
24
|
assert_equal InheritedModel, InheritedModel.elastic_index.model
|
25
25
|
assert_equal 'widget', InheritedModel.elastic_index.mapping_type
|
26
26
|
end
|
27
|
+
|
28
|
+
def test_index_to_elasticsearch
|
29
|
+
project = Project.new(name: 'scorpio')
|
30
|
+
project.index_to_elasticsearch
|
31
|
+
|
32
|
+
assert_equal [project.name], Project.filter(name: 'scorpio').map(&:name)
|
33
|
+
end
|
27
34
|
end
|
@@ -16,6 +16,14 @@ class ElasticRecord::Relation::BatchesTest < MiniTest::Test
|
|
16
16
|
# assert_equal [@red_widget, @blue_widget, @green_widget].to_set, results.to_set
|
17
17
|
# end
|
18
18
|
|
19
|
+
def test_find_hits_in_batches
|
20
|
+
results = []
|
21
|
+
Widget.elastic_relation.find_hits_in_batches do |hits|
|
22
|
+
results << hits
|
23
|
+
end
|
24
|
+
assert_equal [[@red_widget, @blue_widget, @green_widget].to_set], results.map(&:to_records).map(&:to_set)
|
25
|
+
end
|
26
|
+
|
19
27
|
def test_find_ids_in_batches
|
20
28
|
results = []
|
21
29
|
Widget.elastic_relation.find_ids_in_batches do |ids|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class ElasticRecord::Relation::CalculationsTest < MiniTest::Test
|
4
|
+
def test_calculate
|
5
|
+
Widget.create!(color: 'red')
|
6
|
+
Widget.create!(color: 'red')
|
7
|
+
Widget.create!(color: 'blue')
|
8
|
+
|
9
|
+
assert_equal 2, Widget.elastic_relation.calculate('cardinality' => {'field' => 'color'}).value
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Infogroup
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-04-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: arelastic
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/elastic_record/config.rb
|
68
68
|
- lib/elastic_record/connection.rb
|
69
69
|
- lib/elastic_record/errors.rb
|
70
|
+
- lib/elastic_record/from_search_hit.rb
|
70
71
|
- lib/elastic_record/index.rb
|
71
72
|
- lib/elastic_record/index/analyze.rb
|
72
73
|
- lib/elastic_record/index/deferred.rb
|
@@ -74,7 +75,6 @@ files:
|
|
74
75
|
- lib/elastic_record/index/manage.rb
|
75
76
|
- lib/elastic_record/index/mapping.rb
|
76
77
|
- lib/elastic_record/index/mapping_type.rb
|
77
|
-
- lib/elastic_record/index/mapping_type_test.rb
|
78
78
|
- lib/elastic_record/index/settings.rb
|
79
79
|
- lib/elastic_record/log_subscriber.rb
|
80
80
|
- lib/elastic_record/lucene.rb
|
@@ -84,6 +84,7 @@ files:
|
|
84
84
|
- lib/elastic_record/railties/controller_runtime.rb
|
85
85
|
- lib/elastic_record/relation.rb
|
86
86
|
- lib/elastic_record/relation/batches.rb
|
87
|
+
- lib/elastic_record/relation/calculations.rb
|
87
88
|
- lib/elastic_record/relation/delegation.rb
|
88
89
|
- lib/elastic_record/relation/finder_methods.rb
|
89
90
|
- lib/elastic_record/relation/hits.rb
|
@@ -151,14 +152,17 @@ files:
|
|
151
152
|
- test/elastic_record/aggregation_response/bucket_test.rb
|
152
153
|
- test/elastic_record/aggregation_response/multi_bucket_aggregation_test.rb
|
153
154
|
- test/elastic_record/aggregation_response/single_bucket_aggregation_test.rb
|
155
|
+
- test/elastic_record/aggregation_response/single_value_aggregation_test.rb
|
154
156
|
- test/elastic_record/as_document_test.rb
|
155
157
|
- test/elastic_record/callbacks_test.rb
|
156
158
|
- test/elastic_record/config_test.rb
|
157
159
|
- test/elastic_record/connection_test.rb
|
160
|
+
- test/elastic_record/from_search_hits_test.rb
|
158
161
|
- test/elastic_record/index/analyze_test.rb
|
159
162
|
- test/elastic_record/index/documents_test.rb
|
160
163
|
- test/elastic_record/index/manage_test.rb
|
161
164
|
- test/elastic_record/index/mapping_test.rb
|
165
|
+
- test/elastic_record/index/mapping_type_test.rb
|
162
166
|
- test/elastic_record/index/settings_test.rb
|
163
167
|
- test/elastic_record/index_test.rb
|
164
168
|
- test/elastic_record/integration/active_record_test.rb
|
@@ -168,6 +172,7 @@ files:
|
|
168
172
|
- test/elastic_record/percolator_model_test.rb
|
169
173
|
- test/elastic_record/railties/controller_runtime_test.rb
|
170
174
|
- test/elastic_record/relation/batches_test.rb
|
175
|
+
- test/elastic_record/relation/calculations_test.rb
|
171
176
|
- test/elastic_record/relation/delegation_test.rb
|
172
177
|
- test/elastic_record/relation/finder_methods_test.rb
|
173
178
|
- test/elastic_record/relation/hits_test.rb
|
@@ -196,8 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
201
|
- !ruby/object:Gem::Version
|
197
202
|
version: 1.8.11
|
198
203
|
requirements: []
|
199
|
-
|
200
|
-
rubygems_version: 2.7.6
|
204
|
+
rubygems_version: 3.0.3
|
201
205
|
signing_key:
|
202
206
|
specification_version: 4
|
203
207
|
summary: An Elasticsearch querying ORM
|