waistband 0.2.0 → 0.2.1
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/README.md +1 -0
- data/lib/waistband/query.rb +45 -12
- data/lib/waistband/version.rb +1 -1
- data/spec/lib/query_spec.rb +56 -14
- metadata +23 -11
- checksums.yaml +0 -7
data/README.md
CHANGED
|
@@ -145,6 +145,7 @@ index = Waistband::Index.new('search')
|
|
|
145
145
|
query = index.query('shopping')
|
|
146
146
|
query.add_fields('name', 'description') # look for the search term `shopping` in the attributes `name` and `description`
|
|
147
147
|
query.add_term('task', 'true') # only in documents where the attribute task is set to true
|
|
148
|
+
query.add_optiona_term('task', 'true') # prefers documents where the attribute task is set to true
|
|
148
149
|
|
|
149
150
|
query.results # => returns an array of Waistband::QueryResult
|
|
150
151
|
|
data/lib/waistband/query.rb
CHANGED
|
@@ -9,15 +9,16 @@ module Waistband
|
|
|
9
9
|
attr_accessor :page, :page_size
|
|
10
10
|
|
|
11
11
|
def initialize(index, search_term, options = {})
|
|
12
|
-
@index
|
|
13
|
-
@search_term
|
|
14
|
-
@wildcards
|
|
15
|
-
@fields
|
|
16
|
-
@ranges
|
|
17
|
-
@sorts
|
|
18
|
-
@terms
|
|
19
|
-
@
|
|
20
|
-
@
|
|
12
|
+
@index = index
|
|
13
|
+
@search_term = search_term
|
|
14
|
+
@wildcards = []
|
|
15
|
+
@fields = []
|
|
16
|
+
@ranges = []
|
|
17
|
+
@sorts = []
|
|
18
|
+
@terms = {}
|
|
19
|
+
@optional_terms = {}
|
|
20
|
+
@page = (options[:page] || 1).to_i
|
|
21
|
+
@page_size = (options[:page_size] || 20).to_i
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def paginated_results
|
|
@@ -68,10 +69,18 @@ module Waistband
|
|
|
68
69
|
@terms[key] ||= {
|
|
69
70
|
keywords: []
|
|
70
71
|
}
|
|
71
|
-
@terms[key][:keywords] += words
|
|
72
|
+
@terms[key][:keywords] += prep_words_uniquely(words)
|
|
72
73
|
end
|
|
73
74
|
alias :add_term :add_terms
|
|
74
75
|
|
|
76
|
+
def add_optional_terms(key, words)
|
|
77
|
+
@optional_terms[key] ||= {
|
|
78
|
+
keywords: []
|
|
79
|
+
}
|
|
80
|
+
@optional_terms[key][:keywords] += prep_words_uniquely(words)
|
|
81
|
+
end
|
|
82
|
+
alias :add_optional_term :add_optional_terms
|
|
83
|
+
|
|
75
84
|
def add_sort(key, ord)
|
|
76
85
|
@sorts << {
|
|
77
86
|
key: key,
|
|
@@ -93,9 +102,9 @@ module Waistband
|
|
|
93
102
|
{
|
|
94
103
|
query: {
|
|
95
104
|
bool: {
|
|
96
|
-
must:
|
|
105
|
+
must: must_to_hash,
|
|
97
106
|
must_not: [],
|
|
98
|
-
should:
|
|
107
|
+
should: should_to_hash
|
|
99
108
|
}
|
|
100
109
|
},
|
|
101
110
|
from: from,
|
|
@@ -158,6 +167,16 @@ module Waistband
|
|
|
158
167
|
must
|
|
159
168
|
end
|
|
160
169
|
|
|
170
|
+
def should_to_hash
|
|
171
|
+
should = []
|
|
172
|
+
|
|
173
|
+
optional_terms.each do |term|
|
|
174
|
+
should << term
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
should
|
|
178
|
+
end
|
|
179
|
+
|
|
161
180
|
def terms
|
|
162
181
|
@terms.map do |key, term|
|
|
163
182
|
{
|
|
@@ -168,10 +187,24 @@ module Waistband
|
|
|
168
187
|
end
|
|
169
188
|
end
|
|
170
189
|
|
|
190
|
+
def optional_terms
|
|
191
|
+
@optional_terms.map do |key, term|
|
|
192
|
+
{
|
|
193
|
+
terms: {
|
|
194
|
+
key.to_sym => term[:keywords]
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
171
200
|
def from
|
|
172
201
|
@page_size * (@page - 1)
|
|
173
202
|
end
|
|
174
203
|
|
|
204
|
+
def prep_words_uniquely(str)
|
|
205
|
+
str.gsub(/ +/, ' ').strip.split(' ').uniq
|
|
206
|
+
end
|
|
207
|
+
|
|
175
208
|
# /private
|
|
176
209
|
|
|
177
210
|
end
|
data/lib/waistband/version.rb
CHANGED
data/spec/lib/query_spec.rb
CHANGED
|
@@ -12,22 +12,42 @@ describe Waistband::Query do
|
|
|
12
12
|
|
|
13
13
|
describe '#execute!' do
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
add_result!
|
|
15
|
+
before { add_result! }
|
|
17
16
|
|
|
17
|
+
it "gets results from elastic search" do
|
|
18
18
|
json = query.send(:execute!)
|
|
19
|
+
|
|
19
20
|
json['hits'].should be_a Hash
|
|
20
21
|
json['hits']['total'].should > 0
|
|
21
|
-
json['hits']['hits'].size.should eql
|
|
22
|
-
|
|
23
|
-
json['hits']['hits'].
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
json['hits']['hits'].size.should eql 2
|
|
23
|
+
|
|
24
|
+
hit = json['hits']['hits'].first
|
|
25
|
+
|
|
26
|
+
hit['_id'].should match(/^task_.*/)
|
|
27
|
+
hit['_source'].should be_a Hash
|
|
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'
|
|
31
51
|
end
|
|
32
52
|
|
|
33
53
|
end
|
|
@@ -81,6 +101,20 @@ describe Waistband::Query do
|
|
|
81
101
|
|
|
82
102
|
end
|
|
83
103
|
|
|
104
|
+
describe '#add_optional_term' do
|
|
105
|
+
|
|
106
|
+
it "adds the term on the key" do
|
|
107
|
+
query.add_optional_term('metro', 'boston')
|
|
108
|
+
query.instance_variable_get('@optional_terms')['metro'][:keywords].should eql ['boston']
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "adds several terms on multiple words" do
|
|
112
|
+
query.add_optional_term('metro', 'sf bay area')
|
|
113
|
+
query.instance_variable_get('@optional_terms')['metro'][:keywords].should eql ['sf', 'bay', 'area']
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
84
118
|
describe '#terms' do
|
|
85
119
|
|
|
86
120
|
it "builds an array of all terms" do
|
|
@@ -213,6 +247,7 @@ describe Waistband::Query do
|
|
|
213
247
|
it 'constructs the query with several terms' do
|
|
214
248
|
query.add_term('metro', 'sf bay area')
|
|
215
249
|
query.add_term('geography', 'San Francisco')
|
|
250
|
+
query.add_optional_term('internal', 'true')
|
|
216
251
|
query.add_field('name')
|
|
217
252
|
query.add_field('description')
|
|
218
253
|
|
|
@@ -238,7 +273,13 @@ describe Waistband::Query do
|
|
|
238
273
|
}
|
|
239
274
|
],
|
|
240
275
|
must_not: [],
|
|
241
|
-
should: [
|
|
276
|
+
should: [
|
|
277
|
+
{
|
|
278
|
+
terms: {
|
|
279
|
+
internal: ['true']
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
]
|
|
242
283
|
}
|
|
243
284
|
},
|
|
244
285
|
from: 0,
|
|
@@ -270,7 +311,8 @@ describe Waistband::Query do
|
|
|
270
311
|
end
|
|
271
312
|
|
|
272
313
|
def add_result!
|
|
273
|
-
index.store!("task_123123", {id: 123123, name: 'some shopping in ikea',
|
|
314
|
+
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})
|
|
315
|
+
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})
|
|
274
316
|
index.refresh
|
|
275
317
|
|
|
276
318
|
query.add_field('name')
|
metadata
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: waistband
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
|
+
prerelease:
|
|
5
6
|
platform: ruby
|
|
6
7
|
authors:
|
|
7
8
|
- David Jairala
|
|
8
9
|
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date: 2013-08-
|
|
12
|
+
date: 2013-08-26 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: activesupport
|
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
16
18
|
requirements:
|
|
17
|
-
- - '>='
|
|
19
|
+
- - ! '>='
|
|
18
20
|
- !ruby/object:Gem::Version
|
|
19
21
|
version: 3.0.0
|
|
20
22
|
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
23
26
|
requirements:
|
|
24
|
-
- - '>='
|
|
27
|
+
- - ! '>='
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
29
|
version: 3.0.0
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
|
28
31
|
name: rest-client
|
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
30
34
|
requirements:
|
|
31
35
|
- - ~>
|
|
32
36
|
- !ruby/object:Gem::Version
|
|
@@ -34,6 +38,7 @@ dependencies:
|
|
|
34
38
|
type: :runtime
|
|
35
39
|
prerelease: false
|
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
37
42
|
requirements:
|
|
38
43
|
- - ~>
|
|
39
44
|
- !ruby/object:Gem::Version
|
|
@@ -41,6 +46,7 @@ dependencies:
|
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
|
42
47
|
name: json
|
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
44
50
|
requirements:
|
|
45
51
|
- - ~>
|
|
46
52
|
- !ruby/object:Gem::Version
|
|
@@ -48,6 +54,7 @@ dependencies:
|
|
|
48
54
|
type: :runtime
|
|
49
55
|
prerelease: false
|
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
51
58
|
requirements:
|
|
52
59
|
- - ~>
|
|
53
60
|
- !ruby/object:Gem::Version
|
|
@@ -55,6 +62,7 @@ dependencies:
|
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
|
56
63
|
name: bundler
|
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
58
66
|
requirements:
|
|
59
67
|
- - ~>
|
|
60
68
|
- !ruby/object:Gem::Version
|
|
@@ -62,6 +70,7 @@ dependencies:
|
|
|
62
70
|
type: :development
|
|
63
71
|
prerelease: false
|
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
65
74
|
requirements:
|
|
66
75
|
- - ~>
|
|
67
76
|
- !ruby/object:Gem::Version
|
|
@@ -69,15 +78,17 @@ dependencies:
|
|
|
69
78
|
- !ruby/object:Gem::Dependency
|
|
70
79
|
name: rake
|
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
72
82
|
requirements:
|
|
73
|
-
- - '>='
|
|
83
|
+
- - ! '>='
|
|
74
84
|
- !ruby/object:Gem::Version
|
|
75
85
|
version: '0'
|
|
76
86
|
type: :development
|
|
77
87
|
prerelease: false
|
|
78
88
|
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
79
90
|
requirements:
|
|
80
|
-
- - '>='
|
|
91
|
+
- - ! '>='
|
|
81
92
|
- !ruby/object:Gem::Version
|
|
82
93
|
version: '0'
|
|
83
94
|
description: Ruby interface to Elastic Search
|
|
@@ -121,26 +132,27 @@ files:
|
|
|
121
132
|
homepage: https://github.com/taskrabbit/waistband
|
|
122
133
|
licenses:
|
|
123
134
|
- MIT
|
|
124
|
-
metadata: {}
|
|
125
135
|
post_install_message:
|
|
126
136
|
rdoc_options: []
|
|
127
137
|
require_paths:
|
|
128
138
|
- lib
|
|
129
139
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
|
+
none: false
|
|
130
141
|
requirements:
|
|
131
|
-
- - '>='
|
|
142
|
+
- - ! '>='
|
|
132
143
|
- !ruby/object:Gem::Version
|
|
133
144
|
version: 1.9.3
|
|
134
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
|
+
none: false
|
|
135
147
|
requirements:
|
|
136
|
-
- - '>='
|
|
148
|
+
- - ! '>='
|
|
137
149
|
- !ruby/object:Gem::Version
|
|
138
150
|
version: '0'
|
|
139
151
|
requirements: []
|
|
140
152
|
rubyforge_project:
|
|
141
|
-
rubygems_version:
|
|
153
|
+
rubygems_version: 1.8.25
|
|
142
154
|
signing_key:
|
|
143
|
-
specification_version:
|
|
155
|
+
specification_version: 3
|
|
144
156
|
summary: Elastic Search all the things!
|
|
145
157
|
test_files:
|
|
146
158
|
- spec/config/waistband/waistband.yml
|
checksums.yaml
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
SHA1:
|
|
3
|
-
metadata.gz: 0bb1048847e31a803f414112221ee12f51ec7df9
|
|
4
|
-
data.tar.gz: 2ba18a9f7eb6ab073ce1a2c0f20b06fa4006b90f
|
|
5
|
-
SHA512:
|
|
6
|
-
metadata.gz: e6e394da1f1941fcba5487e59debe69f063c4eb7893e33fb9bbfcf1c8fdc9017baceeaba2ada6b2ecdfb04fb2ffa943905439aea31855c4f7a4b7a2bd06094be
|
|
7
|
-
data.tar.gz: f45002b13606503854402badae133138e67cc351f6eae142b0e49c130023e71253bc0bed174ea65e79a30c8d97eb4bb8d0fd4070d957eec1131d1c5c0ad68ab7
|