lsolr 0.1.9 → 0.2.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.
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