hightop 0.2.1 → 0.2.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/CHANGELOG.md +4 -0
- data/README.md +20 -14
- data/lib/hightop.rb +6 -1
- data/lib/hightop/enumerable.rb +4 -2
- data/lib/hightop/mongoid.rb +52 -0
- data/lib/hightop/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e2fc0f11b1504620f8989548410fb965f5399f10a2a160f8911c72e1ee9be73
|
4
|
+
data.tar.gz: b9a4289ebbd844162263c513bfcc93ebcb1a7c97f27b7ec8bee511729d7b0d37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bb15ebfacc0e6383ca32f46cca4839d8f8a69180154ddf2a6a9fca65b5fe11cfbdcf087b3ec767d21fabfa75db197c4b7b1d1f68bd332e030076f1ea5c8f0e2
|
7
|
+
data.tar.gz: 5659dc207fb18a98d70febfbd51f28a5155672365ed9b9a8e06dceff27d0c640abbb99461c1410f6209571f4e283201724383d82fd732c7ddab49cbcc665a66d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -4,23 +4,16 @@ A nice shortcut for group count queries
|
|
4
4
|
|
5
5
|
```ruby
|
6
6
|
Visit.top(:browser)
|
7
|
+
# {
|
8
|
+
# "Chrome" => 63,
|
9
|
+
# "Safari" => 50,
|
10
|
+
# "Firefox" => 34
|
11
|
+
# }
|
7
12
|
```
|
8
13
|
|
9
|
-
|
14
|
+
Works with Active Record, Mongoid, arrays and hashes
|
10
15
|
|
11
|
-
|
12
|
-
Visit.group(:browser).where("browser IS NOT NULL").order("count_all DESC, browser").count
|
13
|
-
```
|
14
|
-
|
15
|
-
Be sure to [sanitize user input](https://rails-sqli.org/) like you must with `group`
|
16
|
-
|
17
|
-
Also works with arrays and hashes
|
18
|
-
|
19
|
-
```ruby
|
20
|
-
["up", "up", "down"].top(1)
|
21
|
-
```
|
22
|
-
|
23
|
-
[](https://travis-ci.org/ankane/hightop)
|
16
|
+
[](https://travis-ci.org/ankane/hightop)
|
24
17
|
|
25
18
|
## Installation
|
26
19
|
|
@@ -68,6 +61,19 @@ And min count
|
|
68
61
|
Visit.top(:city, min: 10)
|
69
62
|
```
|
70
63
|
|
64
|
+
## User Input
|
65
|
+
|
66
|
+
If passing user input as the column, be sure to sanitize it first [like you must](https://rails-sqli.org/) with `group`.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
column = params[:column]
|
70
|
+
|
71
|
+
# check against permitted columns
|
72
|
+
raise "Unpermitted column" unless ["column_a", "column_b"].include?(column)
|
73
|
+
|
74
|
+
User.top(column)
|
75
|
+
```
|
76
|
+
|
71
77
|
## Arrays and Hashes
|
72
78
|
|
73
79
|
Arrays
|
data/lib/hightop.rb
CHANGED
@@ -3,9 +3,14 @@ require "active_support"
|
|
3
3
|
|
4
4
|
# modules
|
5
5
|
require "hightop/enumerable"
|
6
|
-
require "hightop/kicks"
|
7
6
|
require "hightop/version"
|
8
7
|
|
9
8
|
ActiveSupport.on_load(:active_record) do
|
9
|
+
require "hightop/kicks"
|
10
10
|
extend Hightop::Kicks
|
11
11
|
end
|
12
|
+
|
13
|
+
ActiveSupport.on_load(:mongoid) do
|
14
|
+
require "hightop/mongoid"
|
15
|
+
Mongoid::Document::ClassMethods.include(Hightop::Mongoid)
|
16
|
+
end
|
data/lib/hightop/enumerable.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Enumerable
|
2
2
|
def top(*args, &block)
|
3
|
-
if block || !respond_to?(:scoping)
|
3
|
+
if block || !(respond_to?(:scoping) || respond_to?(:with_scope))
|
4
4
|
limit, options, _ = args
|
5
5
|
if limit.is_a?(Hash) && args.size == 1
|
6
6
|
options = limit
|
@@ -19,8 +19,10 @@ module Enumerable
|
|
19
19
|
arr = counts.sort_by { |_, v| -v }
|
20
20
|
arr = arr[0...limit] if limit
|
21
21
|
Hash[arr]
|
22
|
-
|
22
|
+
elsif respond_to?(:scoping)
|
23
23
|
scoping { @klass.send(:top, *args, &block) }
|
24
|
+
else
|
25
|
+
with_scope(self) { klass.send(:top, *args, &block) }
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Hightop
|
2
|
+
module Mongoid
|
3
|
+
# super helpful article
|
4
|
+
# https://maximomussini.com/posts/mongoid-aggregation-dsl/
|
5
|
+
def top(column, limit = nil, distinct: nil, uniq: nil, min: nil, nil: nil)
|
6
|
+
distinct ||= uniq
|
7
|
+
|
8
|
+
relation = all
|
9
|
+
|
10
|
+
# terribly named option
|
11
|
+
unless binding.local_variable_get(:nil)
|
12
|
+
(column.is_a?(Array) ? column : [column]).each do |c|
|
13
|
+
relation = relation.and(c.ne => nil)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
ids = {}
|
18
|
+
Array(column).each_with_index do |c, i|
|
19
|
+
ids["c#{i}"] = "$#{c}"
|
20
|
+
end
|
21
|
+
|
22
|
+
if distinct
|
23
|
+
# group with distinct column first, then group without it
|
24
|
+
# https://stackoverflow.com/questions/24761266/select-group-by-count-and-distinct-count-in-same-mongodb-query/24770233#24770233
|
25
|
+
distinct_ids = ids.merge("c#{ids.size}" => "$#{distinct}")
|
26
|
+
relation = relation.group(_id: distinct_ids, count: {"$sum" => 1})
|
27
|
+
ids.each_key do |k|
|
28
|
+
ids[k] = "$_id.#{k}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
relation = relation.group(_id: ids, count: {"$sum" => 1})
|
33
|
+
|
34
|
+
if min
|
35
|
+
relation.pipeline.push("$match" => {"count" => {"$gte" => min}})
|
36
|
+
end
|
37
|
+
|
38
|
+
relation = relation.desc(:count)
|
39
|
+
if limit
|
40
|
+
relation = relation.limit(limit)
|
41
|
+
end
|
42
|
+
|
43
|
+
result = {}
|
44
|
+
collection.aggregate(relation.pipeline).each do |doc|
|
45
|
+
key = doc["_id"].values
|
46
|
+
key = key[0] if key.size == 1
|
47
|
+
result[key] = doc["count"]
|
48
|
+
end
|
49
|
+
result
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/hightop/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hightop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/hightop.rb
|
93
93
|
- lib/hightop/enumerable.rb
|
94
94
|
- lib/hightop/kicks.rb
|
95
|
+
- lib/hightop/mongoid.rb
|
95
96
|
- lib/hightop/version.rb
|
96
97
|
homepage: https://github.com/ankane/hightop
|
97
98
|
licenses:
|