waistband 0.4.2 → 0.7.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.rb +0 -1
- data/lib/waistband/index.rb +2 -6
- data/lib/waistband/query.rb +12 -169
- data/lib/waistband/version.rb +1 -1
- data/spec/lib/index_spec.rb +1 -5
- data/spec/lib/query_spec.rb +130 -342
- metadata +2 -8
- data/lib/waistband/free_query.rb +0 -34
- data/lib/waistband/model.rb +0 -215
- data/spec/lib/free_query_spec.rb +0 -161
- data/spec/lib/model_spec.rb +0 -217
data/lib/waistband.rb
CHANGED
@@ -9,7 +9,6 @@ module Waistband
|
|
9
9
|
autoload :QueryResult, "waistband/query_result"
|
10
10
|
autoload :QueryHelpers, "waistband/query_helpers"
|
11
11
|
autoload :Query, "waistband/query"
|
12
|
-
autoload :FreeQuery, "waistband/free_query"
|
13
12
|
autoload :Index, "waistband/index"
|
14
13
|
autoload :QuickError, "waistband/quick_error"
|
15
14
|
autoload :Model, "waistband/model"
|
data/lib/waistband/index.rb
CHANGED
@@ -54,12 +54,8 @@ module Waistband
|
|
54
54
|
connection.read @index, key
|
55
55
|
end
|
56
56
|
|
57
|
-
def query(
|
58
|
-
::Waistband::Query.new @index,
|
59
|
-
end
|
60
|
-
|
61
|
-
def free_query(options = {})
|
62
|
-
::Waistband::FreeQuery.new @index, options
|
57
|
+
def query(options = {})
|
58
|
+
::Waistband::Query.new @index, options
|
63
59
|
end
|
64
60
|
|
65
61
|
def search_url
|
data/lib/waistband/query.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'rest-client'
|
3
|
-
require 'active_support/core_ext/object/blank'
|
4
|
-
require 'kaminari/models/array_extension' if defined?(Kaminari)
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
5
2
|
|
6
3
|
module Waistband
|
7
4
|
class Query
|
@@ -10,180 +7,26 @@ module Waistband
|
|
10
7
|
|
11
8
|
attr_accessor :page, :page_size
|
12
9
|
|
13
|
-
def initialize(index,
|
14
|
-
@index
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@fields = []
|
18
|
-
@ranges = []
|
19
|
-
@sorts = []
|
20
|
-
@terms = {}
|
21
|
-
@exclude_terms = {}
|
22
|
-
@optional_terms = {}
|
23
|
-
@page = (options[:page] || 1).to_i
|
24
|
-
@page_size = (options[:page_size] || 20).to_i
|
10
|
+
def initialize(index, options = {})
|
11
|
+
@index = index
|
12
|
+
@page = (options[:page] || 1).to_i
|
13
|
+
@page_size = (options[:page_size] || 20).to_i
|
25
14
|
end
|
26
15
|
|
27
|
-
def
|
28
|
-
@
|
29
|
-
|
30
|
-
|
31
|
-
def add_fields(*fields)
|
32
|
-
@fields |= fields
|
33
|
-
@fields = @fields.compact.uniq
|
34
|
-
end
|
35
|
-
alias :add_field :add_fields
|
36
|
-
|
37
|
-
def add_wildcard(wildcard, value)
|
38
|
-
@wildcards << {
|
39
|
-
wildcard: wildcard,
|
40
|
-
value: value
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
def add_range(field, min, max)
|
45
|
-
@ranges << {
|
46
|
-
field: field,
|
47
|
-
min: min,
|
48
|
-
max: max
|
49
|
-
}
|
50
|
-
end
|
51
|
-
|
52
|
-
def add_terms(key, words)
|
53
|
-
@terms[key] ||= {
|
54
|
-
keywords: []
|
55
|
-
}
|
56
|
-
@terms[key][:keywords] += prep_words_uniquely(words)
|
57
|
-
end
|
58
|
-
alias :add_term :add_terms
|
59
|
-
|
60
|
-
def add_exclude_terms(key, words)
|
61
|
-
@exclude_terms[key] ||= {
|
62
|
-
keywords: []
|
63
|
-
}
|
64
|
-
@exclude_terms[key][:keywords] += prep_words_uniquely(words)
|
65
|
-
end
|
66
|
-
alias :add_exclude_term :add_exclude_terms
|
67
|
-
|
68
|
-
def add_optional_terms(key, words)
|
69
|
-
@optional_terms[key] ||= {
|
70
|
-
keywords: []
|
71
|
-
}
|
72
|
-
@optional_terms[key][:keywords] += prep_words_uniquely(words)
|
73
|
-
end
|
74
|
-
alias :add_optional_term :add_optional_terms
|
75
|
-
|
76
|
-
def add_sort(key, ord)
|
77
|
-
@sorts << {
|
78
|
-
key: key,
|
79
|
-
ord: ord
|
80
|
-
}
|
81
|
-
end
|
82
|
-
|
83
|
-
def add_random_sort
|
84
|
-
@random_sort = {
|
85
|
-
_script: {
|
86
|
-
script: "Math.random()",
|
87
|
-
type: :number,
|
88
|
-
params: {},
|
89
|
-
order: :asc
|
90
|
-
}
|
91
|
-
}
|
16
|
+
def prepare(hash)
|
17
|
+
@hash = hash.with_indifferent_access
|
18
|
+
self
|
92
19
|
end
|
93
20
|
|
94
21
|
private
|
95
22
|
|
96
23
|
def to_hash
|
97
|
-
|
98
|
-
query: {
|
99
|
-
bool: {
|
100
|
-
must: must_to_hash,
|
101
|
-
must_not: must_not_to_hash,
|
102
|
-
should: should_to_hash
|
103
|
-
}
|
104
|
-
},
|
105
|
-
from: from,
|
106
|
-
size: @page_size,
|
107
|
-
sort: sort_to_hash
|
108
|
-
}
|
109
|
-
end
|
110
|
-
|
111
|
-
def sort_to_hash
|
112
|
-
return @random_sort if @random_sort
|
24
|
+
raise "No query has been prepared yet!" unless @hash
|
113
25
|
|
114
|
-
|
115
|
-
|
116
|
-
@sorts.each do |s|
|
117
|
-
sort << {s[:key] => s[:ord]}
|
118
|
-
end
|
119
|
-
|
120
|
-
sort << '_score'
|
121
|
-
|
122
|
-
sort
|
123
|
-
end
|
124
|
-
|
125
|
-
def must_to_hash
|
126
|
-
must = []
|
127
|
-
|
128
|
-
must << {
|
129
|
-
multi_match: {
|
130
|
-
query: @search_term,
|
131
|
-
fields: @fields
|
132
|
-
}
|
133
|
-
} if @fields.any?
|
134
|
-
|
135
|
-
@wildcards.each do |wc|
|
136
|
-
must << {
|
137
|
-
wildcard: {
|
138
|
-
wc[:wildcard] => wc[:value]
|
139
|
-
}
|
140
|
-
}
|
141
|
-
end
|
142
|
-
|
143
|
-
@ranges.each do |range|
|
144
|
-
must << {
|
145
|
-
range: {
|
146
|
-
range[:field] => {
|
147
|
-
lte: range[:max],
|
148
|
-
gte: range[:min],
|
149
|
-
}
|
150
|
-
}
|
151
|
-
}
|
152
|
-
end
|
153
|
-
|
154
|
-
must << {
|
155
|
-
match: {
|
156
|
-
@match => @search_term
|
157
|
-
}
|
158
|
-
} if @match.present?
|
159
|
-
|
160
|
-
prep_term_hash(@terms).each do |term|
|
161
|
-
must << term
|
162
|
-
end
|
163
|
-
|
164
|
-
must
|
165
|
-
end
|
166
|
-
|
167
|
-
def must_not_to_hash
|
168
|
-
prep_term_hash(@exclude_terms).map { |term| term }
|
169
|
-
end
|
170
|
-
|
171
|
-
def should_to_hash
|
172
|
-
prep_term_hash(@optional_terms).map { |term| term }
|
173
|
-
end
|
174
|
-
|
175
|
-
def prep_term_hash(terms)
|
176
|
-
terms.map do |key, term|
|
177
|
-
{
|
178
|
-
terms: {
|
179
|
-
key.to_sym => term[:keywords]
|
180
|
-
}
|
181
|
-
}
|
182
|
-
end
|
183
|
-
end
|
26
|
+
@hash[:from] = from unless @hash[:from]
|
27
|
+
@hash[:size] = @page_size unless @hash[:size]
|
184
28
|
|
185
|
-
|
186
|
-
val.to_s.gsub(/ +/, ' ').strip.split(' ').uniq
|
29
|
+
@hash
|
187
30
|
end
|
188
31
|
|
189
32
|
# /private
|
data/lib/waistband/version.rb
CHANGED
data/spec/lib/index_spec.rb
CHANGED
@@ -32,11 +32,7 @@ describe Waistband::Index do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it "proxies to a query" do
|
35
|
-
index.query
|
36
|
-
end
|
37
|
-
|
38
|
-
it "proxies to a free query" do
|
39
|
-
index.free_query.should be_a Waistband::FreeQuery
|
35
|
+
index.query.should be_a Waistband::Query
|
40
36
|
end
|
41
37
|
|
42
38
|
describe "storing" do
|
data/spec/lib/query_spec.rb
CHANGED
@@ -1,373 +1,161 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_support/core_ext/kernel/reporting'
|
3
|
-
|
4
|
-
Kernel.silence_stderr do
|
5
|
-
require 'kaminari'
|
6
|
-
end
|
7
2
|
|
8
3
|
describe Waistband::Query do
|
9
4
|
|
10
|
-
let(:index)
|
11
|
-
let(:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
hit['_source']['id'].should eql 123123
|
29
|
-
hit['_source']['name'].should eql 'some shopping in ikea'
|
30
|
-
hit['_source']['user_id'].should eql 999
|
31
|
-
hit['_source']['description'].should eql 'i need you to pick up some stuff in ikea'
|
32
|
-
end
|
33
|
-
|
34
|
-
it "boosts results with optional terms" do
|
35
|
-
query = index.query('shopping ikea')
|
36
|
-
query.add_field('name')
|
37
|
-
query.add_optional_term('internal', 'true')
|
38
|
-
|
39
|
-
json = query.send(:execute!)
|
40
|
-
|
41
|
-
json['hits']['hits'].size.should eql 2
|
42
|
-
|
43
|
-
hit = json['hits']['hits'].first
|
44
|
-
|
45
|
-
hit['_id'].should match(/^task_.*/)
|
46
|
-
hit['_source'].should be_a Hash
|
47
|
-
hit['_source']['id'].should eql 234234
|
48
|
-
hit['_source']['name'].should eql "some shopping in ikea and trader joe's"
|
49
|
-
hit['_source']['user_id'].should eql 987
|
50
|
-
hit['_source']['description'].should eql 'pick me up some eggs'
|
51
|
-
end
|
52
|
-
|
53
|
-
it "excludes results" do
|
54
|
-
query = index.query('shopping ikea')
|
55
|
-
query.add_field('name')
|
56
|
-
query.add_exclude_term('internal', 'true')
|
57
|
-
|
58
|
-
json = query.send(:execute!)
|
59
|
-
|
60
|
-
json['hits']['hits'].size.should eql 1
|
61
|
-
|
62
|
-
hit = json['hits']['hits'].first
|
63
|
-
|
64
|
-
hit['_id'].should match(/^task_.*/)
|
65
|
-
hit['_source'].should be_a Hash
|
66
|
-
hit['_source']['id'].should eql 123123
|
67
|
-
hit['_source']['name'].should eql 'some shopping in ikea'
|
68
|
-
hit['_source']['user_id'].should eql 999
|
69
|
-
hit['_source']['description'].should eql 'i need you to pick up some stuff in ikea'
|
70
|
-
hit['_source']['internal'].should be_false
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
describe '#add_sort' do
|
76
|
-
|
77
|
-
it "adds sort field" do
|
78
|
-
query.add_sort('created_at', 'asc')
|
79
|
-
query.instance_variable_get('@sorts').should eql [{key: 'created_at', ord: 'asc'}]
|
80
|
-
|
81
|
-
query.add_sort('updated_at', 'desc')
|
82
|
-
query.instance_variable_get('@sorts').should eql [{key: 'created_at', ord: 'asc'}, {key: 'updated_at', ord: 'desc'}]
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
describe '#add_random_sort' do
|
88
|
-
|
89
|
-
it "sets the correct instance variables" do
|
90
|
-
query.add_random_sort
|
91
|
-
|
92
|
-
query.instance_variable_get('@random_sort').should eql({
|
93
|
-
_script: {
|
94
|
-
script: "Math.random()",
|
95
|
-
type: :number,
|
96
|
-
params: {},
|
97
|
-
order: :asc
|
98
|
-
}
|
99
|
-
})
|
100
|
-
|
101
|
-
query.send(:sort_to_hash).should eql({
|
102
|
-
_script: {
|
103
|
-
script: "Math.random()",
|
104
|
-
type: :number,
|
105
|
-
params: {},
|
106
|
-
order: :asc
|
5
|
+
let(:index) { Waistband::Index.new('search') }
|
6
|
+
let(:geo_index) { Waistband::Index.new('geo') }
|
7
|
+
|
8
|
+
let(:query) { Waistband::Query.new('search') }
|
9
|
+
let(:geo_query) { Waistband::Query.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
|
+
]
|
107
23
|
}
|
108
|
-
}
|
109
|
-
|
110
|
-
|
111
|
-
it "sorts restuls randomly" do
|
112
|
-
add_result!
|
113
|
-
|
114
|
-
query = index.query('shopping ikea')
|
115
|
-
|
116
|
-
query.add_field('name')
|
117
|
-
query.add_random_sort
|
118
|
-
|
119
|
-
query.results.size.should eql 2
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
describe '#add_range' do
|
125
|
-
|
126
|
-
it "adds a range" do
|
127
|
-
query.add_range('task_id', 5, 10)
|
128
|
-
query.instance_variable_get('@ranges').should eql [{field: 'task_id', min: 5, max: 10}]
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
132
|
-
|
133
|
-
describe '#add_field' do
|
134
|
-
|
135
|
-
it "adds field" do
|
136
|
-
query.add_field('name')
|
137
|
-
query.instance_variable_get('@fields').should eql ['name']
|
138
|
-
end
|
139
|
-
|
140
|
-
it "adds multiple fields at once" do
|
141
|
-
query.add_field('name', 'description')
|
142
|
-
query.instance_variable_get('@fields').should eql ['name', 'description']
|
143
|
-
end
|
144
|
-
|
24
|
+
}
|
25
|
+
}
|
145
26
|
end
|
146
27
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
query.add_term('metro', 'boston')
|
151
|
-
query.instance_variable_get('@terms')['metro'][:keywords].should eql ['boston']
|
152
|
-
end
|
153
|
-
|
154
|
-
it "adds several terms on multiple words" do
|
155
|
-
query.add_term('metro', 'sf bay area')
|
156
|
-
query.instance_variable_get('@terms')['metro'][:keywords].should eql ['sf', 'bay', 'area']
|
157
|
-
end
|
28
|
+
it "correclty forms a query hash" do
|
29
|
+
add_result!
|
30
|
+
query.prepare(attrs)
|
158
31
|
|
32
|
+
expect(query.instance_variable_get('@hash')).to eql(attrs)
|
159
33
|
end
|
160
34
|
|
161
|
-
|
35
|
+
it "finds results for a query" do
|
36
|
+
add_result!
|
37
|
+
query.prepare(attrs)
|
38
|
+
json = query.send(:execute!)
|
162
39
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
end
|
40
|
+
json['hits'].should be_a Hash
|
41
|
+
json['hits']['total'].should > 0
|
42
|
+
json['hits']['hits'].size.should eql 2
|
167
43
|
|
168
|
-
|
169
|
-
query.add_exclude_term('metro', 'sf bay area')
|
170
|
-
query.instance_variable_get('@exclude_terms')['metro'][:keywords].should eql ['sf', 'bay', 'area']
|
171
|
-
end
|
44
|
+
hit = json['hits']['hits'].first
|
172
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'
|
173
52
|
end
|
174
53
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
query
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
it "creates an array of the must of the query" do
|
192
|
-
query.add_term('metro', 'sf bay area')
|
193
|
-
query.add_field('name')
|
194
|
-
query.send(:must_to_hash).should eql([
|
195
|
-
{
|
196
|
-
multi_match: {
|
197
|
-
query: "shopping ikea",
|
198
|
-
fields: ['name']
|
199
|
-
}
|
200
|
-
},
|
201
|
-
{
|
202
|
-
terms: {
|
203
|
-
metro: ["sf", "bay", "area"]
|
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
|
+
}
|
204
70
|
}
|
205
71
|
}
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
query
|
217
|
-
{
|
218
|
-
|
219
|
-
|
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
|
+
}
|
220
95
|
}
|
221
96
|
}
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
end
|
226
|
-
|
227
|
-
describe '#from' do
|
228
|
-
|
229
|
-
it "returns 0 when page is 1" do
|
230
|
-
Waistband::Query.new('search', 'shopping ikea', page: 1, page_size: 20).send(:from).should eql 0
|
231
|
-
end
|
232
|
-
|
233
|
-
it "returns 20 when page is 2 and page_size is 20" do
|
234
|
-
Waistband::Query.new('search', 'shopping ikea', page: 2, page_size: 20).send(:from).should eql 20
|
235
|
-
end
|
236
|
-
|
237
|
-
it "returns 30 when page is 4 and page_size is 10" do
|
238
|
-
Waistband::Query.new('search', 'shopping ikea', page: 4, page_size: 10).send(:from).should eql 30
|
239
|
-
end
|
240
|
-
|
241
|
-
it "returns 10 when page is 2 and page_size is 10" do
|
242
|
-
Waistband::Query.new('search', 'shopping ikea', page: 2, page_size: 10).send(:from).should eql 10
|
243
|
-
end
|
97
|
+
}
|
98
|
+
})
|
244
99
|
|
245
|
-
|
246
|
-
|
247
|
-
describe '#to_hash' do
|
248
|
-
|
249
|
-
it "constructs the query's json" do
|
250
|
-
query.add_term('metro', 'sf bay area')
|
251
|
-
query.add_field('name')
|
252
|
-
query.add_sort('created_at', 'desc')
|
253
|
-
query.add_range('task_id', 1, 10)
|
254
|
-
|
255
|
-
query.send(:to_hash).should eql({
|
256
|
-
query: {
|
257
|
-
bool: {
|
258
|
-
must: [
|
259
|
-
{
|
260
|
-
multi_match: {
|
261
|
-
query: "shopping ikea",
|
262
|
-
fields: ['name']
|
263
|
-
},
|
264
|
-
},
|
265
|
-
{
|
266
|
-
range: {
|
267
|
-
'task_id' => {
|
268
|
-
lte: 10,
|
269
|
-
gte: 1
|
270
|
-
}
|
271
|
-
}
|
272
|
-
},
|
273
|
-
{
|
274
|
-
terms: {
|
275
|
-
metro: ["sf","bay","area"]
|
276
|
-
}
|
277
|
-
}
|
278
|
-
],
|
279
|
-
must_not: [],
|
280
|
-
should: []
|
281
|
-
}
|
282
|
-
},
|
283
|
-
from: 0,
|
284
|
-
size: 20,
|
285
|
-
sort: [
|
286
|
-
{'created_at' => 'desc'},
|
287
|
-
'_score'
|
288
|
-
]
|
289
|
-
})
|
290
|
-
end
|
291
|
-
|
292
|
-
it 'constructs the query with several terms' do
|
293
|
-
query.add_term('metro', 'sf bay area')
|
294
|
-
query.add_term('geography', 'San Francisco')
|
295
|
-
query.add_optional_term('internal', 'true')
|
296
|
-
query.add_exclude_term('user_id', '999')
|
297
|
-
query.add_field('name')
|
298
|
-
query.add_field('description')
|
299
|
-
|
300
|
-
query.send(:to_hash).should eql({
|
301
|
-
query: {
|
302
|
-
bool: {
|
303
|
-
must: [
|
304
|
-
{
|
305
|
-
multi_match: {
|
306
|
-
query: "shopping ikea",
|
307
|
-
fields: ['name', 'description']
|
308
|
-
}
|
309
|
-
},
|
310
|
-
{
|
311
|
-
terms: {
|
312
|
-
metro: ["sf", "bay", "area"]
|
313
|
-
}
|
314
|
-
},
|
315
|
-
{
|
316
|
-
terms: {
|
317
|
-
geography: ["San", "Francisco"]
|
318
|
-
}
|
319
|
-
}
|
320
|
-
],
|
321
|
-
must_not: [
|
322
|
-
{
|
323
|
-
terms: {
|
324
|
-
user_id: ['999']
|
325
|
-
}
|
326
|
-
}
|
327
|
-
],
|
328
|
-
should: [
|
329
|
-
{
|
330
|
-
terms: {
|
331
|
-
internal: ['true']
|
332
|
-
}
|
333
|
-
}
|
334
|
-
]
|
335
|
-
}
|
336
|
-
},
|
337
|
-
from: 0,
|
338
|
-
size: 20,
|
339
|
-
sort: ['_score']
|
340
|
-
})
|
341
|
-
end
|
342
|
-
|
343
|
-
end
|
344
|
-
|
345
|
-
describe '#results' do
|
346
|
-
|
347
|
-
it "returns a QueryResult array" do
|
348
|
-
add_result!
|
349
|
-
|
350
|
-
query.results.first.should be_a Waistband::QueryResult
|
351
|
-
end
|
352
|
-
|
353
|
-
end
|
354
|
-
|
355
|
-
describe '#paginated_results' do
|
356
|
-
|
357
|
-
it "returns a kaminari paginated array" do
|
358
|
-
add_result!
|
359
|
-
|
360
|
-
query.paginated_results.should be_an Array
|
361
|
-
end
|
100
|
+
json = geo_query.send(:execute!)
|
362
101
|
|
102
|
+
json['hits'].should be_a Hash
|
103
|
+
json['hits']['total'].should eql 1
|
104
|
+
json['hits']['hits'].size.should eql 1
|
363
105
|
end
|
364
106
|
|
365
107
|
def add_result!
|
366
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})
|
367
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})
|
368
110
|
index.refresh
|
111
|
+
end
|
369
112
|
|
370
|
-
|
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
|
371
159
|
end
|
372
160
|
|
373
161
|
end
|