waistband 0.3.2 → 0.4.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/lib/waistband/free_query.rb +34 -0
- data/lib/waistband/query.rb +2 -35
- data/lib/waistband/query_helpers.rb +44 -0
- data/lib/waistband/version.rb +1 -1
- data/lib/waistband.rb +2 -0
- data/spec/config/waistband/waistband_geo.yml +19 -0
- data/spec/lib/free_query_spec.rb +161 -0
- data/spec/support/index_helper.rb +1 -1
- metadata +8 -2
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
+
|
3
|
+
module Waistband
|
4
|
+
class FreeQuery
|
5
|
+
|
6
|
+
include ::Waistband::QueryHelpers
|
7
|
+
|
8
|
+
attr_accessor :page, :page_size
|
9
|
+
|
10
|
+
def initialize(index, options = {})
|
11
|
+
@index = index
|
12
|
+
@page = (options[:page] || 1).to_i
|
13
|
+
@page_size = (options[:page_size] || 20).to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def prepare(hash)
|
17
|
+
@hash = hash.with_indifferent_access
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def to_hash
|
23
|
+
raise "No query has been prepared yet!" unless @hash
|
24
|
+
|
25
|
+
@hash[:from] = from unless @hash[:from]
|
26
|
+
@hash[:size] = @page_size unless @hash[:size]
|
27
|
+
|
28
|
+
@hash
|
29
|
+
end
|
30
|
+
|
31
|
+
# /private
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/waistband/query.rb
CHANGED
@@ -6,6 +6,8 @@ require 'kaminari/models/array_extension' if defined?(Kaminari)
|
|
6
6
|
module Waistband
|
7
7
|
class Query
|
8
8
|
|
9
|
+
include ::Waistband::QueryHelpers
|
10
|
+
|
9
11
|
attr_accessor :page, :page_size
|
10
12
|
|
11
13
|
def initialize(index, search_term, options = {})
|
@@ -22,25 +24,6 @@ module Waistband
|
|
22
24
|
@page_size = (options[:page_size] || 20).to_i
|
23
25
|
end
|
24
26
|
|
25
|
-
def paginated_results
|
26
|
-
return Kaminari.paginate_array(results, total_count: total_results).page(@page).per(@page_size) if defined?(Kaminari)
|
27
|
-
raise "Please include the `kaminari` gem to use this method!"
|
28
|
-
end
|
29
|
-
|
30
|
-
def results
|
31
|
-
hits.map do |hit|
|
32
|
-
Waistband::QueryResult.new(hit)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def hits
|
37
|
-
execute!['hits']['hits'] rescue []
|
38
|
-
end
|
39
|
-
|
40
|
-
def total_results
|
41
|
-
execute!['hits']['total'] rescue 0
|
42
|
-
end
|
43
|
-
|
44
27
|
def add_match(field)
|
45
28
|
@match = field
|
46
29
|
end
|
@@ -110,18 +93,6 @@ module Waistband
|
|
110
93
|
|
111
94
|
private
|
112
95
|
|
113
|
-
def url
|
114
|
-
index.search_url
|
115
|
-
end
|
116
|
-
|
117
|
-
def index
|
118
|
-
Waistband::Index.new(@index)
|
119
|
-
end
|
120
|
-
|
121
|
-
def execute!
|
122
|
-
@executed ||= JSON.parse(RestClient.post(url, to_hash.to_json))
|
123
|
-
end
|
124
|
-
|
125
96
|
def to_hash
|
126
97
|
{
|
127
98
|
query: {
|
@@ -211,10 +182,6 @@ module Waistband
|
|
211
182
|
end
|
212
183
|
end
|
213
184
|
|
214
|
-
def from
|
215
|
-
@page_size * (@page - 1)
|
216
|
-
end
|
217
|
-
|
218
185
|
def prep_words_uniquely(val)
|
219
186
|
val.to_s.gsub(/ +/, ' ').strip.split(' ').uniq
|
220
187
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Waistband
|
2
|
+
module QueryHelpers
|
3
|
+
|
4
|
+
def paginated_results
|
5
|
+
return Kaminari.paginate_array(results, total_count: total_results).page(@page).per(@page_size) if defined?(Kaminari)
|
6
|
+
raise "Please include the `kaminari` gem to use this method!"
|
7
|
+
end
|
8
|
+
|
9
|
+
def results
|
10
|
+
hits.map do |hit|
|
11
|
+
Waistband::QueryResult.new(hit)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def hits
|
16
|
+
execute!['hits']['hits'] rescue []
|
17
|
+
end
|
18
|
+
|
19
|
+
def total_results
|
20
|
+
execute!['hits']['total'] rescue 0
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def url
|
26
|
+
index.search_url
|
27
|
+
end
|
28
|
+
|
29
|
+
def index
|
30
|
+
Waistband::Index.new(@index)
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute!
|
34
|
+
JSON.parse(RestClient.post(url, to_hash.to_json))
|
35
|
+
end
|
36
|
+
|
37
|
+
def from
|
38
|
+
@page_size * (@page - 1)
|
39
|
+
end
|
40
|
+
|
41
|
+
# /private
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/lib/waistband/version.rb
CHANGED
data/lib/waistband.rb
CHANGED
@@ -7,7 +7,9 @@ module Waistband
|
|
7
7
|
autoload :StringifiedArray, "waistband/stringified_array"
|
8
8
|
autoload :StringifiedHash, "waistband/stringified_hash"
|
9
9
|
autoload :QueryResult, "waistband/query_result"
|
10
|
+
autoload :QueryHelpers, "waistband/query_helpers"
|
10
11
|
autoload :Query, "waistband/query"
|
12
|
+
autoload :FreeQuery, "waistband/free_query"
|
11
13
|
autoload :Index, "waistband/index"
|
12
14
|
autoload :QuickError, "waistband/quick_error"
|
13
15
|
autoload :Model, "waistband/model"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
development: &DEV
|
2
|
+
name: waistband_geo
|
3
|
+
stringify: false
|
4
|
+
settings:
|
5
|
+
index:
|
6
|
+
number_of_shards: 4
|
7
|
+
mappings:
|
8
|
+
geo:
|
9
|
+
_source:
|
10
|
+
includes: ["*"]
|
11
|
+
properties:
|
12
|
+
work_area:
|
13
|
+
type: geo_shape
|
14
|
+
tree: geohash
|
15
|
+
precision: 5m
|
16
|
+
|
17
|
+
test:
|
18
|
+
<<: *DEV
|
19
|
+
name: waistband_geo_test
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Waistband::FreeQuery do
|
4
|
+
|
5
|
+
let(:index) { Waistband::Index.new('search') }
|
6
|
+
let(:geo_index) { Waistband::Index.new('geo') }
|
7
|
+
|
8
|
+
let(:query) { Waistband::FreeQuery.new('search') }
|
9
|
+
let(:geo_query) { Waistband::FreeQuery.new('geo') }
|
10
|
+
|
11
|
+
let(:attrs) do
|
12
|
+
{
|
13
|
+
'query' => {
|
14
|
+
'bool' => {
|
15
|
+
'must' => [
|
16
|
+
{
|
17
|
+
'multi_match' => {
|
18
|
+
'query' => "shopping ikea",
|
19
|
+
'fields' => ['name']
|
20
|
+
},
|
21
|
+
}
|
22
|
+
]
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "correclty forms a query hash" do
|
29
|
+
add_result!
|
30
|
+
query.prepare(attrs)
|
31
|
+
|
32
|
+
expect(query.instance_variable_get('@hash')).to eql(attrs)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "finds results for a free query" do
|
36
|
+
add_result!
|
37
|
+
query.prepare(attrs)
|
38
|
+
json = query.send(:execute!)
|
39
|
+
|
40
|
+
json['hits'].should be_a Hash
|
41
|
+
json['hits']['total'].should > 0
|
42
|
+
json['hits']['hits'].size.should eql 2
|
43
|
+
|
44
|
+
hit = json['hits']['hits'].first
|
45
|
+
|
46
|
+
hit['_id'].should match(/^task_.*/)
|
47
|
+
hit['_source'].should be_a Hash
|
48
|
+
hit['_source']['id'].should eql 123123
|
49
|
+
hit['_source']['name'].should eql 'some shopping in ikea'
|
50
|
+
hit['_source']['user_id'].should eql 999
|
51
|
+
hit['_source']['description'].should eql 'i need you to pick up some stuff in ikea'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "permits storing and fetching geo results" do
|
55
|
+
add_geo_results!
|
56
|
+
geo_query.prepare({
|
57
|
+
"query" => {
|
58
|
+
"filtered" => {
|
59
|
+
"query" => { "match_all" => {} },
|
60
|
+
"filter" => {
|
61
|
+
"geo_shape" => {
|
62
|
+
"work_area" => {
|
63
|
+
"relation" => "intersects",
|
64
|
+
"shape" => {
|
65
|
+
"type" => "Point",
|
66
|
+
"coordinates" => [-122.39455,37.7841]
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
})
|
74
|
+
|
75
|
+
json = geo_query.send(:execute!)
|
76
|
+
|
77
|
+
json['hits'].should be_a Hash
|
78
|
+
json['hits']['total'].should eql 3
|
79
|
+
json['hits']['hits'].size.should eql 3
|
80
|
+
|
81
|
+
geo_query.prepare({
|
82
|
+
"query" => {
|
83
|
+
"filtered" => {
|
84
|
+
"query" => { "match_all" => {} },
|
85
|
+
"filter" => {
|
86
|
+
"geo_shape" => {
|
87
|
+
"work_area" => {
|
88
|
+
"relation" => "intersects",
|
89
|
+
"shape" => {
|
90
|
+
"type" => "Point",
|
91
|
+
"coordinates" => [-122.3859222222222,37.78292222222222]
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
})
|
99
|
+
|
100
|
+
json = geo_query.send(:execute!)
|
101
|
+
|
102
|
+
json['hits'].should be_a Hash
|
103
|
+
json['hits']['total'].should eql 1
|
104
|
+
json['hits']['hits'].size.should eql 1
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_result!
|
108
|
+
index.store!("task_123123", {id: 123123, name: 'some shopping in ikea', user_id: 999, description: 'i need you to pick up some stuff in ikea', internal: false})
|
109
|
+
index.store!("task_234234", {id: 234234, name: "some shopping in ikea and trader joe's", user_id: 987, description: 'pick me up some eggs', internal: true})
|
110
|
+
index.refresh
|
111
|
+
end
|
112
|
+
|
113
|
+
def add_geo_results!
|
114
|
+
geo_index.store!("rabbit_1", {
|
115
|
+
id: "rabbit_1",
|
116
|
+
work_area: {
|
117
|
+
type: 'polygon',
|
118
|
+
coordinates: [[
|
119
|
+
[-122.4119,37.78211],
|
120
|
+
[-122.39285,37.79649],
|
121
|
+
[-122.37997,37.78415],
|
122
|
+
[-122.39817,37.77248],
|
123
|
+
[-122.40932,37.77302],
|
124
|
+
[-122.4119,37.78211]
|
125
|
+
]]
|
126
|
+
}
|
127
|
+
})
|
128
|
+
|
129
|
+
geo_index.store!("rabbit_2", {
|
130
|
+
id: "rabbit_2",
|
131
|
+
work_area: {
|
132
|
+
type: 'polygon',
|
133
|
+
coordinates: [[
|
134
|
+
[-122.41087,37.78822],
|
135
|
+
[-122.43174,37.78578],
|
136
|
+
[-122.42816,37.75938],
|
137
|
+
[-122.38787,37.76882],
|
138
|
+
[-122.39199,37.78584],
|
139
|
+
[-122.41087,37.78822]
|
140
|
+
]]
|
141
|
+
}
|
142
|
+
})
|
143
|
+
|
144
|
+
geo_index.store!("rabbit_3", {
|
145
|
+
id: "rabbit_3",
|
146
|
+
work_area: {
|
147
|
+
type: 'polygon',
|
148
|
+
coordinates: [[
|
149
|
+
[-122.41997,37.79744],
|
150
|
+
[-122.39576,37.79975],
|
151
|
+
[-122.38461,37.78469],
|
152
|
+
[-122.40294,37.77738],
|
153
|
+
[-122.41997,37.79744]
|
154
|
+
]]
|
155
|
+
}
|
156
|
+
})
|
157
|
+
|
158
|
+
geo_index.refresh
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: waistband
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -109,9 +109,11 @@ files:
|
|
109
109
|
- lib/waistband.rb
|
110
110
|
- lib/waistband/configuration.rb
|
111
111
|
- lib/waistband/connection.rb
|
112
|
+
- lib/waistband/free_query.rb
|
112
113
|
- lib/waistband/index.rb
|
113
114
|
- lib/waistband/model.rb
|
114
115
|
- lib/waistband/query.rb
|
116
|
+
- lib/waistband/query_helpers.rb
|
115
117
|
- lib/waistband/query_result.rb
|
116
118
|
- lib/waistband/quick_error.rb
|
117
119
|
- lib/waistband/stringified_array.rb
|
@@ -119,9 +121,11 @@ files:
|
|
119
121
|
- lib/waistband/version.rb
|
120
122
|
- spec/config/waistband/waistband.yml
|
121
123
|
- spec/config/waistband/waistband_events.yml
|
124
|
+
- spec/config/waistband/waistband_geo.yml
|
122
125
|
- spec/config/waistband/waistband_search.yml
|
123
126
|
- spec/lib/configuration_spec.rb
|
124
127
|
- spec/lib/connection_spec.rb
|
128
|
+
- spec/lib/free_query_spec.rb
|
125
129
|
- spec/lib/index_spec.rb
|
126
130
|
- spec/lib/model_spec.rb
|
127
131
|
- spec/lib/query_result_spec.rb
|
@@ -159,9 +163,11 @@ summary: Elastic Search all the things!
|
|
159
163
|
test_files:
|
160
164
|
- spec/config/waistband/waistband.yml
|
161
165
|
- spec/config/waistband/waistband_events.yml
|
166
|
+
- spec/config/waistband/waistband_geo.yml
|
162
167
|
- spec/config/waistband/waistband_search.yml
|
163
168
|
- spec/lib/configuration_spec.rb
|
164
169
|
- spec/lib/connection_spec.rb
|
170
|
+
- spec/lib/free_query_spec.rb
|
165
171
|
- spec/lib/index_spec.rb
|
166
172
|
- spec/lib/model_spec.rb
|
167
173
|
- spec/lib/query_result_spec.rb
|