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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6b9494adc6453711289b4e3c5321c683d190ab7
4
- data.tar.gz: 0d8832b4787080dff61db37429c7cf8d021a0074
3
+ metadata.gz: 9296a4a37e2bf84e553b9b5757132c71d0bfca0c
4
+ data.tar.gz: 8e9eea9e347fb728f3a779bc0ba32713c52549c9
5
5
  SHA512:
6
- metadata.gz: 5b3bb35dcdeec2eb3745b29c4adfa127e6055c02ed3273a8c308f25135f1dd5a9498b0f3de3c1684934b78f60687a2c56caed3bac45da8a7a0b127f8d7b299cf
7
- data.tar.gz: aa4e00a5abda4a8ca7e581ecc5b84a513283deeacc8b295412d4bc561c388c3895562612a0b9a041d9938ab99fa8e8f53cfcefa7ae1c1cdce403b40fe71eef37
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] || base.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. Options passed here correspond
187
- # to `where`-style filters which boost a document
188
- # if matched.
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
- # @param options = {} [type] [description]
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(options = {})
196
- BoostClause.new(self, options)
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, opts_or_string.merge(inverse: true))
250
+ WhereClause.new(self).not(opts_or_string)
217
251
  else
218
- MatchClause.new(self, opts_or_string, opts.merge(inverse: true))
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, opts_or_string.merge(should: true))
276
+ WhereClause.new(self).should(opts_or_string)
243
277
  else
244
- MatchClause.new(self, opts_or_string, opts.merge(should: true))
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, options = {})
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
- self.class.new(self, options.merge(inverse: !inverse?))
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 = {}, options = {})
54
- self.class.new(self, opts_or_string, options.merge(inverse: !inverse?))
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, options)
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
- self.new(Base.new, options)
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 = {}, options = {})
81
- self.class.new(self, opts_or_str, options.merge(inverse: true, should: should?))
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 not(opts_or_str)
97
+ # @overload should(opts_or_str)
92
98
  # @param [String] A string that should be matched anywhere in the document
93
- # @overload not(opts_or_str)
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 = {}, options = {})
118
- self.class.new(self, opts_or_str, options.merge(should: true))
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
- self.new(Base.new, options)
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
- self.class.new(self, options.merge(inverse: true, should: should?))
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
- self.class.new(self, options.merge(should: true))
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[:explain] = true if clause.get_explain
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, _| field == '_source' }
59
- hit['_source'].merge(merge_fields)
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
@@ -1,5 +1,6 @@
1
1
  require 'stretchy/utils/contract'
2
2
  require 'stretchy/utils/colorize'
3
3
  require 'stretchy/utils/logger'
4
+ require 'stretchy/utils/dot_handler'
4
5
  require 'stretchy/utils/configuration'
5
6
  require 'stretchy/utils/client_actions'
@@ -1,3 +1,3 @@
1
1
  module Stretchy
2
- VERSION = "0.3.8"
2
+ VERSION = "0.4.0"
3
3
  end
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.3.8
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-05-20 00:00:00.000000000 Z
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