elastic_record 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
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