stretchy 0.3.8 → 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.
- checksums.yaml +4 -4
- data/lib/stretchy/clauses/base.rb +45 -11
- data/lib/stretchy/clauses/boost_clause.rb +3 -3
- data/lib/stretchy/clauses/boost_match_clause.rb +8 -4
- data/lib/stretchy/clauses/boost_where_clause.rb +2 -2
- data/lib/stretchy/clauses/match_clause.rb +16 -7
- data/lib/stretchy/clauses/where_clause.rb +13 -6
- data/lib/stretchy/results/base.rb +16 -3
- data/lib/stretchy/utils/dot_handler.rb +44 -0
- data/lib/stretchy/utils.rb +1 -0
- data/lib/stretchy/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9296a4a37e2bf84e553b9b5757132c71d0bfca0c
|
4
|
+
data.tar.gz: 8e9eea9e347fb728f3a779bc0ba32713c52549c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23721cc1bee9c018e53c3ca34f68e5c9c46d6e9e593c59fcdb3eb27b32bc869fccd36e6ac64736a62e5993d9ddd2da4eaff3d1d43e70ec48cd2a2d2f166c9b4e
|
7
|
+
data.tar.gz: 020882eeb4e78a3bc16a6749d963ab9850cfc6d2fd2727dc218312078e917f6a4c2738fb4b66b16dc861a89fa141f9ca88d063c94c21bc838f870d67ba85fc46
|
@@ -48,10 +48,11 @@ module Stretchy
|
|
48
48
|
@where_builder = base.where_builder
|
49
49
|
@boost_builder = base.boost_builder
|
50
50
|
@aggregate_builder = base.aggregate_builder
|
51
|
-
@inverse = options[:inverse]
|
51
|
+
@inverse = options[:inverse]
|
52
52
|
@limit = base.get_limit
|
53
53
|
@offset = base.get_offset
|
54
54
|
@explain = base.get_explain
|
55
|
+
@fields = base.get_fields
|
55
56
|
else
|
56
57
|
options = Hash(base_or_opts).merge(options)
|
57
58
|
@index_name = options[:index] || Stretchy.index_name
|
@@ -63,6 +64,7 @@ module Stretchy
|
|
63
64
|
@inverse = options[:inverse]
|
64
65
|
@limit = DEFAULT_LIMIT
|
65
66
|
@offset = DEFAULT_OFFSET
|
67
|
+
@fields = nil
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
@@ -133,6 +135,34 @@ module Stretchy
|
|
133
135
|
end
|
134
136
|
alias :current_page :get_page
|
135
137
|
|
138
|
+
#
|
139
|
+
# Select fields for Elasticsearch to return
|
140
|
+
#
|
141
|
+
# By default, Stretchy will return the entire _source
|
142
|
+
# for each document. If you call `.fields` with no
|
143
|
+
# arguments or an empty array, Stretchy will pass
|
144
|
+
# an empty array and only the "_type" and "_id"
|
145
|
+
# fields will be returned.
|
146
|
+
#
|
147
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-fields.html Elastic Docs - Fields
|
148
|
+
#
|
149
|
+
# @param new_fields [Array] Fields elasticsearch should return
|
150
|
+
#
|
151
|
+
# @return [self] Allows continuing the query chain
|
152
|
+
def fields(*args)
|
153
|
+
@fields ||= []
|
154
|
+
@fields += args.flatten if args.any?
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# Accessor for fields Elasticsearch will return
|
160
|
+
#
|
161
|
+
# @return [Array] List of fields in the current query
|
162
|
+
def get_fields
|
163
|
+
@fields
|
164
|
+
end
|
165
|
+
|
136
166
|
#
|
137
167
|
# Tells the search to explain the scoring
|
138
168
|
# mechanism for each document.
|
@@ -183,17 +213,21 @@ module Stretchy
|
|
183
213
|
|
184
214
|
#
|
185
215
|
# Used for boosting the relevance score of
|
186
|
-
# search results.
|
187
|
-
#
|
188
|
-
#
|
216
|
+
# search results. `match` and `where` clauses
|
217
|
+
# added after `boost` will be applied as
|
218
|
+
# boosting functions instead of filters
|
219
|
+
#
|
220
|
+
# @example Boost documents that match a filter
|
221
|
+
# query.boost.where('post.user_id' => current_user.id)
|
189
222
|
#
|
190
|
-
# @
|
223
|
+
# @example Boost documents that match fulltext search
|
224
|
+
# query.boost.match('user search terms')
|
191
225
|
#
|
192
226
|
# @return [BoostClause] query in boost context
|
193
227
|
#
|
194
228
|
# @see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html Elastic Docs - Function Score Query
|
195
|
-
def boost
|
196
|
-
BoostClause.new(self
|
229
|
+
def boost
|
230
|
+
BoostClause.new(self)
|
197
231
|
end
|
198
232
|
|
199
233
|
#
|
@@ -213,9 +247,9 @@ module Stretchy
|
|
213
247
|
# is given (ie, doing a full-text search across the whole document)
|
214
248
|
def not(opts_or_string = {}, opts = {})
|
215
249
|
if opts_or_string.is_a?(Hash)
|
216
|
-
WhereClause.new(self
|
250
|
+
WhereClause.new(self).not(opts_or_string)
|
217
251
|
else
|
218
|
-
MatchClause.new(self
|
252
|
+
MatchClause.new(self).not(opts_or_string)
|
219
253
|
end
|
220
254
|
end
|
221
255
|
|
@@ -239,9 +273,9 @@ module Stretchy
|
|
239
273
|
# @see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html Elastic Docs - Bool Filter
|
240
274
|
def should(opts_or_string = {}, opts = {})
|
241
275
|
if opts_or_string.is_a?(Hash)
|
242
|
-
WhereClause.new(self
|
276
|
+
WhereClause.new(self).should(opts_or_string)
|
243
277
|
else
|
244
|
-
MatchClause.new(self
|
278
|
+
MatchClause.new(self).should(opts_or_string)
|
245
279
|
end
|
246
280
|
end
|
247
281
|
|
@@ -31,9 +31,8 @@ module Stretchy
|
|
31
31
|
# @param options = {} [Hash] Options for the boost clause
|
32
32
|
# @option options [true, false] :inverse (nil) If this boost should also be in the inverse state
|
33
33
|
#
|
34
|
-
def initialize(base
|
34
|
+
def initialize(base)
|
35
35
|
super(base)
|
36
|
-
@inverse = options.delete(:inverse)
|
37
36
|
end
|
38
37
|
|
39
38
|
#
|
@@ -199,7 +198,8 @@ module Stretchy
|
|
199
198
|
#
|
200
199
|
# @return [BoostClause] Boost clause in inverse context
|
201
200
|
def not(options = {})
|
202
|
-
|
201
|
+
@inverse = true
|
202
|
+
self
|
203
203
|
end
|
204
204
|
|
205
205
|
end
|
@@ -30,10 +30,8 @@ module Stretchy
|
|
30
30
|
def initialize(base, opts_or_string = {}, options = {})
|
31
31
|
super(base)
|
32
32
|
if opts_or_string.is_a?(Hash)
|
33
|
-
@inverse = opts_or_string.delete(:inverse) || options.delete(:inverse)
|
34
33
|
match_function(opts_or_string.merge(options))
|
35
34
|
else
|
36
|
-
@inverse = options.delete(:inverse)
|
37
35
|
match_function(options.merge('_all' => opts_or_string))
|
38
36
|
end
|
39
37
|
end
|
@@ -50,8 +48,14 @@ module Stretchy
|
|
50
48
|
# @param opts_or_string [Hash] Fields and values that should not match in the document
|
51
49
|
#
|
52
50
|
# @return [BoostMatchClause] Query with inverse matching boost function applied
|
53
|
-
def not(opts_or_string = {}
|
54
|
-
|
51
|
+
def not(opts_or_string = {})
|
52
|
+
@inverse = true
|
53
|
+
if opts_or_string.is_a?(Hash)
|
54
|
+
match_function(opts_or_string)
|
55
|
+
else
|
56
|
+
match_function('_all' => opts_or_string)
|
57
|
+
end
|
58
|
+
self
|
55
59
|
end
|
56
60
|
|
57
61
|
#
|
@@ -21,8 +21,8 @@ module Stretchy
|
|
21
21
|
#
|
22
22
|
# @return [BoostWhereClause] Query with filter boosts applied
|
23
23
|
def initialize(base, options = {})
|
24
|
-
super(base
|
25
|
-
where_function(:init, options)
|
24
|
+
super(base)
|
25
|
+
where_function(:init, options) if options.any?
|
26
26
|
self
|
27
27
|
end
|
28
28
|
|
@@ -21,7 +21,11 @@ module Stretchy
|
|
21
21
|
#
|
22
22
|
# @return [MatchClause] Temporary clause outside current state
|
23
23
|
def self.tmp(options = {})
|
24
|
-
|
24
|
+
if options.delete(:inverse)
|
25
|
+
self.new(Base.new).not(options)
|
26
|
+
else
|
27
|
+
self.new(Base.new, options)
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
#
|
@@ -77,8 +81,10 @@ module Stretchy
|
|
77
81
|
# my_field: "not_match_1",
|
78
82
|
# other_field: "not_match_2"
|
79
83
|
# )
|
80
|
-
def not(opts_or_str = {}
|
81
|
-
|
84
|
+
def not(opts_or_str = {})
|
85
|
+
@inverse = true
|
86
|
+
add_params(opts_or_str)
|
87
|
+
self
|
82
88
|
end
|
83
89
|
|
84
90
|
#
|
@@ -88,9 +94,9 @@ module Stretchy
|
|
88
94
|
#
|
89
95
|
# Can be chained with {#not}
|
90
96
|
#
|
91
|
-
# @overload
|
97
|
+
# @overload should(opts_or_str)
|
92
98
|
# @param [String] A string that should be matched anywhere in the document
|
93
|
-
# @overload
|
99
|
+
# @overload should(opts_or_str)
|
94
100
|
# @param [Hash] A hash of fields and strings that should be matched in those fields
|
95
101
|
#
|
96
102
|
# @param opts_or_str = {} [type] [description]
|
@@ -114,8 +120,11 @@ module Stretchy
|
|
114
120
|
# )
|
115
121
|
#
|
116
122
|
# @see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html Elastic Docs - Bool Query
|
117
|
-
def should(opts_or_str = {}
|
118
|
-
|
123
|
+
def should(opts_or_str = {})
|
124
|
+
@should = true
|
125
|
+
@inverse = false
|
126
|
+
add_params(opts_or_str)
|
127
|
+
self
|
119
128
|
end
|
120
129
|
|
121
130
|
#
|
@@ -31,7 +31,11 @@ module Stretchy
|
|
31
31
|
#
|
32
32
|
# @return [WhereClause] A clause outside the main query context
|
33
33
|
def self.tmp(options = {})
|
34
|
-
|
34
|
+
if options.delete(:inverse)
|
35
|
+
self.new(Base.new).not(options)
|
36
|
+
else
|
37
|
+
self.new(Base.new, options)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
|
37
41
|
#
|
@@ -60,8 +64,6 @@ module Stretchy
|
|
60
64
|
#
|
61
65
|
def initialize(base, options = {})
|
62
66
|
super(base)
|
63
|
-
@inverse = options.delete(:inverse)
|
64
|
-
@should = options.delete(:should)
|
65
67
|
add_params(options)
|
66
68
|
end
|
67
69
|
|
@@ -153,7 +155,9 @@ module Stretchy
|
|
153
155
|
# match_field: [:these, "options"]
|
154
156
|
# )
|
155
157
|
def not(options = {})
|
156
|
-
|
158
|
+
@inverse = true
|
159
|
+
add_params(options)
|
160
|
+
self
|
157
161
|
end
|
158
162
|
|
159
163
|
#
|
@@ -178,7 +182,10 @@ module Stretchy
|
|
178
182
|
# exists_field: nil
|
179
183
|
# )
|
180
184
|
def should(options = {})
|
181
|
-
|
185
|
+
@inverse = false
|
186
|
+
@should = true
|
187
|
+
add_params(options)
|
188
|
+
self
|
182
189
|
end
|
183
190
|
|
184
191
|
#
|
@@ -190,7 +197,7 @@ module Stretchy
|
|
190
197
|
# @return [Boosts::FilterBoost] A boost including all the current filters
|
191
198
|
def to_boost(weight = nil)
|
192
199
|
weight ||= Stretchy::Boosts::FilterBoost::DEFAULT_WEIGHT
|
193
|
-
|
200
|
+
|
194
201
|
if @match_builder.any? && @where_builder.any?
|
195
202
|
Stretchy::Boosts::FilterBoost.new(
|
196
203
|
filter: Stretchy::Filters::QueryFilter.new(
|
@@ -19,6 +19,10 @@ module Stretchy
|
|
19
19
|
alias :per_page :limit
|
20
20
|
alias :limit_value :limit
|
21
21
|
|
22
|
+
def fields
|
23
|
+
clause.get_fields
|
24
|
+
end
|
25
|
+
|
22
26
|
def offset
|
23
27
|
clause.get_offset
|
24
28
|
end
|
@@ -45,7 +49,8 @@ module Stretchy
|
|
45
49
|
from: offset,
|
46
50
|
size: limit
|
47
51
|
}
|
48
|
-
params[:
|
52
|
+
params[:fields] = fields if fields
|
53
|
+
params[:explain] = true if clause.get_explain
|
49
54
|
@response ||= Stretchy.search(params)
|
50
55
|
end
|
51
56
|
|
@@ -55,8 +60,16 @@ module Stretchy
|
|
55
60
|
|
56
61
|
def hits
|
57
62
|
@hits ||= response['hits']['hits'].map do |hit|
|
58
|
-
merge_fields = hit.reject{|field, _|
|
59
|
-
|
63
|
+
merge_fields = hit.reject{|field, _| ['_source', 'fields'].include?(field) }
|
64
|
+
|
65
|
+
source_fields = {}
|
66
|
+
if hit['fields']
|
67
|
+
source_fields = Stretchy::Utils::DotHandler.convert_from_dotted_keys(hit['fields'])
|
68
|
+
elsif hit['_source']
|
69
|
+
source_fields = hit['_source']
|
70
|
+
end
|
71
|
+
|
72
|
+
source_fields.merge(merge_fields)
|
60
73
|
end
|
61
74
|
end
|
62
75
|
alias :results :hits
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Stretchy
|
2
|
+
module Utils
|
3
|
+
module DotHandler
|
4
|
+
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def self.convert_from_dotted_keys(hash)
|
8
|
+
new_hash = {}
|
9
|
+
|
10
|
+
hash.each do |key, value|
|
11
|
+
h = new_hash
|
12
|
+
|
13
|
+
parts = key.to_s.split('.')
|
14
|
+
while parts.length > 0
|
15
|
+
new_key = parts[0]
|
16
|
+
rest = parts[1..-1]
|
17
|
+
|
18
|
+
if not h.instance_of? Hash
|
19
|
+
raise ArgumentError, "Trying to set key #{new_key} to value #{value} on a non hash #{h}\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
if rest.length == 0
|
23
|
+
if h[new_key].instance_of? Hash
|
24
|
+
raise ArgumentError, "Replacing a hash with a scalar. key #{new_key}, value #{value}, current value #{h[new_key]}\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
h.store(new_key, value)
|
28
|
+
break
|
29
|
+
end
|
30
|
+
|
31
|
+
if h[new_key].nil?
|
32
|
+
h[new_key] = {}
|
33
|
+
end
|
34
|
+
|
35
|
+
h = h[new_key]
|
36
|
+
parts = rest
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
new_hash
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/stretchy/utils.rb
CHANGED
data/lib/stretchy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stretchy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- agius
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elasticsearch
|
@@ -200,6 +200,7 @@ files:
|
|
200
200
|
- lib/stretchy/utils/colorize.rb
|
201
201
|
- lib/stretchy/utils/configuration.rb
|
202
202
|
- lib/stretchy/utils/contract.rb
|
203
|
+
- lib/stretchy/utils/dot_handler.rb
|
203
204
|
- lib/stretchy/utils/logger.rb
|
204
205
|
- lib/stretchy/version.rb
|
205
206
|
- stretchy.gemspec
|