elasticsearch-persistence 5.0.2 → 6.1.1

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 (81) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +2 -0
  3. data/Gemfile +9 -0
  4. data/README.md +206 -338
  5. data/Rakefile +15 -12
  6. data/elasticsearch-persistence.gemspec +6 -7
  7. data/examples/notes/application.rb +3 -4
  8. data/lib/elasticsearch/persistence.rb +2 -110
  9. data/lib/elasticsearch/persistence/repository.rb +212 -53
  10. data/lib/elasticsearch/persistence/repository/dsl.rb +94 -0
  11. data/lib/elasticsearch/persistence/repository/find.rb +27 -10
  12. data/lib/elasticsearch/persistence/repository/response/results.rb +21 -8
  13. data/lib/elasticsearch/persistence/repository/search.rb +30 -18
  14. data/lib/elasticsearch/persistence/repository/serialize.rb +65 -7
  15. data/lib/elasticsearch/persistence/repository/store.rb +38 -44
  16. data/lib/elasticsearch/persistence/version.rb +1 -1
  17. data/spec/repository/find_spec.rb +179 -0
  18. data/spec/repository/response/results_spec.rb +128 -0
  19. data/spec/repository/search_spec.rb +181 -0
  20. data/spec/repository/serialize_spec.rb +53 -0
  21. data/spec/repository/store_spec.rb +327 -0
  22. data/spec/repository_spec.rb +723 -0
  23. data/spec/spec_helper.rb +32 -0
  24. metadata +26 -104
  25. data/examples/music/album.rb +0 -54
  26. data/examples/music/artist.rb +0 -70
  27. data/examples/music/artists/_form.html.erb +0 -8
  28. data/examples/music/artists/artists_controller.rb +0 -67
  29. data/examples/music/artists/artists_controller_test.rb +0 -53
  30. data/examples/music/artists/index.html.erb +0 -60
  31. data/examples/music/artists/show.html.erb +0 -54
  32. data/examples/music/assets/application.css +0 -257
  33. data/examples/music/assets/autocomplete.css +0 -48
  34. data/examples/music/assets/blank_artist.png +0 -0
  35. data/examples/music/assets/blank_cover.png +0 -0
  36. data/examples/music/assets/form.css +0 -113
  37. data/examples/music/index_manager.rb +0 -73
  38. data/examples/music/search/index.html.erb +0 -95
  39. data/examples/music/search/search_controller.rb +0 -41
  40. data/examples/music/search/search_controller_test.rb +0 -12
  41. data/examples/music/search/search_helper.rb +0 -15
  42. data/examples/music/suggester.rb +0 -69
  43. data/examples/music/template.rb +0 -430
  44. data/examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.css +0 -7
  45. data/examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.js +0 -6
  46. data/examples/music/vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  47. data/lib/elasticsearch/persistence/client.rb +0 -51
  48. data/lib/elasticsearch/persistence/model.rb +0 -135
  49. data/lib/elasticsearch/persistence/model/base.rb +0 -87
  50. data/lib/elasticsearch/persistence/model/errors.rb +0 -8
  51. data/lib/elasticsearch/persistence/model/find.rb +0 -180
  52. data/lib/elasticsearch/persistence/model/rails.rb +0 -47
  53. data/lib/elasticsearch/persistence/model/store.rb +0 -254
  54. data/lib/elasticsearch/persistence/model/utils.rb +0 -0
  55. data/lib/elasticsearch/persistence/repository/class.rb +0 -71
  56. data/lib/elasticsearch/persistence/repository/naming.rb +0 -115
  57. data/lib/rails/generators/elasticsearch/model/model_generator.rb +0 -21
  58. data/lib/rails/generators/elasticsearch/model/templates/model.rb.tt +0 -9
  59. data/lib/rails/generators/elasticsearch_generator.rb +0 -2
  60. data/test/integration/model/model_basic_test.rb +0 -233
  61. data/test/integration/repository/custom_class_test.rb +0 -85
  62. data/test/integration/repository/customized_class_test.rb +0 -82
  63. data/test/integration/repository/default_class_test.rb +0 -116
  64. data/test/integration/repository/virtus_model_test.rb +0 -118
  65. data/test/test_helper.rb +0 -55
  66. data/test/unit/model_base_test.rb +0 -72
  67. data/test/unit/model_find_test.rb +0 -153
  68. data/test/unit/model_gateway_test.rb +0 -101
  69. data/test/unit/model_rails_test.rb +0 -112
  70. data/test/unit/model_store_test.rb +0 -576
  71. data/test/unit/persistence_test.rb +0 -32
  72. data/test/unit/repository_class_test.rb +0 -51
  73. data/test/unit/repository_client_test.rb +0 -32
  74. data/test/unit/repository_find_test.rb +0 -388
  75. data/test/unit/repository_indexing_test.rb +0 -37
  76. data/test/unit/repository_module_test.rb +0 -146
  77. data/test/unit/repository_naming_test.rb +0 -146
  78. data/test/unit/repository_response_results_test.rb +0 -98
  79. data/test/unit/repository_search_test.rb +0 -117
  80. data/test/unit/repository_serialize_test.rb +0 -57
  81. data/test/unit/repository_store_test.rb +0 -303
@@ -1,5 +1,5 @@
1
1
  module Elasticsearch
2
2
  module Persistence
3
- VERSION = "5.0.2"
3
+ VERSION = '6.1.1'
4
4
  end
5
5
  end
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+
3
+ describe Elasticsearch::Persistence::Repository::Find do
4
+
5
+ after do
6
+ begin; repository.delete_index!; rescue; end
7
+ end
8
+
9
+ let(:repository) do
10
+ DEFAULT_REPOSITORY
11
+ end
12
+
13
+ describe '#exists?' do
14
+
15
+ context 'when the document exists' do
16
+
17
+ let(:id) do
18
+ repository.save(a: 1)['_id']
19
+ end
20
+
21
+ it 'returns true' do
22
+ expect(repository.exists?(id)).to be(true)
23
+ end
24
+ end
25
+
26
+ context 'when the document does not exist' do
27
+
28
+ it 'returns false' do
29
+ expect(repository.exists?('1')).to be(false)
30
+ end
31
+ end
32
+
33
+ context 'when options are provided' do
34
+
35
+ let(:id) do
36
+ repository.save(a: 1)['_id']
37
+ end
38
+
39
+ it 'applies the options' do
40
+ expect(repository.exists?(id, type: 'other_type')).to be(false)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#find' do
46
+
47
+ context 'when options are not provided' do
48
+
49
+ context 'when a single id is provided' do
50
+
51
+ let!(:id) do
52
+ repository.save(a: 1)['_id']
53
+ end
54
+
55
+ it 'retrieves the document' do
56
+ expect(repository.find(id)).to eq('a' => 1)
57
+ end
58
+ end
59
+
60
+ context 'when an array of ids is provided' do
61
+
62
+ let!(:ids) do
63
+ 3.times.collect do |i|
64
+ repository.save(a: i)['_id']
65
+ end
66
+ end
67
+
68
+ it 'retrieves the documents' do
69
+ expect(repository.find(ids)).to eq([{ 'a' =>0 },
70
+ { 'a' => 1 },
71
+ { 'a' => 2 }])
72
+ end
73
+
74
+ context 'when some documents are found and some are not' do
75
+
76
+ before do
77
+ ids[1] = 22
78
+ ids
79
+ end
80
+
81
+ it 'returns nil in the result list for the documents not found' do
82
+ expect(repository.find(ids)).to eq([{ 'a' =>0 },
83
+ nil,
84
+ { 'a' => 2 }])
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'when multiple ids are provided' do
90
+
91
+ let!(:ids) do
92
+ 3.times.collect do |i|
93
+ repository.save(a: i)['_id']
94
+ end
95
+ end
96
+
97
+ it 'retrieves the documents' do
98
+ expect(repository.find(*ids)).to eq([{ 'a' =>0 },
99
+ { 'a' => 1 },
100
+ { 'a' => 2 }])
101
+ end
102
+ end
103
+
104
+ context 'when the document cannot be found' do
105
+
106
+ before do
107
+ begin; repository.create_index!; rescue; end
108
+ end
109
+
110
+ it 'raises a DocumentNotFound exception' do
111
+ expect {
112
+ repository.find(1)
113
+ }.to raise_exception(Elasticsearch::Persistence::Repository::DocumentNotFound)
114
+ end
115
+ end
116
+ end
117
+
118
+ context 'when options are provided' do
119
+
120
+ context 'when a single id is passed' do
121
+
122
+ let!(:id) do
123
+ repository.save(a: 1)['_id']
124
+ end
125
+
126
+ it 'applies the options' do
127
+ expect {
128
+ repository.find(id, type: 'none')
129
+ }.to raise_exception(Elasticsearch::Persistence::Repository::DocumentNotFound)
130
+ end
131
+ end
132
+
133
+ context 'when an array of ids is passed' do
134
+
135
+ let!(:ids) do
136
+ 3.times.collect do |i|
137
+ repository.save(a: i)['_id']
138
+ end
139
+ end
140
+
141
+ it 'applies the options' do
142
+ expect(repository.find(ids, type: 'none')).to eq([nil, nil, nil])
143
+ end
144
+ end
145
+
146
+ context 'when multiple ids are passed' do
147
+
148
+ let!(:ids) do
149
+ 3.times.collect do |i|
150
+ repository.save(a: i)['_id']
151
+ end
152
+ end
153
+
154
+ it 'applies the options' do
155
+ expect(repository.find(*ids, type: 'none')).to eq([nil, nil, nil])
156
+ end
157
+ end
158
+ end
159
+
160
+ context 'when a document_type is defined on the class' do
161
+
162
+ let(:repository) do
163
+ MyTestRepository.new(document_type:'other_type', client: DEFAULT_CLIENT, index_name: 'test')
164
+ end
165
+
166
+ let!(:ids) do
167
+ 3.times.collect do |i|
168
+ repository.save(a: i)['_id']
169
+ end
170
+ end
171
+
172
+ it 'uses the document type in the query' do
173
+ expect(repository.find(ids)).to eq([{ 'a' =>0 },
174
+ { 'a' => 1 },
175
+ { 'a' => 2 }])
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+
3
+ describe Elasticsearch::Persistence::Repository::Response::Results do
4
+
5
+ before(:all) do
6
+ class MyRepository
7
+ include Elasticsearch::Persistence::Repository
8
+
9
+ def deserialize(document)
10
+ 'Object'
11
+ end
12
+ end
13
+ end
14
+
15
+ let(:repository) do
16
+ MyRepository.new
17
+ end
18
+
19
+ after(:all) do
20
+ if defined?(MyRepository)
21
+ Object.send(:remove_const, MyRepository.name)
22
+ end
23
+ end
24
+
25
+ let(:response) do
26
+ { "took" => 2,
27
+ "timed_out" => false,
28
+ "_shards" => {"total" => 5, "successful" => 5, "failed" => 0},
29
+ "hits" =>
30
+ { "total" => 2,
31
+ "max_score" => 0.19,
32
+ "hits" =>
33
+ [{"_index" => "my_index",
34
+ "_type" => "note",
35
+ "_id" => "1",
36
+ "_score" => 0.19,
37
+ "_source" => {"id" => 1, "title" => "Test 1"}},
38
+
39
+ {"_index" => "my_index",
40
+ "_type" => "note",
41
+ "_id" => "2",
42
+ "_score" => 0.19,
43
+ "_source" => {"id" => 2, "title" => "Test 2"}}
44
+ ]
45
+ }
46
+ }
47
+ end
48
+
49
+ let(:results) do
50
+ described_class.new(repository, response)
51
+ end
52
+
53
+ describe '#repository' do
54
+
55
+ it 'should return the repository' do
56
+ expect(results.repository).to be(repository)
57
+ end
58
+ end
59
+
60
+ describe '#response' do
61
+
62
+ it 'returns the response' do
63
+ expect(results.response).to eq(response)
64
+ end
65
+
66
+ it 'wraps the response in a HashWrapper' do
67
+ expect(results.response._shards.total).to eq(5)
68
+ end
69
+
70
+ context 'when the response method is not called' do
71
+
72
+ it 'does not create an instance of HashWrapper' do
73
+ expect(Elasticsearch::Model::HashWrapper).not_to receive(:new)
74
+ results
75
+ end
76
+ end
77
+
78
+ context 'when the response method is called' do
79
+
80
+ it 'does create an instance of HashWrapper' do
81
+ expect(Elasticsearch::Model::HashWrapper).to receive(:new)
82
+ results.response
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '#total' do
88
+
89
+ it 'returns the total' do
90
+ expect(results.total).to eq(2)
91
+ end
92
+ end
93
+
94
+ describe '#max_score' do
95
+
96
+ it 'returns the max score' do
97
+ expect(results.max_score).to eq(0.19)
98
+ end
99
+ end
100
+
101
+ describe '#each' do
102
+
103
+ it 'delegates the method to the results' do
104
+ expect(results.size).to eq(2)
105
+ end
106
+ end
107
+
108
+ describe '#each_with_hit' do
109
+
110
+ it 'returns each deserialized object with the raw document' do
111
+ expect(results.each_with_hit { |pair| pair[0] = 'Obj'}).to eq(['Obj', 'Obj'].zip(response['hits']['hits']))
112
+ end
113
+ end
114
+
115
+ describe '#map_with_hit' do
116
+
117
+ it 'returns the result of the block called on a pair of each raw document and the deserialized object' do
118
+ expect(results.map_with_hit { |pair| pair[0] }).to eq(['Object', 'Object'])
119
+ end
120
+ end
121
+
122
+ describe '#raw_response' do
123
+
124
+ it 'returns the raw response from Elasticsearch' do
125
+ expect(results.raw_response).to eq(response)
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+
3
+ describe Elasticsearch::Persistence::Repository::Search do
4
+
5
+ after do
6
+ begin; repository.delete_index!; rescue; end
7
+ end
8
+
9
+ describe '#search' do
10
+
11
+ let(:repository) do
12
+ DEFAULT_REPOSITORY
13
+ end
14
+
15
+ context 'when the repository does not have a type set' do
16
+
17
+ before do
18
+ repository.save({ name: 'user' }, refresh: true)
19
+ end
20
+
21
+ context 'when a query definition is provided as a hash' do
22
+
23
+ it 'uses the default document type' do
24
+ expect(repository.search({ query: { match: { name: 'user' } } }).first).to eq('name' => 'user')
25
+ end
26
+ end
27
+
28
+ context 'when a query definition is provided as a string' do
29
+
30
+ it 'uses the default document type' do
31
+ expect(repository.search('user').first).to eq('name' => 'user')
32
+ end
33
+ end
34
+
35
+ context 'when the query definition is neither a String nor a Hash' do
36
+
37
+ it 'raises an ArgumentError' do
38
+ expect {
39
+ repository.search(1)
40
+ }.to raise_exception(ArgumentError)
41
+ end
42
+ end
43
+
44
+ context 'when options are provided' do
45
+
46
+ context 'when a query definition is provided as a hash' do
47
+
48
+ it 'uses the default document type' do
49
+ expect(repository.search({ query: { match: { name: 'user' } } }, type: 'other').first).to be_nil
50
+ end
51
+ end
52
+
53
+ context 'when a query definition is provided as a string' do
54
+
55
+ it 'uses the default document type' do
56
+ expect(repository.search('user', type: 'other').first).to be_nil
57
+ end
58
+ end
59
+
60
+ context 'when the query definition is neither a String nor a Hash' do
61
+
62
+ it 'raises an ArgumentError' do
63
+ expect {
64
+ repository.search(1)
65
+ }.to raise_exception(ArgumentError)
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ context 'when the repository does have a type set' do
72
+
73
+ let(:repository) do
74
+ MyTestRepository.new(document_type: 'other_note')
75
+ end
76
+
77
+ before do
78
+ repository.save({ name: 'user' }, refresh: true)
79
+ end
80
+
81
+ context 'when options are provided' do
82
+
83
+ context 'when a query definition is provided as a hash' do
84
+
85
+ it 'uses the options' do
86
+ expect(repository.search({ query: { match: { name: 'user' } } }, type: 'other').first).to be_nil
87
+ end
88
+ end
89
+
90
+ context 'when a query definition is provided as a string' do
91
+
92
+ it 'uses the options' do
93
+ expect(repository.search('user', type: 'other').first).to be_nil
94
+ end
95
+ end
96
+
97
+ context 'when the query definition is neither a String nor a Hash' do
98
+
99
+ it 'raises an ArgumentError' do
100
+ expect {
101
+ repository.search(1)
102
+ }.to raise_exception(ArgumentError)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ describe '#count' do
110
+
111
+ context 'when the repository does not have a type set' do
112
+
113
+ let(:repository) do
114
+ DEFAULT_REPOSITORY
115
+ end
116
+
117
+ before do
118
+ repository.save({ name: 'user' }, refresh: true)
119
+ end
120
+
121
+ context 'when a query definition is provided as a hash' do
122
+
123
+ it 'uses the default document type' do
124
+ expect(repository.count({ query: { match: { name: 'user' } } })).to eq(1)
125
+ end
126
+ end
127
+
128
+ context 'when a query definition is provided as a string' do
129
+
130
+ it 'uses the default document type' do
131
+ expect(repository.count('user')).to eq(1)
132
+ end
133
+ end
134
+
135
+ context 'when options are provided' do
136
+
137
+ context 'when a query definition is provided as a hash' do
138
+
139
+ it 'uses the options' do
140
+ expect(repository.count({ query: { match: { name: 'user' } } }, type: 'other')).to eq(0)
141
+ end
142
+ end
143
+
144
+ context 'when a query definition is provided as a string' do
145
+
146
+ it 'uses the options' do
147
+ expect(repository.count('user', type: 'other')).to eq(0)
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ context 'when the repository does have a type set' do
154
+
155
+ let(:repository) do
156
+ MyTestRepository.new(document_type: 'other_note')
157
+ end
158
+
159
+ before do
160
+ repository.save({ name: 'user' }, refresh: true)
161
+ end
162
+
163
+ context 'when options are provided' do
164
+
165
+ context 'when a query definition is provided as a hash' do
166
+
167
+ it 'uses the options' do
168
+ expect(repository.count({ query: { match: { name: 'user' } } }, type: 'other')).to eq(0)
169
+ end
170
+ end
171
+
172
+ context 'when a query definition is provided as a string' do
173
+
174
+ it 'uses the options' do
175
+ expect(repository.count('user', type: 'other')).to eq(0)
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end