stretchy 0.3.8 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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