elastic_record 4.0.0 → 4.1.0

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -6
  3. data/Gemfile +0 -2
  4. data/README.md +25 -9
  5. data/elastic_record.gemspec +1 -1
  6. data/lib/elastic_record/as_document.rb +41 -0
  7. data/lib/elastic_record/callbacks.rb +11 -56
  8. data/lib/elastic_record/connection.rb +1 -1
  9. data/lib/elastic_record/doctype.rb +43 -0
  10. data/lib/elastic_record/index/deferred.rb +13 -15
  11. data/lib/elastic_record/index/documents.rb +23 -13
  12. data/lib/elastic_record/index/manage.rb +4 -6
  13. data/lib/elastic_record/index/mapping.rb +7 -26
  14. data/lib/elastic_record/index/settings.rb +17 -2
  15. data/lib/elastic_record/index.rb +12 -24
  16. data/lib/elastic_record/model.rb +14 -4
  17. data/lib/elastic_record/percolator_model.rb +44 -0
  18. data/lib/elastic_record/relation.rb +1 -2
  19. data/lib/elastic_record/searching.rb +5 -1
  20. data/lib/elastic_record/tasks/index.rake +0 -10
  21. data/lib/elastic_record.rb +3 -0
  22. data/test/dummy/app/models/mock_model.rb +108 -0
  23. data/test/dummy/app/models/project.rb +1 -1
  24. data/test/dummy/app/models/test_model.rb +1 -102
  25. data/test/dummy/app/models/test_percolator_model.rb +8 -0
  26. data/test/dummy/app/models/widget.rb +2 -5
  27. data/test/dummy/app/models/widget_query.rb +14 -0
  28. data/test/dummy/config/environments/test.rb +3 -3
  29. data/test/dummy/config/initializers/elastic_record.rb +1 -1
  30. data/test/elastic_record/as_document_test.rb +65 -0
  31. data/test/elastic_record/callbacks_test.rb +6 -81
  32. data/test/elastic_record/config_test.rb +1 -1
  33. data/test/elastic_record/doctype_test.rb +45 -0
  34. data/test/elastic_record/index/documents_test.rb +1 -1
  35. data/test/elastic_record/index/mapping_test.rb +16 -13
  36. data/test/elastic_record/index/settings_test.rb +34 -1
  37. data/test/elastic_record/index_test.rb +7 -15
  38. data/test/elastic_record/model_test.rb +1 -7
  39. data/test/elastic_record/percolator_model_test.rb +54 -0
  40. data/test/elastic_record/relation/batches_test.rb +0 -1
  41. data/test/elastic_record/relation/delegation_test.rb +0 -1
  42. data/test/elastic_record/relation/finder_methods_test.rb +0 -1
  43. data/test/elastic_record/relation_test.rb +0 -2
  44. data/test/elastic_record/searching_test.rb +7 -0
  45. metadata +11 -10
  46. data/lib/elastic_record/index/configurator.rb +0 -18
  47. data/lib/elastic_record/index/percolator.rb +0 -50
  48. data/lib/elastic_record/index/warmer.rb +0 -24
  49. data/lib/elastic_record/relation/admin.rb +0 -13
  50. data/test/elastic_record/index/configurator_test.rb +0 -18
  51. data/test/elastic_record/index/percolator_test.rb +0 -45
  52. data/test/elastic_record/index/warmer_test.rb +0 -20
  53. data/test/elastic_record/relation/admin_test.rb +0 -28
@@ -2,108 +2,7 @@ module TestModel
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  included do
5
- extend ActiveModel::Naming
6
- extend ActiveModel::Callbacks
7
- define_model_callbacks :save, :update, :create, :destroy
8
-
9
- include ActiveModel::Dirty
10
- include ActiveModel::Validations
11
-
5
+ include MockModel
12
6
  include ElasticRecord::Model
13
7
  end
14
-
15
- module ClassMethods
16
- def find(ids)
17
- ids.map { |id| new(id: id) }
18
- end
19
-
20
- def where(query)
21
- find query[:id]
22
- end
23
-
24
- def primary_key
25
- 'id'
26
- end
27
-
28
- def base_class
29
- self
30
- end
31
-
32
- def create(attributes = {})
33
- record = new(attributes)
34
- record.save
35
- record
36
- end
37
-
38
- def define_attributes(attributes)
39
- define_attribute_methods attributes
40
-
41
- attributes.each do |attribute|
42
- define_method attribute do
43
- instance_variable_get("@#{attribute}")
44
- end
45
-
46
- define_method "#{attribute}=" do |value|
47
- send("#{attribute}_will_change!")
48
- instance_variable_set("@#{attribute}", value)
49
- end
50
- end
51
-
52
- define_method 'attributes' do
53
- Hash[attributes.map { |attr| [attr.to_s, send(attr)] }]
54
- end
55
- end
56
- end
57
-
58
- def initialize(attrs = {})
59
- self.attributes = attrs
60
- end
61
-
62
- def attributes=(attrs)
63
- attrs.each do |key, val|
64
- send("#{key}=", val)
65
- end
66
- end
67
-
68
- def id=(value)
69
- @id = value
70
- end
71
-
72
- def id
73
- @id ||= rand(10000).to_s
74
- end
75
-
76
- def save
77
- @persisted = true
78
- callback_method = new_record? ? :create : :update
79
- run_callbacks callback_method
80
- end
81
-
82
- def destroy
83
- @destroyed = true
84
- run_callbacks :destroy
85
- end
86
-
87
- def ==(other)
88
- id == other.id
89
- end
90
-
91
- def changed?
92
- true
93
- end
94
-
95
- def new_record?
96
- !@persisted
97
- end
98
-
99
- def persisted?
100
- @persisted
101
- end
102
-
103
- def destroyed?
104
- @destroyed
105
- end
106
-
107
- def reload
108
- end
109
8
  end
@@ -0,0 +1,8 @@
1
+ module TestPercolatorModel
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ include MockModel
6
+ include ElasticRecord::PercolatorModel
7
+ end
8
+ end
@@ -5,13 +5,10 @@ class Widget
5
5
 
6
6
  define_attributes [:name, :color, :warehouse_id]
7
7
 
8
- self.elastic_index.has_percolator = true
9
-
10
- self.elastic_index.mapping[:properties].update(
8
+ self.doctype.mapping[:properties].update(
11
9
  'name' => {
12
- type: 'string',
10
+ type: 'string', index: 'not_analyzed',
13
11
  fields: {
14
- name: {type: 'string', index: 'not_analyzed'},
15
12
  analyzed: {type: 'string', index: 'analyzed'}
16
13
  }
17
14
  },
@@ -0,0 +1,14 @@
1
+ class WidgetQuery
2
+ include TestPercolatorModel
3
+
4
+ define_attributes [:name, :color]
5
+
6
+ self.percolates_model = Widget
7
+
8
+ def as_search_document
9
+ filters = {}
10
+ filters[:name] = name if name
11
+ filters[:color] = color if color
12
+ percolates_model.elastic_search.filter(filters).as_elastic
13
+ end
14
+ end
@@ -12,9 +12,9 @@ Rails.application.configure do
12
12
  # preloads Rails for running tests, you may have to set it to true.
13
13
  config.eager_load = false
14
14
 
15
- # Configure static file server for tests with Cache-Control for performance.
16
- config.serve_static_files = true
17
- config.static_cache_control = 'public, max-age=3600'
15
+ # Configure public file server for tests with Cache-Control for performance.
16
+ config.public_file_server.enabled = true
17
+ config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
18
18
 
19
19
  # Show full error reports and disable caching.
20
20
  config.consider_all_requests_local = true
@@ -1,3 +1,3 @@
1
1
  ElasticRecord.configure do |config|
2
- config.model_names = %w(Warehouse Widget Project)
2
+ config.model_names = %w(Warehouse Widget WidgetQuery Project)
3
3
  end
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+
3
+ class ElasticRecord::AsDocumentTest < MiniTest::Test
4
+ def test_as_search_document
5
+ Widget.new(id: '10', color: 'green').tap do |widget|
6
+ assert_equal({"color" => "green"}, widget.as_search_document)
7
+ end
8
+
9
+ Widget.new(id: '10', color: '').tap do |widget|
10
+ assert_equal({}, widget.as_search_document)
11
+ end
12
+
13
+ Widget.new(id: '10', color: false).tap do |widget|
14
+ assert_equal({"color" => false}, widget.as_search_document)
15
+ end
16
+ end
17
+
18
+ def test_as_dirty_search
19
+ Widget.new(id: '10', color: 'green').tap do |widget|
20
+ assert_equal({'color' => 'green'}, widget.as_partial_update_document)
21
+ end
22
+
23
+ Widget.new(id: '10').tap do |widget|
24
+ assert_equal({}, widget.as_partial_update_document)
25
+ end
26
+
27
+ Widget.new(id: '10', color: '').tap do |widget|
28
+ assert_equal({'color' => nil}, widget.as_partial_update_document)
29
+ end
30
+ end
31
+
32
+ class SpecialFieldsModel
33
+ include TestModel
34
+
35
+ class Author
36
+ def as_search_document
37
+ {name: 'Jonny'}
38
+ end
39
+ end
40
+
41
+ self.doctype.mapping[:properties].update(
42
+ author: {
43
+ type: :object
44
+ },
45
+ commenters: {
46
+ type: :nested
47
+ }
48
+ )
49
+
50
+ def author
51
+ Author.new
52
+ end
53
+
54
+ def commenters
55
+ [Author.new, Author.new]
56
+ end
57
+ end
58
+
59
+ def test_as_search_document_with_special_fields
60
+ doc = SpecialFieldsModel.new.as_search_document
61
+
62
+ assert_equal({name: 'Jonny'}, doc[:author])
63
+ assert_equal([{name: 'Jonny'}, {name: 'Jonny'}], doc[:commenters])
64
+ end
65
+ end
@@ -21,7 +21,7 @@ class ElasticRecord::CallbacksTest < MiniTest::Test
21
21
 
22
22
  def test_deleted_from_index
23
23
  widget = Widget.new id: '10', color: 'green'
24
- Widget.elastic_index.index_document(widget.id, widget.as_search)
24
+ Widget.elastic_index.index_document(widget.id, widget.as_search_document)
25
25
 
26
26
  assert Widget.elastic_index.record_exists?(widget.id)
27
27
 
@@ -30,95 +30,20 @@ class ElasticRecord::CallbacksTest < MiniTest::Test
30
30
  refute Widget.elastic_index.record_exists?(widget.id)
31
31
  end
32
32
 
33
- def test_as_search
34
- Widget.new(id: '10', color: 'green').tap do |widget|
35
- assert_equal({"color" => "green"}, widget.as_search)
36
- end
37
-
38
- Widget.new(id: '10', color: '').tap do |widget|
39
- assert_equal({}, widget.as_search)
40
- end
41
-
42
- Widget.new(id: '10', color: false).tap do |widget|
43
- assert_equal({"color" => false}, widget.as_search)
44
- end
45
- end
46
-
47
- def test_as_dirty_search
48
- Widget.new(id: '10', color: 'green').tap do |widget|
49
- assert_equal({'color' => 'green'}, widget.as_partial_update_document)
50
- end
51
-
52
- Widget.new(id: '10').tap do |widget|
53
- assert_equal({}, widget.as_partial_update_document)
54
- end
55
-
56
- Widget.new(id: '10', color: '').tap do |widget|
57
- assert_equal({'color' => nil}, widget.as_partial_update_document)
58
- end
59
- end
60
-
61
- class SpecialFieldsModel
62
- include TestModel
63
-
64
- class Author
65
- def as_search
66
- {name: 'Jonny'}
67
- end
68
- end
69
-
70
- self.elastic_index.mapping[:properties].update(
71
- author: {
72
- type: :object
73
- },
74
- commenters: {
75
- type: :nested
76
- }
77
- )
78
-
79
- def author
80
- Author.new
81
- end
82
-
83
- def commenters
84
- [Author.new, Author.new]
85
- end
86
- end
87
-
88
- def test_as_search_with_special_fields
89
- doc = SpecialFieldsModel.new.as_search
90
-
91
- assert_equal({name: 'Jonny'}, doc[:author])
92
- assert_equal([{name: 'Jonny'}, {name: 'Jonny'}], doc[:commenters])
93
- end
94
-
95
33
  class DisablingModel
96
34
  include TestModel
97
35
 
98
- attr_accessor :called_as_search
99
-
100
36
  define_attributes [:height]
101
37
 
102
- self.elastic_index.mapping[:properties].update(
38
+ self.doctype.mapping[:properties].update(
103
39
  height: {
104
- type: 'string', index: 'not_analyzed'
40
+ type: 'keyword'
105
41
  }
106
42
  )
107
43
 
108
- def as_search
109
- @called_as_search = true
44
+ def as_search_document
45
+ raise StandardError.new("Should never be called!")
110
46
  super
111
47
  end
112
-
113
- end
114
-
115
- def test_disabled_skip_document
116
- DisablingModel.elastic_index.disable!
117
-
118
- model = DisablingModel.new id: '5', height: '9 feets'
119
- model.save
120
-
121
- refute Widget.elastic_index.record_exists?(model.id)
122
- refute model.called_as_search
123
48
  end
124
- end
49
+ end
@@ -8,7 +8,7 @@ class ElasticRecord::ConfigTest < MiniTest::Test
8
8
  def test_models
9
9
  ElasticRecord::Config.model_names = %w(Widget)
10
10
 
11
- assert_equal [Warehouse, Widget, Project], ElasticRecord::Config.models
11
+ assert_equal [Warehouse, Widget, WidgetQuery, Project], ElasticRecord::Config.models
12
12
  end
13
13
 
14
14
  def test_servers
@@ -0,0 +1,45 @@
1
+ require 'helper'
2
+
3
+ class ElasticRecord::DoctypeTest < MiniTest::Test
4
+ def test_default_mapping
5
+ doctype = ElasticRecord::Doctype.new('widget')
6
+
7
+ refute_nil doctype.mapping[:properties]
8
+ end
9
+
10
+ def test_default_analysis
11
+ doctype = ElasticRecord::Doctype.new('widget')
12
+
13
+ assert_empty doctype.analysis
14
+ end
15
+
16
+ def test_merge_mapping
17
+ doctype = ElasticRecord::Doctype.new('widget')
18
+ doctype.mapping[:properties] = {
19
+ color: { type: 'string' },
20
+ name: { type: 'string' }
21
+ }
22
+
23
+ custom = { properties: { color: { type: 'integer' } }}
24
+ doctype.mapping = custom
25
+
26
+ expected = {
27
+ properties: {
28
+ color: { type: 'integer' },
29
+ name: { type: 'string' }
30
+ },
31
+ _all: {
32
+ enabled: false
33
+ }
34
+ }
35
+
36
+ assert_equal expected, doctype.mapping
37
+ end
38
+
39
+ def test_percolator_doctype
40
+ doctype = ElasticRecord::Doctype.percolator_doctype
41
+
42
+ assert_equal 'queries', doctype.name
43
+ assert_equal ElasticRecord::Doctype::PERCOLATOR_MAPPING, doctype.mapping
44
+ end
45
+ end
@@ -28,7 +28,7 @@ class ElasticRecord::Index::DocumentsTest < MiniTest::Test
28
28
  index.update_document('abc', color: 'blue')
29
29
 
30
30
  expected = {'warehouse_id' => '5', 'color' => 'blue'}
31
- assert_equal expected, index.get('abc')['_source']
31
+ assert_equal expected, index.get('abc', Widget.doctype)['_source']
32
32
  end
33
33
 
34
34
  def test_delete_document
@@ -1,23 +1,26 @@
1
1
  require 'helper'
2
2
 
3
3
  class ElasticRecord::Index::MappingTest < MiniTest::Test
4
- def test_default_mapping
5
- mapping = index.mapping
4
+ def test_get_mapping
5
+ expected = {
6
+ "widget" => {
7
+ "_all" => { "enabled" => false },
8
+ "properties" => {
9
+ "color" => { "type" => "keyword" },
10
+ "name" => {
11
+ "type" => "keyword",
12
+ "fields" => { "analyzed" => { "type" => "text" } }
13
+ },
14
+ "warehouse_id" => { "type" => "keyword" }
15
+ }
16
+ }
17
+ }
6
18
 
7
- refute_nil mapping[:properties]
8
- end
9
-
10
- def test_merge_mapping
11
- index.mapping.clear
12
- index.mapping[:properties] = {color: {type: 'string'}}
13
-
14
- custom = {properties: {color: {type: 'integer'}}, other: 'stuff'}
15
- index.mapping = custom
16
-
17
- assert_equal custom, index.mapping
19
+ assert_equal expected, index.get_mapping
18
20
  end
19
21
 
20
22
  private
23
+
21
24
  def index
22
25
  @index ||= ElasticRecord::Index.new(Widget)
23
26
  end