lsolr 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +5 -5
  2. data/lib/lsolr.rb +76 -25
  3. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e49132ead477dd5f50d86d46cec871e47a7b33db
4
- data.tar.gz: 9ce3049d5577571cea8a650635f0af9d3517285b
2
+ SHA256:
3
+ metadata.gz: 20924e50e137b0ecacfbc21f0b12ac52db3904195c4b3cf42090cefe20cab911
4
+ data.tar.gz: fbfe0c7c327d9205cab1a566db724ec8779f71b20df5a3a05364247978cc1e8f
5
5
  SHA512:
6
- metadata.gz: 2a1db34ed53ab514e0c80f92897bdb74187d3e157a63486eae973dae95429530ec279490aee62f2f5aaabf87e94b78bbfa0715046b9f2dfacd6da41c6b33a16c
7
- data.tar.gz: 2587c78f6de1121226ed98b026e2afa1b0611750037caae7d0c5a9a2acf51250a5bf7810c13462f1dc675bbc7e61faaf1087d10d3716c03b2b0cb43e8ba7d5d6
6
+ metadata.gz: 62cf4176711e853c9468afb0d18c7d8bdec1c3122973caa26d7634696b71485c38feae5619cb81bc55f75d5f84801503a0a0e2611d706fcf69c9d49aa134a801
7
+ data.tar.gz: 6dc375254e095659cbd5af6b5b4523419c5ea83cedfd96e6bac046d6610c6d170c9c4b166a47d4d1a9d49954447b02c0406ab278a7c6e0a39b25642d933b4852
@@ -28,11 +28,21 @@ require 'date'
28
28
  # }
29
29
  #
30
30
  # LSolr.build(params).to_s
31
- # #=> 'field01:hoge AND field02:fuga AND field03:14 AND field04:7.3 AND field05:true
32
- # # AND field06:false AND field07:"7000-07-01T00:00:00Z" AND field08:"6000-05-31T06:31:43Z"
33
- # # AND field09:"5000-06-30T12:59:03Z" AND field10:foo~2.0 AND field11:(1 2 3)
34
- # # AND field12:[1 TO 10] AND field13:[20 TO 40} AND field14:[3000-01-01T00:00:00Z TO 4000-12-31T00:00:00Z]
35
- # # AND field15:[3.0 TO 4.0]'
31
+ # #=> 'field01:hoge AND
32
+ # # field02:fuga AND
33
+ # # field03:14 AND
34
+ # # field04:7.3 AND
35
+ # # field05:true AND
36
+ # # field06:false AND
37
+ # # field07:"7000-07-01T00:00:00Z" AND
38
+ # # field08:"6000-05-31T06:31:43Z" AND
39
+ # # field09:"5000-06-30T12:59:03Z" AND
40
+ # # field10:foo~2.0 AND
41
+ # # field11:(1 2 3) AND
42
+ # # field12:[1 TO 10] AND
43
+ # # field13:[20 TO 40} AND
44
+ # # field14:[3000-01-01T00:00:00Z TO 4000-12-31T00:00:00Z] AND
45
+ # # field15:[3.0 TO 4.0]'
36
46
  #
37
47
  # @example How to use. Part 3:
38
48
  # bool1 = LSolr.new(:bool_field).match(true)
@@ -48,8 +58,12 @@ require 'date'
48
58
  # # OR (bool_field:false AND (date_field1:[* TO 2000-06-30T23:59:59Z] OR date_field2:{2000-07-01T00:00:00Z TO 2001-01-01T00:00:00Z}))'
49
59
  #
50
60
  # @example How to use. Part 4:
51
- # LSolr.build('field:value').to_s
52
- # #=> 'field:value'
61
+ # %w[a b c].map { |v| LSolr.new(:field).prefix_match("#{v}*") }.reduce { |a, e| a.or(e) }.wrap.not.to_s
62
+ # #=> 'NOT (field:a* OR field:b* OR field:c*)'
63
+ #
64
+ # @example How to use. Part 5:
65
+ # LSolr.build('a:1').and(LSolr.build(b: 2)).to_s
66
+ # #=> 'a:1 AND b:2'
53
67
  class LSolr
54
68
  ArgumentError = Class.new(::ArgumentError)
55
69
  RangeError = Class.new(::RangeError)
@@ -69,6 +83,7 @@ class LSolr
69
83
  WILD_CARD = '*'
70
84
  PROXIMITY = '~'
71
85
  BOOST = '^'
86
+ CONSTANT_SCORE = '^='
72
87
  PHRASE_MATCH_DELIMITER = ' '
73
88
  MULTI_VALUE_MATCH_DELIMITER = ' '
74
89
  FUZZY_MATCH_DISTANCE_RANGE = (0.0..2.0).freeze
@@ -96,7 +111,7 @@ class LSolr
96
111
  case params
97
112
  when Hash then params.map { |f, v| build_query(f, v) }.reduce { |a, e| a.and(e) }
98
113
  when String then new.raw(params)
99
- else raise TypeError, 'Could not build solr query. Please specify a Hash or String value.'
114
+ else raise TypeError, "Could not build solr query. Please specify a Hash or String value. #{params.inspect} given."
100
115
  end
101
116
  end
102
117
 
@@ -110,7 +125,7 @@ class LSolr
110
125
  when Array then build_array_query(field, value)
111
126
  when Range then build_range_query(field, value)
112
127
  when Enumerator then build_enumerator_query(field, value)
113
- else raise TypeError, "Could not build solr query. field: #{field}, value: #{value.inspect}"
128
+ else raise TypeError, "Could not build solr query. field: #{field.inspect}, value: #{value.inspect} given."
114
129
  end
115
130
  end
116
131
 
@@ -137,25 +152,25 @@ class LSolr
137
152
 
138
153
  # Create a new query builder instance.
139
154
  #
140
- # @param field [String, Symbol] a field name
155
+ # @param field_name [String, Symbol] a field name
141
156
  # @return [LSolr] a instance
142
- def initialize(field = '')
143
- @expr_not = ''
144
- @field = field.to_s
145
- @value = ''
146
- @range_first = ''
147
- @range_last = ''
148
- @boost = ''
157
+ def initialize(field_name = nil)
158
+ if field_name.nil?
159
+ @field = ''
160
+ else
161
+ field(field_name)
162
+ end
163
+
164
+ @expr_not = @value = @range_first = @range_last = @boost = @constant_score = @raw = ''
149
165
  @left_parentheses = []
150
166
  @right_parentheses = []
151
- @raw = ''
152
167
  end
153
168
 
154
169
  # Returns Apache Solr standard lucene type query string.
155
170
  #
156
171
  # @return [String] a stringified query
157
172
  def to_s
158
- raise IncompleteQueryError, 'Please specify search field and value.' if blank?
173
+ raise IncompleteQueryError, 'Please specify a term of search.' if blank?
159
174
 
160
175
  decorate_term_expr_if_needed(build_term_expr)
161
176
  end
@@ -179,11 +194,13 @@ class LSolr
179
194
 
180
195
  # Sets a field name.
181
196
  #
182
- # @param f [String, Symbol] a field name
197
+ # @param name [String, Symbol] a field name
183
198
  #
184
199
  # @return [LSolr] self instance
185
- def field(f)
186
- @field = f.to_s
200
+ def field(name)
201
+ raise ArgumentError, "The field name must be a not empty string value. #{name.inspect} given." unless present_string?(name)
202
+
203
+ @field = name.to_s
187
204
  self
188
205
  end
189
206
 
@@ -193,6 +210,8 @@ class LSolr
193
210
  #
194
211
  # @return [LSolr] self instance
195
212
  def raw(q)
213
+ raise ArgumentError, "The raw query must be a not empty string value. #{q.inspect} given." unless present_string?(q)
214
+
196
215
  @raw = q.to_s
197
216
  self
198
217
  end
@@ -228,11 +247,26 @@ class LSolr
228
247
  #
229
248
  # @return [LSolr] self instance
230
249
  def boost(factor)
231
- raise ArgumentError, "The boost factor number must be positive. #{factor} given." if factor <= 0
250
+ raise ArgumentError, "The boost factor must be a positive number. #{factor.inspect} given." unless valid_boost_factor?(factor)
251
+
232
252
  @boost = "#{BOOST}#{factor}"
233
253
  self
234
254
  end
235
255
 
256
+ # Specifies scoring result in expression.
257
+ #
258
+ # @see https://lucene.apache.org/solr/guide/7_1/the-standard-query-parser.html#constant-score-with Constant Score with "^="
259
+ #
260
+ # @param score [Float] a constant score
261
+ #
262
+ # @return [LSolr] self instance
263
+ def constant_score(score)
264
+ raise ArgumentError, "The constant score must be a number. #{score.inspect} given." unless valid_score?(score)
265
+
266
+ @constant_score = "#{CONSTANT_SCORE}#{score}"
267
+ self
268
+ end
269
+
236
270
  # Builds a normal query expression.
237
271
  #
238
272
  # @param value [String, Integer, true, false] a search word or a filter value
@@ -255,7 +289,7 @@ class LSolr
255
289
  #
256
290
  # @return [LSolr] self instance
257
291
  def match_in(values)
258
- raise ArgumentError, "#{values.inspect} given. Must be a not empty array." if values.nil? || !values.is_a?(Array) || values.empty?
292
+ raise ArgumentError, "#{values.inspect} given. It must be a not empty array." unless present_array?(values)
259
293
 
260
294
  values = values.map { |v| clean(v) }
261
295
  @value = "(#{values.join(MULTI_VALUE_MATCH_DELIMITER)})"
@@ -414,6 +448,22 @@ class LSolr
414
448
  !@raw.empty?
415
449
  end
416
450
 
451
+ def present_string?(v)
452
+ !v.nil? && (v.is_a?(String) || v.is_a?(Symbol)) && !v.empty?
453
+ end
454
+
455
+ def present_array?(v)
456
+ !v.nil? && v.is_a?(Array) && !v.compact.empty? && v.map(&:to_s).map(&:empty?).none?
457
+ end
458
+
459
+ def valid_boost_factor?(v)
460
+ (v.is_a?(Float) || v.is_a?(Integer)) && v > 0
461
+ end
462
+
463
+ def valid_score?(v)
464
+ v.is_a?(Float) || v.is_a?(Integer)
465
+ end
466
+
417
467
  def clean(value, symbols: RESERVED_SYMBOLS)
418
468
  value.to_s
419
469
  .tr(symbols.join, REPLACEMENT_CHAR)
@@ -463,6 +513,7 @@ class LSolr
463
513
  def decorate_term_expr_if_needed(expr)
464
514
  expr = "#{expr_not}#{left_parentheses.join}#{expr}#{right_parentheses.join}"
465
515
  expr = "#{prev} #{operator} #{expr}" if !prev.nil? && prev.present?
466
- "#{expr}#{@boost}"
516
+ scoring = present_string?(@constant_score) ? @constant_score : @boost
517
+ "#{expr}#{scoring}"
467
518
  end
468
519
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lsolr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taishi Kasuga
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-16 00:00:00.000000000 Z
11
+ date: 2018-02-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: LSolr is a query builder of Apache Solr standard Lucene type query for
14
14
  Ruby.
@@ -38,7 +38,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
38
  version: '0'
39
39
  requirements: []
40
40
  rubyforge_project:
41
- rubygems_version: 2.6.14
41
+ rubygems_version: 2.7.4
42
42
  signing_key:
43
43
  specification_version: 4
44
44
  summary: A query builder of Apache Solr for Ruby