elastic_adapter 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/.hound.yml +3 -0
- data/.rubocop.yml +8 -0
- data/.ruby.yml +261 -0
- data/.travis.yml +6 -0
- data/README.md +87 -8
- data/elastic_adapter.gemspec +1 -0
- data/examples/basic_usage.rb +164 -0
- data/lib/elastic_adapter/decoration/count_response.rb +0 -2
- data/lib/elastic_adapter/decoration/decorator.rb +2 -4
- data/lib/elastic_adapter/decoration/response_decorator_factory.rb +3 -6
- data/lib/elastic_adapter/decoration/search_response.rb +0 -2
- data/lib/elastic_adapter/decoration/suggestion_response.rb +0 -1
- data/lib/elastic_adapter/decoration/validation_response.rb +0 -1
- data/lib/elastic_adapter/document_type.rb +12 -2
- data/lib/elastic_adapter/index.rb +103 -10
- data/lib/elastic_adapter/response.rb +2 -1
- data/lib/elastic_adapter/version.rb +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/is_a_response.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/{returs_the_amount_of_all_documents.yml → returns_the_amount_of_all_documents.yml} +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_count/empty_index.yml +57 -0
- data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/is_a_response.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/returns_1.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index.yml +84 -0
- data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present/response/has_an_exception.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present/response/is_a_Response.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present.yml +57 -0
- data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response/has_no_exception.yml +2 -29
- data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response/is_a_Response.yml +2 -29
- data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response.yml +30 -0
- data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_not_present/repsonse/has_an_exception.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_not_present/repsonse/is_a_Response.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/has_no_exception.yml +1 -28
- data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/has_no_exceptionElasticAdapter_Index/_delete_index/index_present/repsonse.yml +30 -0
- data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/is_a_Response.yml +1 -28
- data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/is_a_ResponseElasticAdapter_Index/_delete_index/index_present/repsonse.yml +30 -0
- data/spec/cassettes/ElasticAdapter_Index/_get/document_exists/response/contains_the_document.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_get/document_exists.yml +84 -0
- data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/doesn_t_change_the_document_count.yml +3 -3
- data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/invokes_to_hash_on_the_document.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/updates_the_document.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_index/existing_document.yml +84 -0
- data/spec/cassettes/ElasticAdapter_Index/_index/new_document/indexes_a_document.yml +3 -3
- data/spec/cassettes/ElasticAdapter_Index/_index/new_document/invokes_to_hash_on_the_document.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_index/new_document.yml +57 -0
- data/spec/cassettes/ElasticAdapter_Index/_search/match_all/returns_all_documents.yml +3 -3
- data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_one_document.yml +3 -3
- data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_the_wanted_document.yml +3 -3
- data/spec/cassettes/ElasticAdapter_Index/_search.yml +111 -0
- data/spec/cassettes/ElasticAdapter_Index/_suggest/query_ba_/returns_bar.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_suggest/query_ba_/returns_one_result.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_suggest.yml +111 -0
- data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/is_a_response.yml +4 -3
- data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/is_false.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_a_response.yml +3 -3
- data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_true.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_validate.yml +57 -0
- data/spec/index/count_spec.rb +46 -0
- data/spec/index/create_index_spec.rb +39 -0
- data/spec/index/delete_index_spec.rb +29 -0
- data/spec/index/get_spec.rb +29 -0
- data/spec/index/index_spec.rb +60 -0
- data/spec/index/search_spec.rb +37 -0
- data/spec/index/shared_context.rb +37 -0
- data/spec/index/shared_examples.rb +19 -0
- data/spec/index/suggest_spec.rb +44 -0
- data/spec/index/unit_spec.rb +69 -0
- data/spec/index/validate_spec.rb +55 -0
- data/spec/spec_helper.rb +6 -1
- data/spec/support/index_helper.rb +78 -0
- metadata +72 -7
- data/spec/index_spec.rb +0 -458
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f388cfada6ca770fbeb5f7039efb9986a08c6bcd
|
4
|
+
data.tar.gz: 516fd85530fdf3b62561e829ff72728ef8c90f58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42428a0a11237fad29bdb3f01f1ae007e23baec0da33d29ca3443a4bb8a76ea15eb61bbc42b16fbeb218d552a0463e6eea23cadd067aaa656e07cdf3aaf5f5f2
|
7
|
+
data.tar.gz: a71a53218c7ea5d93fe8150cb3667e9037f276bca3ac9c73bb232093e76d884b972803793d255d67e85ea1896227785ccf28c6bb5acc8baa2e1403ea3338c7f7
|
data/.hound.yml
ADDED
data/.rubocop.yml
ADDED
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
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
[](https://travis-ci.org/kbredemeier/elastic_adatper) [](https://codeclimate.com/github/kbredemeier/elastic_adatper)
|
2
|
+
|
1
3
|
# ElasticAdapter
|
2
4
|
|
3
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
33
|
-
|
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
|
|
data/elastic_adapter.gemspec
CHANGED
@@ -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(
|
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? :
|
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
|
-
|
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
|