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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab3d32f450ac1c3c57de3216607cd0e98933ee13e009081556e40170db56c4e7
4
- data.tar.gz: 3fe65fcfe4e06a56606aeb26e5dc0850433a146da77f3ceb4fcbf5fdff225813
3
+ metadata.gz: ea174acd40e5c2ec841c31085fea2a2994e0d05a705042d5ddf044e8c8962376
4
+ data.tar.gz: 1adb61c8170f1e966a7acb0c7c68ac95cc5f93181a81d6118f166de0cdf45a6a
5
5
  SHA512:
6
- metadata.gz: a7afe879bc728ec2feecf6c616fa7b405d2df8172b468a052c307eee5ae02f97062e7f24d04efaecc9717591b489e3c01e4023d8f7034a4afd5ed0cf99bc106c
7
- data.tar.gz: 79e3764907546cab0d8355f96ae32ca8460f8037a26009af46d77b3b8b107e6022832207227979a236d48507a2c70d069001c8b206b9c80960d920019084b4a8
6
+ metadata.gz: 741a6d678b18f9c373e7bc6412e98ab7ec5b97241af2fde09c84fb5b5baebac69d5236a893886c88ed73c37d81f4e426d4182f5818659cb5f675e820494e5d06
7
+ data.tar.gz: 848de3cb5054a6997aa8022721bf7dff2c40740921a127611033ec87dcda6e862945697ef19414c775b7b8c970671e19f251d6812cd193ad3eb797c52c9e95b8
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ gemspec
4
4
 
5
5
  gem 'dotenv-rails'
6
6
  gem 'oj'
7
- gem 'pg', '~> 0.21'
8
- gem 'rails'
9
- gem 'rake', '~> 10.5.0'
7
+ gem 'pg'
8
+ gem 'rails', '~> 5.2.2'
9
+ gem 'rake'
10
10
  gem 'webmock', require: false
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` (including analysis configuration) - Same as parent
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
@@ -13,6 +13,7 @@ Rake::TestTask.new(:test) do |t|
13
13
  t.libs << 'test'
14
14
  t.pattern = 'test/**/*_test.rb'
15
15
  t.verbose = false
16
+ t.warning = false
16
17
  end
17
18
 
18
19
  APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'elastic_record'
5
- s.version = '5.4.0'
5
+ s.version = '5.5.0'
6
6
  s.summary = 'An Elasticsearch querying ORM'
7
7
  s.description = 'Find your records with Elasticsearch'
8
8
 
@@ -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 :create_index_document
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
- self.connection_options = {}
7
-
8
- class_attribute :default_index_settings
9
- self.default_index_settings = {}
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 :scroll_id, :keep_alive, :batch_size
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.nil?
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 = response['_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 ||= begin
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)
@@ -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
@@ -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
- begin
21
- index = ElasticRecord::Index.new(self)
22
- index.mapping = DEFAULT_PERCOLATOR_MAPPING
23
- index.mapping = percolates_model.elastic_index.mapping
24
- index.analysis = percolates_model.elastic_index.analysis
25
- index.partial_updates = false
26
- index
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
- build_scroll_enumerator(options).each_slice do |hits|
12
- yield SearchHits.new(klass, hits).to_records
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).to_ids
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| load_from_hit(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
@@ -9,6 +9,7 @@ module ElasticRecord
9
9
  autoload :Config
10
10
  autoload :Connection
11
11
  autoload :Doctype
12
+ autoload :FromSearchHit
12
13
  autoload :Index
13
14
  autoload :Lucene
14
15
  autoload :Model
@@ -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, :name
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
- def as_search_document
16
- { name: name }
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
@@ -2,7 +2,7 @@ require 'helper'
2
2
 
3
3
  class ElasticRecord::ConfigTest < MiniTest::Test
4
4
  def test_defaults
5
- assert_equal '5m', ElasticRecord::Config.scroll_keep_alive
5
+ assert_equal '2m', ElasticRecord::Config.scroll_keep_alive
6
6
  end
7
7
 
8
8
  def test_models
@@ -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.connection.json_delete '/_search/scroll', scroll_id: scroll_enumerator.scroll_id
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
@@ -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": "custom",
16
- "tokenizer": "standard"
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": "custom",
32
- "tokenizer": "standard"
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.0
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: 2018-12-15 00:00:00.000000000 Z
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
- rubyforge_project:
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