active_median 0.2.2 → 0.2.3
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/CHANGELOG.md +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +14 -13
- data/lib/active_median.rb +6 -1
- data/lib/active_median/enumerable.rb +3 -1
- data/lib/active_median/model.rb +1 -2
- data/lib/active_median/mongoid.rb +21 -0
- data/lib/active_median/version.rb +1 -1
- metadata +27 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47d759f5155e0a9687eeb845cf25a65daae5fe2a475bed1dcc071b742413b8c4
|
4
|
+
data.tar.gz: 9eb8b10f9ff8526adcea04beb4fa68fb11e61b544f11413925280c5d37f10e2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af49d340ff2b1298d1706381a7879ac3666e9077a56607c2d8809b132f93eef3eb8beb9996aa7599157a3d900ad3951e606413cb936f23d045115d8baead0121
|
7
|
+
data.tar.gz: ed82a1e318b79372aace81c56d2ca9bd9c59f373be5795f2e595fc8a60c7a7bdd9f9191e5a46069c4ea7405347e3057abb3c1ad6ae794a252cdce6de7f5411b6
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ActiveMedian
|
2
2
|
|
3
|
-
Median for
|
3
|
+
Median for Active Record, Mongoid, arrays, and hashes
|
4
4
|
|
5
5
|
Supports:
|
6
6
|
|
@@ -8,13 +8,22 @@ Supports:
|
|
8
8
|
- MariaDB 10.3.3+
|
9
9
|
- MySQL and SQL (with extensions)
|
10
10
|
- SQL Server 2012+
|
11
|
-
- Arrays and hashes
|
12
11
|
|
13
12
|
:fire: Uses native functions for blazing performance
|
14
13
|
|
15
14
|
[](https://travis-ci.org/ankane/active_median)
|
16
15
|
|
17
|
-
##
|
16
|
+
## Getting Started
|
17
|
+
|
18
|
+
Add this line to your application’s Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'active_median'
|
22
|
+
```
|
23
|
+
|
24
|
+
For MySQL and SQLite, also follow [these instructions](#additional-instructions).
|
25
|
+
|
26
|
+
## Models
|
18
27
|
|
19
28
|
```ruby
|
20
29
|
Item.median(:price)
|
@@ -51,15 +60,7 @@ raise "Unpermitted column" unless ["column_a", "column_b"].include?(column)
|
|
51
60
|
User.median(column)
|
52
61
|
```
|
53
62
|
|
54
|
-
##
|
55
|
-
|
56
|
-
Add this line to your application’s Gemfile:
|
57
|
-
|
58
|
-
```ruby
|
59
|
-
gem 'active_median'
|
60
|
-
```
|
61
|
-
|
62
|
-
For MySQL and SQLite, also follow the instructions below.
|
63
|
+
## Additional Instructions
|
63
64
|
|
64
65
|
### MySQL
|
65
66
|
|
@@ -95,7 +96,7 @@ db.enable_load_extension(0)
|
|
95
96
|
|
96
97
|
### 0.2.0
|
97
98
|
|
98
|
-
A user-defined function is no longer needed. Create a migration with `ActiveMedian.drop_function` to remove it.
|
99
|
+
A user-defined function is no longer needed for Postgres. Create a migration with `ActiveMedian.drop_function` to remove it.
|
99
100
|
|
100
101
|
## Contributing
|
101
102
|
|
data/lib/active_median.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "active_support"
|
2
2
|
|
3
|
-
require "active_median/model"
|
4
3
|
require "active_median/enumerable"
|
5
4
|
require "active_median/version"
|
6
5
|
|
@@ -15,5 +14,11 @@ module ActiveMedian
|
|
15
14
|
end
|
16
15
|
|
17
16
|
ActiveSupport.on_load(:active_record) do
|
17
|
+
require "active_median/model"
|
18
18
|
extend(ActiveMedian::Model)
|
19
19
|
end
|
20
|
+
|
21
|
+
ActiveSupport.on_load(:mongoid) do
|
22
|
+
require "active_median/mongoid"
|
23
|
+
Mongoid::Document::ClassMethods.include(ActiveMedian::Mongoid)
|
24
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module Enumerable
|
2
2
|
unless method_defined?(:median)
|
3
3
|
def median(*args, &block)
|
4
|
-
if respond_to?(:scoping)
|
4
|
+
if !block && respond_to?(:scoping)
|
5
5
|
scoping { @klass.median(*args) }
|
6
|
+
elsif !block && respond_to?(:with_scope)
|
7
|
+
with_scope(self) { klass.median(*args) }
|
6
8
|
else
|
7
9
|
sorted = map(&block).sort
|
8
10
|
len = sorted.length
|
data/lib/active_median/model.rb
CHANGED
@@ -39,9 +39,8 @@ module ActiveMedian
|
|
39
39
|
# typecast
|
40
40
|
rows = []
|
41
41
|
columns = result.columns
|
42
|
-
cast_method = ActiveRecord::VERSION::MAJOR < 5 ? :type_cast : :cast_value
|
43
42
|
result.rows.each do |untyped_row|
|
44
|
-
rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] ? result.column_types[c].send(
|
43
|
+
rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] ? result.column_types[c].send(:cast_value, untyped_row[i]) : untyped_row[i] })
|
45
44
|
end
|
46
45
|
|
47
46
|
result =
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveMedian
|
2
|
+
module Mongoid
|
3
|
+
# https://www.compose.com/articles/mongo-metrics-finding-a-happy-median/
|
4
|
+
def median(column)
|
5
|
+
relation =
|
6
|
+
all
|
7
|
+
.group(_id: nil, count: {"$sum" => 1}, values: {"$push" => "$#{column}"})
|
8
|
+
.unwind("$values")
|
9
|
+
.asc(:values)
|
10
|
+
.project(count: {"$subtract" => ["$count", 1]}, values: 1)
|
11
|
+
.project(count: 1, values: 1, midpoint: {"$divide" => ["$count", 2]})
|
12
|
+
.project(count: 1, values: 1, midpoint: 1, high: {"$ceil" => "$midpoint"}, low: {"$floor" => "$midpoint"})
|
13
|
+
.group(_id: nil, values: {"$push" => "$values"}, high: {"$avg" => "$high"}, low: {"$avg" => "$low"})
|
14
|
+
.project(beginValue: {"$arrayElemAt" => ["$values", "$high"]}, endValue: {"$arrayElemAt" => ["$values", "$low"]})
|
15
|
+
.project(median: {"$avg" => ["$beginValue", "$endValue"]})
|
16
|
+
|
17
|
+
res = collection.aggregate(relation.pipeline).first
|
18
|
+
res ? res["median"] : nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_median
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: pg
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activerecord
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: groupdate
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,6 +120,7 @@ files:
|
|
106
120
|
- lib/active_median.rb
|
107
121
|
- lib/active_median/enumerable.rb
|
108
122
|
- lib/active_median/model.rb
|
123
|
+
- lib/active_median/mongoid.rb
|
109
124
|
- lib/active_median/version.rb
|
110
125
|
homepage: https://github.com/ankane/active_median
|
111
126
|
licenses:
|
@@ -119,16 +134,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
119
134
|
requirements:
|
120
135
|
- - ">="
|
121
136
|
- !ruby/object:Gem::Version
|
122
|
-
version: '2.
|
137
|
+
version: '2.4'
|
123
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
139
|
requirements:
|
125
140
|
- - ">="
|
126
141
|
- !ruby/object:Gem::Version
|
127
142
|
version: '0'
|
128
143
|
requirements: []
|
129
|
-
|
130
|
-
rubygems_version: 2.7.7
|
144
|
+
rubygems_version: 3.0.3
|
131
145
|
signing_key:
|
132
146
|
specification_version: 4
|
133
|
-
summary: Median for
|
147
|
+
summary: Median for Active Record, Mongoid, arrays, and hashes
|
134
148
|
test_files: []
|