waistband 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Waistband
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
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
@@ -1,6 +1,6 @@
1
1
  class IndexHelper
2
2
 
3
- INDEXES = %w(events search)
3
+ INDEXES = %w(events search geo)
4
4
 
5
5
  class << self
6
6
 
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.3.2
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-09-23 00:00:00.000000000 Z
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