esearch 0.2.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.
- data/.gitignore +5 -0
- data/.rspec +6 -0
- data/.travis.yml +19 -0
- data/Changelog.md +27 -0
- data/Gemfile +6 -0
- data/Gemfile.devtools +60 -0
- data/Guardfile +18 -0
- data/LICENSE +20 -0
- data/README.md +93 -0
- data/Rakefile +2 -0
- data/TODO +3 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +3 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +103 -0
- data/config/yardstick.yml +2 -0
- data/esearch.gemspec +26 -0
- data/lib/esearch.rb +43 -0
- data/lib/esearch/cluster.rb +85 -0
- data/lib/esearch/command.rb +158 -0
- data/lib/esearch/command/cluster.rb +28 -0
- data/lib/esearch/command/document.rb +111 -0
- data/lib/esearch/command/exist.rb +37 -0
- data/lib/esearch/command/index.rb +66 -0
- data/lib/esearch/command/search.rb +24 -0
- data/lib/esearch/command/status.rb +24 -0
- data/lib/esearch/connection.rb +36 -0
- data/lib/esearch/document.rb +53 -0
- data/lib/esearch/index.rb +61 -0
- data/lib/esearch/indices.rb +52 -0
- data/lib/esearch/mixin.rb +111 -0
- data/lib/esearch/presenter.rb +43 -0
- data/lib/esearch/presenter/aspect.rb +17 -0
- data/lib/esearch/presenter/aspect/range.rb +63 -0
- data/lib/esearch/presenter/aspect/term.rb +19 -0
- data/lib/esearch/presenter/cluster.rb +84 -0
- data/lib/esearch/presenter/document.rb +102 -0
- data/lib/esearch/presenter/facet.rb +72 -0
- data/lib/esearch/presenter/hit.rb +70 -0
- data/lib/esearch/presenter/hits.rb +60 -0
- data/lib/esearch/presenter/index.rb +23 -0
- data/lib/esearch/presenter/search.rb +32 -0
- data/lib/esearch/presenter/status.rb +18 -0
- data/lib/esearch/request.rb +90 -0
- data/lib/esearch/type.rb +40 -0
- data/spec/integration/esearch/spike_spec.rb +50 -0
- data/spec/spec_helper.rb +65 -0
- data/spec/support/example_group_methods.rb +7 -0
- data/spec/support/ice_nine_config.rb +6 -0
- data/spec/unit/esearch/cluster/class_methods/connect_spec.rb +16 -0
- data/spec/unit/esearch/cluster/health_spec.rb +10 -0
- data/spec/unit/esearch/cluster/index_spec.rb +11 -0
- data/spec/unit/esearch/cluster/indices_spec.rb +11 -0
- data/spec/unit/esearch/cluster/path_spec.rb +11 -0
- data/spec/unit/esearch/command/class_methods/run_spec.rb +16 -0
- data/spec/unit/esearch/command/cluster/health/run_spec.rb +14 -0
- data/spec/unit/esearch/command/document/delete/run_spec.rb +13 -0
- data/spec/unit/esearch/command/document/get/result_spec.rb +27 -0
- data/spec/unit/esearch/command/document/index/create/run_spec.rb +17 -0
- data/spec/unit/esearch/command/document/index/run_create_spec.rb +17 -0
- data/spec/unit/esearch/command/document/index/run_spec.rb +15 -0
- data/spec/unit/esearch/command/document/index/run_update_spec.rb +15 -0
- data/spec/unit/esearch/command/document/index/update/run_spec.rb +15 -0
- data/spec/unit/esearch/command/exist/result_spec.rb +39 -0
- data/spec/unit/esearch/command/index/create/run_spec.rb +14 -0
- data/spec/unit/esearch/command/index/delete/run_spec.rb +13 -0
- data/spec/unit/esearch/command/index/refresh/run_spec.rb +13 -0
- data/spec/unit/esearch/command/result_spec.rb +68 -0
- data/spec/unit/esearch/command/search/run_spec.rb +14 -0
- data/spec/unit/esearch/command/status/run_spec.rb +13 -0
- data/spec/unit/esearch/connection/class_methods/build_spec.rb +29 -0
- data/spec/unit/esearch/connection/run_spec.rb +36 -0
- data/spec/unit/esearch/document/connection_spec.rb +12 -0
- data/spec/unit/esearch/document/delete_spec.rb +12 -0
- data/spec/unit/esearch/document/get_spec.rb +12 -0
- data/spec/unit/esearch/index/create_spec.rb +12 -0
- data/spec/unit/esearch/index/delete_spec.rb +11 -0
- data/spec/unit/esearch/index/type_spec.rb +12 -0
- data/spec/unit/esearch/indices/all/path_spec.rb +12 -0
- data/spec/unit/esearch/mixin/document/index_create_spec.rb +31 -0
- data/spec/unit/esearch/mixin/document/index_spec.rb +31 -0
- data/spec/unit/esearch/mixin/document/index_update_spec.rb +31 -0
- data/spec/unit/esearch/mixin/exist/exist_predicate_spec.rb +16 -0
- data/spec/unit/esearch/mixin/index/refresh_spec.rb +16 -0
- data/spec/unit/esearch/mixin/index/status_spec.rb +16 -0
- data/spec/unit/esearch/mixin/search/search_spec.rb +18 -0
- data/spec/unit/esearch/presenter/aspect/range/from_spec.rb +24 -0
- data/spec/unit/esearch/presenter/aspect/range/to_spec.rb +24 -0
- data/spec/unit/esearch/presenter/class_methods/new_spec.rb +37 -0
- data/spec/unit/esearch/presenter/facet/build_spec.rb +26 -0
- data/spec/unit/esearch/presenter/facet/class_methods/build_spec.rb +26 -0
- data/spec/unit/esearch/presenter/hit/fields_spec.rb +24 -0
- data/spec/unit/esearch/presenter/hit/source_spec.rb +24 -0
- data/spec/unit/esearch/presenter/hits/each_spec.rb +15 -0
- data/spec/unit/esearch/presenter/hits/size_spec.rb +13 -0
- data/spec/unit/esearch/request/initialize_spec.rb +39 -0
- data/spec/unit/esearch/request/run_spec.rb +39 -0
- data/spec/unit/esearch/type/connection_spec.rb +15 -0
- data/spec/unit/esearch/type/document_spec.rb +12 -0
- metadata +330 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
class Command
|
|
3
|
+
# Search command
|
|
4
|
+
class Search < self
|
|
5
|
+
include Concord.new(:context, :query)
|
|
6
|
+
|
|
7
|
+
PRESENTER = Presenter::Search
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Return request
|
|
12
|
+
#
|
|
13
|
+
# @return [Request]
|
|
14
|
+
#
|
|
15
|
+
# @api private
|
|
16
|
+
#
|
|
17
|
+
def request
|
|
18
|
+
Request.get(context_path.join('_search'), query)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
class Command
|
|
3
|
+
|
|
4
|
+
# Command to return cluster status
|
|
5
|
+
class Status < self
|
|
6
|
+
include Concord.new(:context)
|
|
7
|
+
|
|
8
|
+
PRESENTER = Presenter::Status
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
# Return request
|
|
13
|
+
#
|
|
14
|
+
# @return [Request]
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
#
|
|
18
|
+
def request
|
|
19
|
+
Request.get(context_path.join('_status'))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
# Connection to an elasticsearch cluster
|
|
3
|
+
class Connection
|
|
4
|
+
include Adamantium::Flat, Concord.new(:raw_connection, :logger)
|
|
5
|
+
|
|
6
|
+
# Return connection
|
|
7
|
+
#
|
|
8
|
+
# @param [String] uri
|
|
9
|
+
#
|
|
10
|
+
# @return [Connection]
|
|
11
|
+
#
|
|
12
|
+
# @api private
|
|
13
|
+
#
|
|
14
|
+
def self.build(uri, logger = NullLogger.instance)
|
|
15
|
+
new(Faraday.new(uri), logger)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Run request
|
|
20
|
+
#
|
|
21
|
+
# @param [Command::Request] request
|
|
22
|
+
#
|
|
23
|
+
# @return [Faraday::Request]
|
|
24
|
+
#
|
|
25
|
+
# @api private
|
|
26
|
+
#
|
|
27
|
+
def run(request)
|
|
28
|
+
util = logger
|
|
29
|
+
util.debug { request.log_string }
|
|
30
|
+
response = request.run(raw_connection)
|
|
31
|
+
util.debug { response.status.to_s }
|
|
32
|
+
response
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
# Handler for document
|
|
3
|
+
class Document
|
|
4
|
+
include Adamantium::Flat, Concord.new(:type, :id)
|
|
5
|
+
include Mixin::Exist, Mixin::Document
|
|
6
|
+
|
|
7
|
+
# Delete document
|
|
8
|
+
#
|
|
9
|
+
# @return [Presenter::Command::Document::Delete]
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
#
|
|
13
|
+
def delete
|
|
14
|
+
Command::Document::Delete.run(self)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Return document
|
|
18
|
+
#
|
|
19
|
+
# @return [Presenter::Command::Document::Get]
|
|
20
|
+
# if foundd
|
|
21
|
+
#
|
|
22
|
+
# @return [nil]
|
|
23
|
+
# otherwise
|
|
24
|
+
#
|
|
25
|
+
# @api private
|
|
26
|
+
#
|
|
27
|
+
def get
|
|
28
|
+
Command::Document::Get.run(self)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Return path
|
|
32
|
+
#
|
|
33
|
+
# @return [Pathname]
|
|
34
|
+
#
|
|
35
|
+
# @api private
|
|
36
|
+
#
|
|
37
|
+
def path
|
|
38
|
+
type.path.join(id)
|
|
39
|
+
end
|
|
40
|
+
memoize :path
|
|
41
|
+
|
|
42
|
+
# Return connection
|
|
43
|
+
#
|
|
44
|
+
# @return [Connection]
|
|
45
|
+
#
|
|
46
|
+
# @api private
|
|
47
|
+
#
|
|
48
|
+
def connection
|
|
49
|
+
type.connection
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
# Driver for specific index
|
|
3
|
+
class Index
|
|
4
|
+
include Adamantium::Flat, Concord.new(:connection, :name)
|
|
5
|
+
include Mixin::Exist, Mixin::Search, Mixin::Index
|
|
6
|
+
|
|
7
|
+
# Return connection
|
|
8
|
+
#
|
|
9
|
+
# @return [Connection]
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
#
|
|
13
|
+
attr_reader :connection
|
|
14
|
+
|
|
15
|
+
# Cretate remote index
|
|
16
|
+
#
|
|
17
|
+
# @param [Hash] settings
|
|
18
|
+
#
|
|
19
|
+
# @return [Presenter::Index::Create]
|
|
20
|
+
#
|
|
21
|
+
# @api private
|
|
22
|
+
#
|
|
23
|
+
def create(settings)
|
|
24
|
+
Command::Index::Create.run(self, settings)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Delete remote index
|
|
28
|
+
#
|
|
29
|
+
# @return [Presenter::Index::Delete]
|
|
30
|
+
#
|
|
31
|
+
# @api private
|
|
32
|
+
#
|
|
33
|
+
def delete
|
|
34
|
+
Command::Index::Delete.run(self)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Return type for index
|
|
38
|
+
#
|
|
39
|
+
# @param [String] name
|
|
40
|
+
#
|
|
41
|
+
# @return [Type]
|
|
42
|
+
#
|
|
43
|
+
# @api private
|
|
44
|
+
#
|
|
45
|
+
def type(name)
|
|
46
|
+
Type.new(self, name)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Return path
|
|
50
|
+
#
|
|
51
|
+
# @return [Pathname]
|
|
52
|
+
#
|
|
53
|
+
# @api private
|
|
54
|
+
#
|
|
55
|
+
def path
|
|
56
|
+
Pathname.new("/#{name}")
|
|
57
|
+
end
|
|
58
|
+
memoize :path
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
# Handler for set of indices
|
|
3
|
+
class Indices
|
|
4
|
+
include Adamantium::Flat, Concord.new(:connection, :names)
|
|
5
|
+
include Mixin::Exist, Mixin::Index, Mixin::Search
|
|
6
|
+
|
|
7
|
+
# Return connection
|
|
8
|
+
#
|
|
9
|
+
# @return [Connection]
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
#
|
|
13
|
+
attr_reader :connection
|
|
14
|
+
|
|
15
|
+
# Return path
|
|
16
|
+
#
|
|
17
|
+
# @return [Pathname]
|
|
18
|
+
#
|
|
19
|
+
# @api private
|
|
20
|
+
#
|
|
21
|
+
def path
|
|
22
|
+
Pathname.new("/#{names.join(',')}")
|
|
23
|
+
end
|
|
24
|
+
memoize :path
|
|
25
|
+
|
|
26
|
+
# Control all indices of a cluster
|
|
27
|
+
class All < self
|
|
28
|
+
include Concord.new(:connection)
|
|
29
|
+
|
|
30
|
+
# Return connection
|
|
31
|
+
#
|
|
32
|
+
# @return [Connection]
|
|
33
|
+
#
|
|
34
|
+
# @api private
|
|
35
|
+
#
|
|
36
|
+
attr_reader :connection
|
|
37
|
+
|
|
38
|
+
# Return path
|
|
39
|
+
#
|
|
40
|
+
# @return [Pathname]
|
|
41
|
+
#
|
|
42
|
+
# @api private
|
|
43
|
+
#
|
|
44
|
+
def path
|
|
45
|
+
self.class::PATH
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
PATH = Pathname.new('/_all').freeze
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
# Namespace for handler mixins
|
|
3
|
+
module Mixin
|
|
4
|
+
|
|
5
|
+
# Mixin for exist predicate
|
|
6
|
+
module Exist
|
|
7
|
+
|
|
8
|
+
# Test if index does exist
|
|
9
|
+
#
|
|
10
|
+
# @return [true]
|
|
11
|
+
# if index exists
|
|
12
|
+
#
|
|
13
|
+
# @return [false]
|
|
14
|
+
# otherwise
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
#
|
|
18
|
+
def exist?
|
|
19
|
+
Command::Exist.run(self)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Mixin that adds document operations
|
|
25
|
+
module Document
|
|
26
|
+
|
|
27
|
+
# Index document
|
|
28
|
+
#
|
|
29
|
+
# @param [Document] document
|
|
30
|
+
# @param [Hash] options
|
|
31
|
+
#
|
|
32
|
+
# @return [Presenter::Document::Operation::Index]
|
|
33
|
+
#
|
|
34
|
+
# @api private
|
|
35
|
+
#
|
|
36
|
+
def index(document, options = {})
|
|
37
|
+
Command::Document::Index.run(self, document, options)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Create indexed document
|
|
41
|
+
#
|
|
42
|
+
# @param [Document] document
|
|
43
|
+
# @param [Hash] options
|
|
44
|
+
#
|
|
45
|
+
# @return [Presenter::Document::Operation::Index]
|
|
46
|
+
#
|
|
47
|
+
# @api private
|
|
48
|
+
#
|
|
49
|
+
def index_create(document, options = {})
|
|
50
|
+
Command::Document::Index::Create.run(self, document, options)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Update indexed document
|
|
54
|
+
#
|
|
55
|
+
# @param [Document] document
|
|
56
|
+
# @param [Hash] options
|
|
57
|
+
#
|
|
58
|
+
# @return [Presenter::Document::Operation::Index]
|
|
59
|
+
#
|
|
60
|
+
# @api private
|
|
61
|
+
#
|
|
62
|
+
def index_update(document, options = {})
|
|
63
|
+
Command::Document::Index::Update.run(self, document, options)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Mixin that adds index commands
|
|
69
|
+
module Index
|
|
70
|
+
|
|
71
|
+
# Refresh cluster
|
|
72
|
+
#
|
|
73
|
+
# @return [self]
|
|
74
|
+
#
|
|
75
|
+
# @api private
|
|
76
|
+
#
|
|
77
|
+
def refresh
|
|
78
|
+
Command::Index::Refresh.run(self)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Return status of cluster
|
|
82
|
+
#
|
|
83
|
+
# @return [Status]
|
|
84
|
+
#
|
|
85
|
+
# @api private
|
|
86
|
+
#
|
|
87
|
+
def status
|
|
88
|
+
Command::Index::Status.run(self)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Mixin for search command
|
|
94
|
+
module Search
|
|
95
|
+
|
|
96
|
+
# Return result
|
|
97
|
+
#
|
|
98
|
+
# @param [Hash] query
|
|
99
|
+
#
|
|
100
|
+
# @return [Presenter::Search]
|
|
101
|
+
#
|
|
102
|
+
# @api private
|
|
103
|
+
#
|
|
104
|
+
def search(query)
|
|
105
|
+
Command::Search.run(self, query)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
# Abstract base class for json response presenters
|
|
3
|
+
class Presenter
|
|
4
|
+
include Adamantium::Flat, AbstractType, Concord.new(:raw)
|
|
5
|
+
|
|
6
|
+
# Define tagged collection exposer
|
|
7
|
+
#
|
|
8
|
+
# @param [Symbol] name
|
|
9
|
+
# @param [Class:Presenter] presenter
|
|
10
|
+
#
|
|
11
|
+
# @return [undefined]
|
|
12
|
+
#
|
|
13
|
+
# @api private
|
|
14
|
+
#
|
|
15
|
+
def self.expose_tagged_collection(key, presenter)
|
|
16
|
+
key = key.to_s # caches string in closure ;)
|
|
17
|
+
define_method(key) do ||
|
|
18
|
+
raw.fetch(key).map do |name, element|
|
|
19
|
+
presenter.new(element.merge('name' => name))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
private_class_method :expose_tagged_collection
|
|
24
|
+
|
|
25
|
+
# Define primitive exposer
|
|
26
|
+
#
|
|
27
|
+
# @param [Symbol] key
|
|
28
|
+
# @param [Symbol] method_name
|
|
29
|
+
#
|
|
30
|
+
# @return [undefined]
|
|
31
|
+
#
|
|
32
|
+
# @api private
|
|
33
|
+
#
|
|
34
|
+
def self.expose_primitive(key, method_name = key)
|
|
35
|
+
key = key.to_s # caches string in closure ;)
|
|
36
|
+
define_method(method_name) do ||
|
|
37
|
+
raw.fetch(key)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
private_class_method :expose_primitive
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
class Presenter
|
|
3
|
+
|
|
4
|
+
# Abstract base class of an aspect of a facet
|
|
5
|
+
class Aspect < self
|
|
6
|
+
|
|
7
|
+
# Return count of occurences of aspect in facet
|
|
8
|
+
#
|
|
9
|
+
# @return [Fixnum]
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
#
|
|
13
|
+
expose_primitive(:count)
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Esearch
|
|
2
|
+
class Presenter
|
|
3
|
+
class Aspect
|
|
4
|
+
|
|
5
|
+
# Range aspect
|
|
6
|
+
class Range < self
|
|
7
|
+
|
|
8
|
+
# Return range start
|
|
9
|
+
#
|
|
10
|
+
# @return [Float]
|
|
11
|
+
# if present
|
|
12
|
+
#
|
|
13
|
+
# @return [nil]
|
|
14
|
+
# otherwise
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
#
|
|
18
|
+
def from
|
|
19
|
+
raw['from']
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Return range end
|
|
23
|
+
#
|
|
24
|
+
# @return [Float]
|
|
25
|
+
# if present
|
|
26
|
+
#
|
|
27
|
+
# @return [nil]
|
|
28
|
+
# otherwise
|
|
29
|
+
#
|
|
30
|
+
# @api private
|
|
31
|
+
#
|
|
32
|
+
def to
|
|
33
|
+
raw['to']
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Return total count
|
|
37
|
+
#
|
|
38
|
+
# @return [Fixnum]
|
|
39
|
+
#
|
|
40
|
+
# @api private
|
|
41
|
+
#
|
|
42
|
+
expose_primitive(:total_count)
|
|
43
|
+
|
|
44
|
+
# Return total
|
|
45
|
+
#
|
|
46
|
+
# @return [Float]
|
|
47
|
+
#
|
|
48
|
+
# @api private
|
|
49
|
+
#
|
|
50
|
+
expose_primitive(:total)
|
|
51
|
+
|
|
52
|
+
# Return mean
|
|
53
|
+
#
|
|
54
|
+
# @return [Float]
|
|
55
|
+
#
|
|
56
|
+
# @api private
|
|
57
|
+
#
|
|
58
|
+
expose_primitive(:mean)
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|