elasticsearch-resources 0.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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +12 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +276 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/elasticsearch-resources.gemspec +32 -0
- data/lib/elasticsearch/resources.rb +35 -0
- data/lib/elasticsearch/resources/cluster.rb +59 -0
- data/lib/elasticsearch/resources/clusterable.rb +34 -0
- data/lib/elasticsearch/resources/configurable.rb +52 -0
- data/lib/elasticsearch/resources/configuration.rb +11 -0
- data/lib/elasticsearch/resources/configuration/cluster.rb +67 -0
- data/lib/elasticsearch/resources/configuration/index.rb +45 -0
- data/lib/elasticsearch/resources/configuration/settings.rb +25 -0
- data/lib/elasticsearch/resources/configuration/type.rb +29 -0
- data/lib/elasticsearch/resources/describable.rb +49 -0
- data/lib/elasticsearch/resources/document.rb +73 -0
- data/lib/elasticsearch/resources/document_factory.rb +49 -0
- data/lib/elasticsearch/resources/identifiable.rb +34 -0
- data/lib/elasticsearch/resources/index.rb +108 -0
- data/lib/elasticsearch/resources/indexable.rb +34 -0
- data/lib/elasticsearch/resources/locales/en.yml +29 -0
- data/lib/elasticsearch/resources/nameable.rb +28 -0
- data/lib/elasticsearch/resources/queryable.rb +36 -0
- data/lib/elasticsearch/resources/resource.rb +39 -0
- data/lib/elasticsearch/resources/response_factory.rb +49 -0
- data/lib/elasticsearch/resources/type.rb +99 -0
- data/lib/elasticsearch/resources/typeable.rb +34 -0
- data/lib/elasticsearch/resources/version.rb +5 -0
- metadata +188 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
class Document
|
4
|
+
include Resource
|
5
|
+
include Queryable
|
6
|
+
include Typeable
|
7
|
+
include Identifiable
|
8
|
+
include Describable
|
9
|
+
|
10
|
+
def initialize(id:, attributes: {}, type:)
|
11
|
+
self.type = type
|
12
|
+
self.id = id
|
13
|
+
self.attributes = attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
def cluster
|
17
|
+
index.cluster
|
18
|
+
end
|
19
|
+
|
20
|
+
def index
|
21
|
+
type.index
|
22
|
+
end
|
23
|
+
|
24
|
+
def client
|
25
|
+
type.client
|
26
|
+
end
|
27
|
+
|
28
|
+
def query(action, options = {})
|
29
|
+
params = {
|
30
|
+
index: index.name,
|
31
|
+
type: type.name,
|
32
|
+
id: id
|
33
|
+
}.merge(options)
|
34
|
+
|
35
|
+
super(action, **params)
|
36
|
+
end
|
37
|
+
|
38
|
+
def create(options = {})
|
39
|
+
params = {
|
40
|
+
body: attributes
|
41
|
+
}.merge(options)
|
42
|
+
|
43
|
+
query(:create, params)
|
44
|
+
end
|
45
|
+
|
46
|
+
def update(options = {})
|
47
|
+
params = {
|
48
|
+
body: attributes
|
49
|
+
}.merge(options)
|
50
|
+
|
51
|
+
query(:update, params)
|
52
|
+
end
|
53
|
+
|
54
|
+
[:exists?, :delete, :get].each do |action|
|
55
|
+
define_method action do |options = {}|
|
56
|
+
query(action, options)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_cluster
|
61
|
+
self.cluster
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_index(index: nil)
|
65
|
+
self.index
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_type(index: nil, type: nil)
|
69
|
+
self.type
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
class DocumentFactory
|
4
|
+
attr_reader :content, :resources
|
5
|
+
|
6
|
+
def initialize(content:, resources: {})
|
7
|
+
@content = content
|
8
|
+
@resources = resources
|
9
|
+
end
|
10
|
+
|
11
|
+
def build
|
12
|
+
type = get_type
|
13
|
+
type.document_class.new(
|
14
|
+
type: type,
|
15
|
+
id: content['_id'],
|
16
|
+
attributes: content['_source']
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_type
|
21
|
+
resources[:type] || build_type
|
22
|
+
end
|
23
|
+
|
24
|
+
def build_type
|
25
|
+
Elasticsearch::Resources::Type.new(index: get_index) do |type|
|
26
|
+
type.name = content['_type']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_index
|
31
|
+
resources[:index] || build_index
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_index
|
35
|
+
Elasticsearch::Resources::Index.new(cluster: get_cluster) do |index|
|
36
|
+
index.name = content['_index']
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_cluster
|
41
|
+
resources[:cluster] || build_cluster
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_cluster
|
45
|
+
Elasticsearch::Resources::Cluster.new
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
module Identifiable
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
base.include(InstanceMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
attr_reader :id
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def id=(id)
|
18
|
+
raise NullIdError.new if id.nil?
|
19
|
+
@id = id.to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class NullIdError < ArgumentError
|
24
|
+
def initialize
|
25
|
+
super(message)
|
26
|
+
end
|
27
|
+
|
28
|
+
def message
|
29
|
+
I18n.t('elasticsearch.resources.identifiable.null_id_error.message')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
class Index
|
4
|
+
include Resource
|
5
|
+
include Queryable
|
6
|
+
include Configurable
|
7
|
+
include Clusterable
|
8
|
+
include Nameable
|
9
|
+
|
10
|
+
define_configuration \
|
11
|
+
class_name: Configuration::Index,
|
12
|
+
default: -> { cluster.settings.index(self.class.configuration.id) }
|
13
|
+
|
14
|
+
def initialize(cluster:, &block)
|
15
|
+
self.cluster = cluster
|
16
|
+
configure(id: self.class.configuration.id, cluster: cluster.settings, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup!
|
20
|
+
unless exists?
|
21
|
+
create
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def teardown!
|
27
|
+
if exists?
|
28
|
+
delete
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def client
|
34
|
+
cluster.client
|
35
|
+
end
|
36
|
+
|
37
|
+
def name
|
38
|
+
settings.name || super
|
39
|
+
end
|
40
|
+
|
41
|
+
def types
|
42
|
+
[]
|
43
|
+
end
|
44
|
+
|
45
|
+
def query_index(action, options = {})
|
46
|
+
params = {
|
47
|
+
index: name
|
48
|
+
}.merge(options)
|
49
|
+
|
50
|
+
client.indices.send(action, **params)
|
51
|
+
end
|
52
|
+
|
53
|
+
def query(action, options = {})
|
54
|
+
params = {
|
55
|
+
index: name
|
56
|
+
}.merge(options)
|
57
|
+
|
58
|
+
super(action, **params)
|
59
|
+
end
|
60
|
+
|
61
|
+
def exists?
|
62
|
+
query_index(:exists?)
|
63
|
+
end
|
64
|
+
|
65
|
+
def create
|
66
|
+
query_index(:create)
|
67
|
+
end
|
68
|
+
|
69
|
+
def put_mapping(options = {})
|
70
|
+
query_index(:put_mapping, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
def delete
|
74
|
+
query_index(:delete)
|
75
|
+
end
|
76
|
+
|
77
|
+
def search(body, options = {})
|
78
|
+
params = {
|
79
|
+
body: body
|
80
|
+
}.merge(options)
|
81
|
+
|
82
|
+
query(:search, params)
|
83
|
+
end
|
84
|
+
|
85
|
+
def count(body, options = {})
|
86
|
+
params = {
|
87
|
+
body: body
|
88
|
+
}.merge(options)
|
89
|
+
|
90
|
+
query(:count, params)
|
91
|
+
end
|
92
|
+
|
93
|
+
def find_cluster
|
94
|
+
self.cluster
|
95
|
+
end
|
96
|
+
|
97
|
+
def find_index(index: nil)
|
98
|
+
matches_name?(index) ? self : nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_type(index: nil, type:)
|
102
|
+
types.find do |t|
|
103
|
+
t.find_type(type: type)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
module Indexable
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
base.include(InstanceMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
attr_reader :index
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def index=(index)
|
18
|
+
raise NullIndexError.new if index.nil?
|
19
|
+
@index = index
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class NullIndexError < ArgumentError
|
24
|
+
def initialize
|
25
|
+
super(message)
|
26
|
+
end
|
27
|
+
|
28
|
+
def message
|
29
|
+
I18n.t('elasticsearch.resources.indexable.null_index_error.message')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
en:
|
2
|
+
elasticsearch:
|
3
|
+
resources:
|
4
|
+
configuration:
|
5
|
+
cluster:
|
6
|
+
null_name_error:
|
7
|
+
message: 'Cluster cannot be assigned a nil name!'
|
8
|
+
null_host_error:
|
9
|
+
message: 'Cluster cannot be assigned a nil host!'
|
10
|
+
index:
|
11
|
+
null_name_error:
|
12
|
+
message: 'Index cannot be assigned a nil name!'
|
13
|
+
type:
|
14
|
+
null_name_error:
|
15
|
+
message: 'Type cannot be assigned a nil name!'
|
16
|
+
identifiable:
|
17
|
+
null_id_error:
|
18
|
+
message: "ID cannot be assigned a nil value!"
|
19
|
+
indexable:
|
20
|
+
null_index_error:
|
21
|
+
message: "Index cannot be nil!"
|
22
|
+
queryable:
|
23
|
+
client:
|
24
|
+
not_implemented_error: 'This resource does not implement #client.'
|
25
|
+
null_client_error:
|
26
|
+
message: "No client set. Cannot query!"
|
27
|
+
typeable:
|
28
|
+
null_type_error:
|
29
|
+
message: "Type cannot be nil!"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
module Nameable
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
base.include(InstanceMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
attr_reader :default_name
|
11
|
+
|
12
|
+
def define_default_name(name)
|
13
|
+
@default_name = name&.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module InstanceMethods
|
18
|
+
def name
|
19
|
+
self.class.default_name
|
20
|
+
end
|
21
|
+
|
22
|
+
def matches_name?(name)
|
23
|
+
name.to_s == self.name.to_s
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
module Queryable
|
4
|
+
def self.included(base)
|
5
|
+
base.include(Resource)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
base.include(InstanceMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
module InstanceMethods
|
14
|
+
def client
|
15
|
+
raise NotImplementedError.new(I18n.t('elasticsearch.resources.queryable.client.not_implemented_error'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def query(action, params = {})
|
19
|
+
raise NullClientError.new if client.nil?
|
20
|
+
response = client.send(action, **params)
|
21
|
+
ResponseFactory.new(resource: self, action: action, response: response).build
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class NullClientError < ArgumentError
|
26
|
+
def initialize
|
27
|
+
super(message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def message
|
31
|
+
I18n.t('elasticsearch.resources.queryable.null_client_error.message')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
module Resource
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
base.include(InstanceMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
def find_cluster
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_index(index: nil)
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_type(index: nil, type: nil)
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup!
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def populate!
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def teardown!
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Resources
|
3
|
+
class ResponseFactory
|
4
|
+
attr_reader :resource, :action, :response
|
5
|
+
|
6
|
+
def initialize(resource:, action:, response:)
|
7
|
+
@resource = resource
|
8
|
+
@action = action
|
9
|
+
@response = response
|
10
|
+
end
|
11
|
+
|
12
|
+
def build
|
13
|
+
case action
|
14
|
+
when :get
|
15
|
+
build_get
|
16
|
+
when :search
|
17
|
+
build_search
|
18
|
+
else
|
19
|
+
response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_get
|
24
|
+
DocumentFactory.new(
|
25
|
+
content: response,
|
26
|
+
resources: resources_for(response)
|
27
|
+
).build
|
28
|
+
end
|
29
|
+
|
30
|
+
def build_search
|
31
|
+
raw_documents = response['hits']['hits']
|
32
|
+
raw_documents.collect do |raw_document|
|
33
|
+
DocumentFactory.new(
|
34
|
+
content: raw_document,
|
35
|
+
resources: resources_for(raw_document)
|
36
|
+
).build
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def resources_for(content)
|
41
|
+
{
|
42
|
+
cluster: resource.find_cluster,
|
43
|
+
index: resource.find_index(index: content['_index']),
|
44
|
+
type: resource.find_type(index: content['_index'], type: content['_type'])
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|