elastic_adapter 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +3 -0
  3. data/.rubocop.yml +8 -0
  4. data/.ruby.yml +261 -0
  5. data/.travis.yml +6 -0
  6. data/README.md +87 -8
  7. data/elastic_adapter.gemspec +1 -0
  8. data/examples/basic_usage.rb +164 -0
  9. data/lib/elastic_adapter/decoration/count_response.rb +0 -2
  10. data/lib/elastic_adapter/decoration/decorator.rb +2 -4
  11. data/lib/elastic_adapter/decoration/response_decorator_factory.rb +3 -6
  12. data/lib/elastic_adapter/decoration/search_response.rb +0 -2
  13. data/lib/elastic_adapter/decoration/suggestion_response.rb +0 -1
  14. data/lib/elastic_adapter/decoration/validation_response.rb +0 -1
  15. data/lib/elastic_adapter/document_type.rb +12 -2
  16. data/lib/elastic_adapter/index.rb +103 -10
  17. data/lib/elastic_adapter/response.rb +2 -1
  18. data/lib/elastic_adapter/version.rb +1 -1
  19. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/is_a_response.yml +1 -1
  20. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/{returs_the_amount_of_all_documents.yml → returns_the_amount_of_all_documents.yml} +1 -1
  21. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index.yml +57 -0
  22. data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/is_a_response.yml +1 -1
  23. data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/returns_1.yml +1 -1
  24. data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index.yml +84 -0
  25. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present/response/has_an_exception.yml +2 -2
  26. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present/response/is_a_Response.yml +2 -2
  27. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present.yml +57 -0
  28. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response/has_no_exception.yml +2 -29
  29. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response/is_a_Response.yml +2 -29
  30. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response.yml +30 -0
  31. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_not_present/repsonse/has_an_exception.yml +1 -1
  32. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_not_present/repsonse/is_a_Response.yml +1 -1
  33. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/has_no_exception.yml +1 -28
  34. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/has_no_exceptionElasticAdapter_Index/_delete_index/index_present/repsonse.yml +30 -0
  35. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/is_a_Response.yml +1 -28
  36. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/is_a_ResponseElasticAdapter_Index/_delete_index/index_present/repsonse.yml +30 -0
  37. data/spec/cassettes/ElasticAdapter_Index/_get/document_exists/response/contains_the_document.yml +1 -1
  38. data/spec/cassettes/ElasticAdapter_Index/_get/document_exists.yml +84 -0
  39. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/doesn_t_change_the_document_count.yml +3 -3
  40. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/invokes_to_hash_on_the_document.yml +1 -1
  41. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/updates_the_document.yml +1 -1
  42. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document.yml +84 -0
  43. data/spec/cassettes/ElasticAdapter_Index/_index/new_document/indexes_a_document.yml +3 -3
  44. data/spec/cassettes/ElasticAdapter_Index/_index/new_document/invokes_to_hash_on_the_document.yml +2 -2
  45. data/spec/cassettes/ElasticAdapter_Index/_index/new_document.yml +57 -0
  46. data/spec/cassettes/ElasticAdapter_Index/_search/match_all/returns_all_documents.yml +3 -3
  47. data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_one_document.yml +3 -3
  48. data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_the_wanted_document.yml +3 -3
  49. data/spec/cassettes/ElasticAdapter_Index/_search.yml +111 -0
  50. data/spec/cassettes/ElasticAdapter_Index/_suggest/query_ba_/returns_bar.yml +2 -2
  51. data/spec/cassettes/ElasticAdapter_Index/_suggest/query_ba_/returns_one_result.yml +2 -2
  52. data/spec/cassettes/ElasticAdapter_Index/_suggest.yml +111 -0
  53. data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/is_a_response.yml +4 -3
  54. data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/is_false.yml +1 -1
  55. data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_a_response.yml +3 -3
  56. data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_true.yml +1 -1
  57. data/spec/cassettes/ElasticAdapter_Index/_validate.yml +57 -0
  58. data/spec/index/count_spec.rb +46 -0
  59. data/spec/index/create_index_spec.rb +39 -0
  60. data/spec/index/delete_index_spec.rb +29 -0
  61. data/spec/index/get_spec.rb +29 -0
  62. data/spec/index/index_spec.rb +60 -0
  63. data/spec/index/search_spec.rb +37 -0
  64. data/spec/index/shared_context.rb +37 -0
  65. data/spec/index/shared_examples.rb +19 -0
  66. data/spec/index/suggest_spec.rb +44 -0
  67. data/spec/index/unit_spec.rb +69 -0
  68. data/spec/index/validate_spec.rb +55 -0
  69. data/spec/spec_helper.rb +6 -1
  70. data/spec/support/index_helper.rb +78 -0
  71. metadata +72 -7
  72. data/spec/index_spec.rb +0 -458
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7d2b6efb6221dc7ad620073a1d963ce0f92415f
4
- data.tar.gz: c881d1dbbfd1c00d4864224ff8296758709258bd
3
+ metadata.gz: f388cfada6ca770fbeb5f7039efb9986a08c6bcd
4
+ data.tar.gz: 516fd85530fdf3b62561e829ff72728ef8c90f58
5
5
  SHA512:
6
- metadata.gz: b8d5f3a1b40dc170c471f14e4a1cc5552cca27c6fa96542f4fb7bee5e17386a34abe7e3247f8e4ebb9afb125d84242636bfb3a238ec1d5d3d3b0ab4eb1aef974
7
- data.tar.gz: 744cf2cdf6619e92f49aea07ded6d0e6e4640e769b262b6d3e566fdb52e823109b54a7dbe908d054d1a83adfd6ce7e6c08c163f6250f3dd186b4f58aff35f12c
6
+ metadata.gz: 42428a0a11237fad29bdb3f01f1ae007e23baec0da33d29ca3443a4bb8a76ea15eb61bbc42b16fbeb218d552a0463e6eea23cadd067aaa656e07cdf3aaf5f5f2
7
+ data.tar.gz: a71a53218c7ea5d93fe8150cb3667e9037f276bca3ac9c73bb232093e76d884b972803793d255d67e85ea1896227785ccf28c6bb5acc8baa2e1403ea3338c7f7
data/.hound.yml ADDED
@@ -0,0 +1,3 @@
1
+ ruby:
2
+ enable: true
3
+ config_file: .rubocop.yml
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ inherit_from: .ruby.yml
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - spec/**/*
6
+ - Gemfile
7
+ - Rakefile
8
+ - elastic_adapter.gemspec
data/.ruby.yml ADDED
@@ -0,0 +1,261 @@
1
+ # Taken from the thoughtbot/hound repository
2
+ # See https://github.com/thoughtbot/hound/blob/master/config/style_guides/ruby.yml
3
+ AllCops:
4
+ Exclude:
5
+ - db/schema.rb
6
+
7
+ AccessorMethodName:
8
+ Enabled: false
9
+
10
+ ActionFilter:
11
+ Enabled: false
12
+
13
+ Alias:
14
+ Enabled: false
15
+
16
+ ArrayJoin:
17
+ Enabled: false
18
+
19
+ AsciiComments:
20
+ Enabled: false
21
+
22
+ AsciiIdentifiers:
23
+ Enabled: false
24
+
25
+ Attr:
26
+ Enabled: false
27
+
28
+ BlockNesting:
29
+ Enabled: false
30
+
31
+ CaseEquality:
32
+ Enabled: false
33
+
34
+ CharacterLiteral:
35
+ Enabled: false
36
+
37
+ ClassAndModuleChildren:
38
+ Enabled: false
39
+
40
+ ClassLength:
41
+ Enabled: false
42
+
43
+ ClassVars:
44
+ Enabled: false
45
+
46
+ CollectionMethods:
47
+ PreferredMethods:
48
+ find: detect
49
+ reduce: inject
50
+ collect: map
51
+ find_all: select
52
+
53
+ ColonMethodCall:
54
+ Enabled: false
55
+
56
+ CommentAnnotation:
57
+ Enabled: false
58
+
59
+ CyclomaticComplexity:
60
+ Enabled: false
61
+
62
+ Delegate:
63
+ Enabled: false
64
+
65
+ DeprecatedHashMethods:
66
+ Enabled: false
67
+
68
+ Documentation:
69
+ Enabled: false
70
+
71
+ DotPosition:
72
+ EnforcedStyle: trailing
73
+
74
+ DoubleNegation:
75
+ Enabled: false
76
+
77
+ EachWithObject:
78
+ Enabled: false
79
+
80
+ EmptyLiteral:
81
+ Enabled: false
82
+
83
+ Encoding:
84
+ Enabled: false
85
+
86
+ EvenOdd:
87
+ Enabled: false
88
+
89
+ FileName:
90
+ Enabled: false
91
+
92
+ FlipFlop:
93
+ Enabled: false
94
+
95
+ FormatString:
96
+ Enabled: false
97
+
98
+ GlobalVars:
99
+ Enabled: false
100
+
101
+ GuardClause:
102
+ Enabled: false
103
+
104
+ IfUnlessModifier:
105
+ Enabled: false
106
+
107
+ IfWithSemicolon:
108
+ Enabled: false
109
+
110
+ InlineComment:
111
+ Enabled: false
112
+
113
+ Lambda:
114
+ Enabled: false
115
+
116
+ LambdaCall:
117
+ Enabled: false
118
+
119
+ LineEndConcatenation:
120
+ Enabled: false
121
+
122
+ LineLength:
123
+ Max: 80
124
+
125
+ MethodLength:
126
+ Enabled: false
127
+
128
+ ModuleFunction:
129
+ Enabled: false
130
+
131
+ NegatedIf:
132
+ Enabled: false
133
+
134
+ NegatedWhile:
135
+ Enabled: false
136
+
137
+ Next:
138
+ Enabled: false
139
+
140
+ NilComparison:
141
+ Enabled: false
142
+
143
+ Not:
144
+ Enabled: false
145
+
146
+ NumericLiterals:
147
+ Enabled: false
148
+
149
+ OneLineConditional:
150
+ Enabled: false
151
+
152
+ OpMethod:
153
+ Enabled: false
154
+
155
+ ParameterLists:
156
+ Enabled: false
157
+
158
+ PercentLiteralDelimiters:
159
+ Enabled: false
160
+
161
+ PerlBackrefs:
162
+ Enabled: false
163
+
164
+ PredicateName:
165
+ NamePrefixBlacklist:
166
+ - is_
167
+
168
+ Proc:
169
+ Enabled: false
170
+
171
+ RaiseArgs:
172
+ Enabled: false
173
+
174
+ RegexpLiteral:
175
+ Enabled: false
176
+
177
+ SelfAssignment:
178
+ Enabled: false
179
+
180
+ SingleLineBlockParams:
181
+ Enabled: false
182
+
183
+ SingleLineMethods:
184
+ Enabled: false
185
+
186
+ SignalException:
187
+ Enabled: false
188
+
189
+ SpecialGlobalVars:
190
+ Enabled: false
191
+
192
+ StringLiterals:
193
+ EnforcedStyle: double_quotes
194
+
195
+ VariableInterpolation:
196
+ Enabled: false
197
+
198
+ TrailingComma:
199
+ Enabled: false
200
+
201
+ TrivialAccessors:
202
+ Enabled: false
203
+
204
+ VariableInterpolation:
205
+ Enabled: false
206
+
207
+ WhenThen:
208
+ Enabled: false
209
+
210
+ WhileUntilModifier:
211
+ Enabled: false
212
+
213
+ WordArray:
214
+ Enabled: false
215
+
216
+ # Lint
217
+
218
+ AmbiguousOperator:
219
+ Enabled: false
220
+
221
+ AmbiguousRegexpLiteral:
222
+ Enabled: false
223
+
224
+ AssignmentInCondition:
225
+ Enabled: false
226
+
227
+ ConditionPosition:
228
+ Enabled: false
229
+
230
+ DeprecatedClassMethods:
231
+ Enabled: false
232
+
233
+ ElseLayout:
234
+ Enabled: false
235
+
236
+ HandleExceptions:
237
+ Enabled: false
238
+
239
+ InvalidCharacterLiteral:
240
+ Enabled: false
241
+
242
+ LiteralInCondition:
243
+ Enabled: false
244
+
245
+ LiteralInInterpolation:
246
+ Enabled: false
247
+
248
+ Loop:
249
+ Enabled: false
250
+
251
+ ParenthesesAsGroupedExpression:
252
+ Enabled: false
253
+
254
+ RequireParentheses:
255
+ Enabled: false
256
+
257
+ UnderscorePrefixedVariableName:
258
+ Enabled: false
259
+
260
+ Void:
261
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
4
+ addons:
5
+ code_climate:
6
+ repo_token: 4fa4c21362cc2292e0fa77663d676c75c97eaa88a58b9f7fa4e9c49a19ac0820
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
+ [![Build Status](https://travis-ci.org/kbredemeier/elastic_adatper.svg?branch=master)](https://travis-ci.org/kbredemeier/elastic_adatper) [![Code Climate](https://codeclimate.com/github/kbredemeier/elastic_adatper/badges/gpa.svg)](https://codeclimate.com/github/kbredemeier/elastic_adatper)
2
+
1
3
  # ElasticAdapter
2
4
 
3
- TODO: Write a gem description
5
+ This gem provides an implementation of the repository pattern. It is a result of some frustration
6
+ I had with the [elasticsearch-persistence](https://github.com/elasticsearch/elasticsearch-rails/tree/master/elasticsearch-persistence) gem. After reading [Hashie Considered Harmful](http://www.schneems.com/2014/12/15/hashie-considered-harmful.html) and some issues
7
+ I had with overriding methods on a subclassed Repository I decided to give it a own try.
4
8
 
5
9
  ## Installation
6
10
 
@@ -18,19 +22,94 @@ Or install it yourself as:
18
22
 
19
23
  $ gem install elastic_adapter
20
24
 
25
+ ## Documentation
26
+
27
+ Documentation can be found [here](http://www.rubydoc.info/github/kbredemeier/elastic_adatper/)
28
+
21
29
  ## Usage
22
30
 
23
- TODO: Write usage instructions here
31
+ First define the document type. Initialize it by passing a `name` and some `mappings` to the constructor:
24
32
 
33
+ ```ruby
34
+ mappings = {
35
+ product: {
36
+ properties: {
37
+ name: {
38
+ type: "string",
39
+ index_analyzer: "simple",
40
+ search_analyzer: "simple"
41
+ },
42
+ name_suggest: {
43
+ type: "completion"
44
+ },
45
+ price: {
46
+ type: "float",
47
+ index: "not_analyzed"
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ document_type = ElasticAdapter::DocumentType.new("product", mappings)
54
+ ```
25
55
 
26
- ## Testing and Development
56
+ Next define the index settings and instantiate the index:
57
+
58
+ ```ruby
59
+ settings = { number_of_shards: 1 }
60
+
61
+
62
+ index = ElasticAdapter::Index.new(
63
+ name: "product_index",
64
+ url: "http://localhost:9200",
65
+ log: true,
66
+ settings: settings,
67
+ document_type: document_type
68
+ )
69
+ ```
70
+
71
+ Now you can perform actions like create the index, index documents or search for them.
72
+ For a full list of feaures look into the [Documentation](http://www.rubydoc.info/github/kbredemeier/elastic_adatper/master/ElasticAdapter/Index).
27
73
 
28
- For a few specs I needed to place some sleep statements to make them work. To not slow down the specs with the sleep statements and for other reasons
29
- I decided to use VCR to capture the requests. I added a rake taks which sets an environment variable which is used in a helper function to decide either to
30
- `sleep 1` or not. This way the specs are not slowed down. To execute the rake task run `rake record`.
74
+ ```ruby
75
+ # Creating an Index
76
+
77
+ response = index.create_index
78
+ response.inspect # => "{:acknowledged=>true}"
79
+ response.class # => ElasticAdapter::Response
80
+ response.success? # => true
81
+
82
+ # Add a document to the index
83
+
84
+ doc = {
85
+ id: 1,
86
+ name_name: "foo",
87
+ suggest: "foo",
88
+ price: 11.12
89
+ }
90
+
91
+ response = index.index(doc)
92
+ response.inspect # => "{:index=>\"product_index\", :type=>\"product\", :id=>\"1\", :version=>1, :created=>true}"
93
+ response.class # => ElasticAdapter::Response
94
+ response.success? # => true
95
+
96
+ # Search for documents
97
+
98
+ query = {query: {match: {name: "foo"}}}
99
+ response = index.search(query)
100
+ response.inspect # => "{:count=>1, :hits=>[{:id=>\"1\", :name=>\"foo\", :name_suggest=>\"foo\", :price=>11.12}]}"
101
+ response.class # => ElasticAdapter::Decoration::SearchResponse
102
+ ```
103
+
104
+ Fore more usage examples look [here](https://github.com/kbredemeier/elastic_adatper/tree/master/examples)
105
+
106
+ ## Testing and Development
31
107
 
32
- Unfortunatly VCR skips recording some context blocks for unknown reason. I didn't had the time to look into that yet. That means that it is required
33
- to have a running elasticsearch at `localhost:9200` to run the specs.
108
+ I am using [VCR](https://github.com/vcr/vcr) to record the requests to elasticsearch and play them back while testing.
109
+ In some cases it might be necessary to rerecord the requests. Because elasticsearch is a little slow and doesn't return documents for a
110
+ search request that just have been indexed there are some sleep statements in the spec. To not slow down the tests those sleep statements
111
+ are just executed if a `RECORDING` environment variable is set. I added a rake task that sets the environment variable deletes the cassetts
112
+ and runs all specs with `:vcr`. Run `rake record` to rerecord the cassettes.
34
113
 
35
114
  ## Contributing
36
115
 
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "webmock", "~> 1.20.4"
28
28
  spec.add_development_dependency "pry-byebug", "~> 3.0.1"
29
29
  spec.add_development_dependency "yard", "~> 0.8.7.6"
30
+ spec.add_development_dependency "codeclimate-test-reporter"
30
31
  end
@@ -0,0 +1,164 @@
1
+ require "elastic_adapter"
2
+
3
+ mappings = {
4
+ product: {
5
+ properties: {
6
+ name: {
7
+ type: "string",
8
+ index_analyzer: "simple",
9
+ search_analyzer: "simple"
10
+ },
11
+ name_suggest: {
12
+ type: "completion"
13
+ },
14
+ price: {
15
+ type: "float",
16
+ index: "not_analyzed"
17
+ }
18
+ }
19
+ }
20
+ }
21
+
22
+ settings = { number_of_shards: 1 }
23
+
24
+ document_type = ElasticAdapter::DocumentType.new("product", mappings)
25
+
26
+ index = ElasticAdapter::Index.new(
27
+ name: "product_index",
28
+ url: "http://localhost:9200",
29
+ log: true,
30
+ settings: settings,
31
+ document_type: document_type
32
+ )
33
+
34
+ # Creating an Index
35
+
36
+ response = index.create_index
37
+ response.inspect # => "{:acknowledged=>true}"
38
+ response.class # => ElasticAdapter::Response
39
+ response.success? # => true
40
+
41
+ # Indexing
42
+
43
+ doc1 = {
44
+ id: 1,
45
+ name: "foo",
46
+ name_suggest: "foo",
47
+ price: 11.12
48
+ }
49
+ doc2 = {
50
+ id: 2,
51
+ name_suggest: "bar",
52
+ suggest: "bar",
53
+ price: 1.12
54
+ }
55
+
56
+ response = index.index(doc1)
57
+ response.inspect # => "{:index=>\"product_index\", :type=>\"product\", :id=>\"1\", :version=>1, :created=>true}"
58
+ response.class # => ElasticAdapter::Response
59
+ response.success? # => true
60
+
61
+ response = index.index(doc2)
62
+ response.inspect # => "{:index=>\"product_index\", :type=>\"product\", :id=>\"2\", :version=>1, :created=>true}"
63
+ response.class # => ElasticAdapter::Response
64
+ response.success? # => true
65
+
66
+ sleep 3
67
+
68
+ # Query validation
69
+
70
+ query = { query: { match_all: {} } }
71
+ response = index.validate(query)
72
+ response.inspect # => "true"
73
+ response.class # => ElasticAdapter::Decoration::ValidationResponse
74
+
75
+ query = { foo: { match_all: {} } }
76
+ response = index.validate(query)
77
+ response.inspect # => "false"
78
+ response.class # => ElasticAdapter::Decoration::ValidationResponse
79
+
80
+ # Count documents
81
+
82
+ response = index.count(query)
83
+ response.inspect # => "{:exception=>#<Elasticsearch::Transport::Transport::Errors::BadRequest: [400] {\"count\":0,\"_shards\":{\"total\":1,\"successful\":0,\"failed\":1,\"failures\":[{\"index\":\"product_index\",\"shard\":0,\"reason\":\"BroadcastShardOperationFailedException[[product_index][0] ]; nested: QueryParsingException[[product_index] request does not support [foo]]; \"}]}}>}"
84
+ response.class # => ElasticAdapter::Response
85
+
86
+ # Get documents
87
+
88
+ response = index.get(1)
89
+ response.inspect # => "{:id=>\"1\", :name=>\"foo\", :name_suggest=>\"foo\", :price=>11.12}"
90
+ response.class # => ElasticAdapter::Decoration::HitDecorator
91
+
92
+ # Search documents
93
+
94
+ response = index.search(query)
95
+ response.inspect # => "{:exception=>#<Elasticsearch::Transport::Transport::Errors::BadRequest: [400] {\"error\":\"SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[XRKX3VOdSDyg0HVSm3_Wiw][product_index][0]: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\\"foo\\\":{\\\"match_all\\\":{}}}]]]; nested: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [No parser for element [foo]]]; }]\",\"status\":400}>}"
96
+ response.class # => ElasticAdapter::Response
97
+
98
+ query = {query: {match: {name: "foo"}}}
99
+ response = index.search(query)
100
+ response.inspect # => "{:exception=>#<Elasticsearch::Transport::Transport::Errors::BadRequest: [400] {\"error\":\"SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[XRKX3VOdSDyg0HVSm3_Wiw][product_index][0]: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\\"foo\\\":{\\\"match_all\\\":{}}}]]]; nested: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [No parser for element [foo]]]; }]\",\"status\":400}>}"
101
+ response.class # => ElasticAdapter::Response
102
+
103
+ # Suggestions
104
+ suggest_query = {
105
+ product_suggest: {
106
+ text: "fo",
107
+ completion: {
108
+ field: "name_suggest"
109
+ }
110
+ }
111
+ }
112
+
113
+ response = index.suggest(suggest_query)
114
+ response.inspect # => "{:options=>[{:text=>\"foo\", :score=>1.0}]}"
115
+ response.class # => ElasticAdapter::Decoration::SuggestionResponse
116
+
117
+ # Deleting an Index
118
+
119
+ response = index.delete_index
120
+ response.inspect # => "{:acknowledged=>true}"
121
+ response.class # => ElasticAdapter::Response
122
+ response.success? # => true
123
+
124
+ # Failing actions
125
+
126
+ response = index.delete_index
127
+ response.inspect # => "{:exception=>#<Elasticsearch::Transport::Transport::Errors::NotFound: [404] {\"error\":\"IndexMissingException[[product_index] missing]\",\"status\":404}>}"
128
+ response.class # => ElasticAdapter::Response
129
+ response.success? # => false
130
+
131
+
132
+ # !> 2015-02-06 17:52:19 +0100: PUT http://localhost:9200/product_index [status:200, request:0.053s, query:n/a]
133
+ # !> 2015-02-06 17:52:19 +0100: > {"mappings":{"product":{"properties":{"name":{"type":"string","index_analyzer":"simple","search_analyzer":"simple"},"name_suggest":{"type":"completion"},"price":{"type":"float","index":"not_analyzed"}}}},"settings":{"number_of_shards":1}}
134
+ # !> 2015-02-06 17:52:19 +0100: < {"acknowledged":true}
135
+ # !> 2015-02-06 17:52:19 +0100: PUT http://localhost:9200/product_index/product/1 [status:201, request:0.037s, query:n/a]
136
+ # !> 2015-02-06 17:52:19 +0100: > {"name":"foo","name_suggest":"foo","price":11.12}
137
+ # !> 2015-02-06 17:52:19 +0100: < {"_index":"product_index","_type":"product","_id":"1","_version":1,"created":true}
138
+ # !> 2015-02-06 17:52:19 +0100: PUT http://localhost:9200/product_index/product/2 [status:201, request:0.005s, query:n/a]
139
+ # !> 2015-02-06 17:52:19 +0100: > {"name_suggest":"bar","suggest":"bar","price":1.12}
140
+ # !> 2015-02-06 17:52:19 +0100: < {"_index":"product_index","_type":"product","_id":"2","_version":1,"created":true}
141
+ # !> 2015-02-06 17:52:22 +0100: GET http://localhost:9200/product_index/_validate/query?explain=true [status:200, request:0.006s, query:n/a]
142
+ # !> 2015-02-06 17:52:22 +0100: > {"query":{"match_all":{}}}
143
+ # !> 2015-02-06 17:52:22 +0100: < {"valid":true,"_shards":{"total":1,"successful":1,"failed":0},"explanations":[{"index":"product_index","valid":true,"explanation":"ConstantScore(*:*)"}]}
144
+ # !> 2015-02-06 17:52:22 +0100: GET http://localhost:9200/product_index/_validate/query?explain=true [status:200, request:0.004s, query:n/a]
145
+ # !> 2015-02-06 17:52:22 +0100: > {"foo":{"match_all":{}}}
146
+ # !> 2015-02-06 17:52:22 +0100: < {"valid":false,"_shards":{"total":1,"successful":1,"failed":0},"explanations":[{"index":"product_index","valid":false,"error":"org.elasticsearch.index.query.QueryParsingException: [product_index] request does not support [foo]"}]}
147
+ # !> 2015-02-06 17:52:22 +0100: GET http://localhost:9200/product_index/_count [status:400, request:0.005s, query:N/A]
148
+ # !> 2015-02-06 17:52:22 +0100: > {"foo":{"match_all":{}}}
149
+ # !> 2015-02-06 17:52:22 +0100: < {"count":0,"_shards":{"total":1,"successful":0,"failed":1,"failures":[{"index":"product_index","shard":0,"reason":"BroadcastShardOperationFailedException[[product_index][0] ]; nested: QueryParsingException[[product_index] request does not support [foo]]; "}]}}
150
+ # !> 2015-02-06 17:52:22 +0100: [400] {"count":0,"_shards":{"total":1,"successful":0,"failed":1,"failures":[{"index":"product_index","shard":0,"reason":"BroadcastShardOperationFailedException[[product_index][0] ]; nested: QueryParsingException[[product_index] request does not support [foo]]; "}]}}
151
+ # !> 2015-02-06 17:52:22 +0100: GET http://localhost:9200/product_index/product/1 [status:200, request:0.004s, query:n/a]
152
+ # !> 2015-02-06 17:52:22 +0100: < {"_index":"product_index","_type":"product","_id":"1","_version":1,"found":true,"_source":{"name":"foo","name_suggest":"foo","price":11.12}}
153
+ # !> 2015-02-06 17:52:22 +0100: GET http://localhost:9200/product_index/_search [status:400, request:0.007s, query:N/A]
154
+ # !> 2015-02-06 17:52:22 +0100: > {"foo":{"match_all":{}}}
155
+ # !> 2015-02-06 17:52:22 +0100: < {"error":"SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[XRKX3VOdSDyg0HVSm3_Wiw][product_index][0]: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"foo\":{\"match_all\":{}}}]]]; nested: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [No parser for element [foo]]]; }]","status":400}
156
+ # !> 2015-02-06 17:52:22 +0100: [400] {"error":"SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[XRKX3VOdSDyg0HVSm3_Wiw][product_index][0]: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"foo\":{\"match_all\":{}}}]]]; nested: SearchParseException[[product_index][0]: from[-1],size[-1]: Parse Failure [No parser for element [foo]]]; }]","status":400}
157
+ # !> 2015-02-06 17:52:22 +0100: POST http://localhost:9200/product_index/_suggest [status:200, request:0.004s, query:n/a]
158
+ # !> 2015-02-06 17:52:22 +0100: > {"product_suggest":{"text":"fo","completion":{"field":"name_suggest"}}}
159
+ # !> 2015-02-06 17:52:22 +0100: < {"_shards":{"total":1,"successful":1,"failed":0},"product_suggest":[{"text":"fo","offset":0,"length":2,"options":[{"text":"foo","score":1.0}]}]}
160
+ # !> 2015-02-06 17:52:22 +0100: DELETE http://localhost:9200/product_index [status:200, request:0.014s, query:n/a]
161
+ # !> 2015-02-06 17:52:22 +0100: < {"acknowledged":true}
162
+ # !> 2015-02-06 17:52:22 +0100: DELETE http://localhost:9200/product_index [status:404, request:0.003s, query:N/A]
163
+ # !> 2015-02-06 17:52:22 +0100: < {"error":"IndexMissingException[[product_index] missing]","status":404}
164
+ # !> 2015-02-06 17:52:22 +0100: [404] {"error":"IndexMissingException[[product_index] missing]","status":404}
@@ -4,7 +4,6 @@ module ElasticAdapter
4
4
  # After decoration the decorator will point to the actual
5
5
  # count returned by elasticsearch
6
6
  class CountResponse < Decorator
7
-
8
7
  # Reduced the hash to the count returned by elasticsearch
9
8
  #
10
9
  # @param [Object] object
@@ -12,7 +11,6 @@ module ElasticAdapter
12
11
  def alter_object(object)
13
12
  object[:count]
14
13
  end
15
-
16
14
  end
17
15
  end
18
16
  end
@@ -7,7 +7,6 @@ module ElasticAdapter
7
7
  #
8
8
  # @attr [Object] original_object the original unmodified object
9
9
  class Decorator < SimpleDelegator
10
-
11
10
  attr_reader :original_object
12
11
 
13
12
  # Takes an object and stores it in `@original_object` and saves a
@@ -30,10 +29,9 @@ module ElasticAdapter
30
29
  #
31
30
  # @param [Object] object
32
31
  # @return [Object]
33
- def alter_object(object)
34
- fail NotImplementedError, "alter_object must be overriden in subclasses!"
32
+ def alter_object(_object)
33
+ fail NotImplementedError, "alter_object must be overriden in subclasses"
35
34
  end
36
-
37
35
  end
38
36
  end
39
37
  end
@@ -2,7 +2,7 @@ module ElasticAdapter
2
2
  module Decoration
3
3
  # This class is used inside the Response and is used to determin
4
4
  # the decorator for responses returned by elasticsearch
5
- #
5
+ #
6
6
  # @see Response#decorate
7
7
  class ResponseDecoratorFactory
8
8
  class << self
@@ -12,10 +12,7 @@ module ElasticAdapter
12
12
  # @param [Hash] response a response returned by elasticsearch
13
13
  # @return [Docorator] a decorated response
14
14
  def decorate(response)
15
- if response.key? :acknowledged
16
- elsif response.key? :created
17
- elsif response.key? :exception
18
- elsif response.key? :count
15
+ if response.key? :count
19
16
  return CountResponse.new(response)
20
17
  elsif response.key? :source
21
18
  return HitDecorator.new(response)
@@ -43,7 +40,7 @@ module ElasticAdapter
43
40
  return false if second_key.empty?
44
41
  return false unless second_key.first.is_a? Hash
45
42
  return false unless second_key.first.key? :options
46
- return true
43
+ true
47
44
  end
48
45
  end
49
46
  end
@@ -4,7 +4,6 @@ module ElasticAdapter
4
4
  #
5
5
  # @attr_reader [Integer] count the total amount of search results
6
6
  class SearchResponse < Decorator
7
-
8
7
  attr_reader :count
9
8
 
10
9
  # Reduces the interface and assigns the @count variable
@@ -23,7 +22,6 @@ module ElasticAdapter
23
22
 
24
23
  new_hash
25
24
  end
26
-
27
25
  end
28
26
  end
29
27
  end
@@ -3,7 +3,6 @@ module ElasticAdapter
3
3
  # Used to decorate responses from the elasticsearch suggestion api
4
4
  # @attr_reader [Integer] count the amount of suggestions
5
5
  class SuggestionResponse < Decorator
6
-
7
6
  attr_reader :count
8
7
 
9
8
  # Builds a Hash with a smaller interface from the
@@ -3,7 +3,6 @@ module ElasticAdapter
3
3
  # Used to decorate responses from the elasticseach suggest api.
4
4
  # Delegates to a Boolean
5
5
  class ValidationResponse < Decorator
6
-
7
6
  # Returns the validation status from the original hash
8
7
  #
9
8
  # @param [Hash] hash