lsolr 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/lsolr.rb +113 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5e5ca288040ec046e3df00c273dcd6c3ccc6bd31e6db172bb652ff377dddaaf4
|
4
|
+
data.tar.gz: d87df9ae56c1aa37c1b92e11c00c82b0a3afb44abdd7e918e48ab88cce69a7e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4da503d0ce9a2627630c35848d8e3dc0d1b5fdacbf60839d9973f82a7ac2cd79d29a73a57a4583ed2ebf3a98de9bd14a5488da55f77cc41f24010cb76c091e70
|
7
|
+
data.tar.gz: b0ad4353b239b32cfdaf828cfc201dae3b917f21f861c4c460787b575d0630ec60276ff9cd6a36d3daa8d9ee0cc24730df68206a11ae83ea8d283c83453de95c
|
data/lib/lsolr.rb
CHANGED
@@ -1,8 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'date'
|
4
|
+
|
3
5
|
# A query builder of Apache Solr standard Lucene type query for Ruby.
|
4
6
|
#
|
5
|
-
# @example How to use.
|
7
|
+
# @example How to use. Part 1:
|
8
|
+
# LSolr.build(term1: 'hoge', term2: true).to_s
|
9
|
+
# #=> 'term1:hoge AND term2:true'
|
10
|
+
#
|
11
|
+
# @example How to use. Part 2:
|
12
|
+
# params = {
|
13
|
+
# term01: 'hoge',
|
14
|
+
# term02: :fuga,
|
15
|
+
# term03: 14,
|
16
|
+
# term04: 7.3,
|
17
|
+
# term05: true,
|
18
|
+
# term06: false,
|
19
|
+
# term07: Date.new(7000, 7, 1),
|
20
|
+
# term08: DateTime.new(6000, 5, 31, 6, 31, 43),
|
21
|
+
# term09: Time.new(5000, 6, 30, 12, 59, 3),
|
22
|
+
# term10: LSolr.new(:term10).fuzzy_match('foo'),
|
23
|
+
# term11: [1, 2, 3],
|
24
|
+
# term12: 1..10,
|
25
|
+
# term13: 20...40,
|
26
|
+
# term14: Date.new(3000, 1, 1)..Date.new(4000, 12, 31),
|
27
|
+
# term15: (3.0..4.0).step(0.1)
|
28
|
+
# }
|
29
|
+
#
|
30
|
+
# LSolr.build(params).to_s
|
31
|
+
# #=> 'term01:hoge AND term02:fuga AND term03:14 AND term04:7.3 AND term05:true
|
32
|
+
# # AND term06:false AND term07:"7000-07-01T00:00:00Z" AND term08:"6000-05-31T06:31:43Z"
|
33
|
+
# # AND term09:"5000-06-30T12:59:03Z" AND term10:foo~2.0 AND (term11:1 OR term11:2 OR term11:3)
|
34
|
+
# # AND term12:[1 TO 10] AND term13:[20 TO 40} AND term14:[3000-01-01T00:00:00Z TO 4000-12-31T00:00:00Z]
|
35
|
+
# # AND term15:[3.0 TO 4.0]'
|
36
|
+
#
|
37
|
+
# @example How to use. Part 3:
|
6
38
|
# monoclinic = LSolr.new(:crystal_system).match(:monoclinic)
|
7
39
|
# cubic = LSolr.new(:crystal_system).match(:cubic)
|
8
40
|
# soft = LSolr.new(:mohs_scale).greater_than_or_equal_to('*').less_than(5.0)
|
@@ -27,7 +59,12 @@ class LSolr
|
|
27
59
|
WILD_CARD = '*'
|
28
60
|
PROXIMITY = '~'
|
29
61
|
BOOST = '^'
|
62
|
+
PHRASE_MATCH_DELIMITER = ' '
|
30
63
|
FUZZY_MATCH_DISTANCE_RANGE = (0.0..2.0).freeze
|
64
|
+
FORMAT_DATE_TIME = '%Y-%m-%dT%H:%M:%SZ'
|
65
|
+
FORMAT_MILLISECOND_FOR_DATE_TYPE = '%Q'
|
66
|
+
FORMAT_MILLISECOND_FOR_TIME_TYPE = '%L'
|
67
|
+
FORMAT_SECOND = '%s'
|
31
68
|
|
32
69
|
PARENTHESIS_LEFT = '('
|
33
70
|
PARENTHESIS_RIGHT = ')'
|
@@ -38,6 +75,49 @@ class LSolr
|
|
38
75
|
|
39
76
|
attr_accessor :prev, :operator, :left_parentheses, :right_parentheses
|
40
77
|
|
78
|
+
class << self
|
79
|
+
# Builds composite query and returns builder instance.
|
80
|
+
#
|
81
|
+
# @param params [Hash{Symbol => String, Integer, Float, true, false, Range, Date, Time}] query terms
|
82
|
+
#
|
83
|
+
# @return [LSolr] a instance
|
84
|
+
def build(params)
|
85
|
+
params.map { |f, v| build_query(f, v) }.reduce { |a, e| a.and(e) }
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def build_query(field, value) # rubocop:disable Metrics/CyclomaticComplexity
|
91
|
+
case value
|
92
|
+
when String, Symbol, Integer, Float, true, false then new(field).match(value)
|
93
|
+
when Date, Time then new(field).date_time_match(value)
|
94
|
+
when LSolr then value
|
95
|
+
when Array then build_array_query(field, value)
|
96
|
+
when Range then build_range_query(field, value)
|
97
|
+
when Enumerator then build_enumerator_query(field, value)
|
98
|
+
else raise ArgumentError, "Could not build solr query. field: #{field}, value: #{value.inspect}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def build_array_query(field, values)
|
103
|
+
values.map { |v| build_query(field, v) }.reduce { |a, e| a.or(e) }.wrap
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_range_query(field, value)
|
107
|
+
if value.exclude_end?
|
108
|
+
new(field).greater_than_or_equal_to(value.first).less_than(value.last)
|
109
|
+
else
|
110
|
+
new(field).greater_than_or_equal_to(value.first).less_than_or_equal_to(value.last)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def build_enumerator_query(field, values)
|
115
|
+
last = nil
|
116
|
+
values.each { |v| last = v }
|
117
|
+
new(field).greater_than_or_equal_to(values.first).less_than_or_equal_to(last)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
41
121
|
# Create a new query builder instance.
|
42
122
|
#
|
43
123
|
# @param field [String] a field name
|
@@ -125,6 +205,7 @@ class LSolr
|
|
125
205
|
# @return [LSolr] self instance
|
126
206
|
def match(value)
|
127
207
|
values = clean(value).split
|
208
|
+
|
128
209
|
if values.size > 1
|
129
210
|
phrase_match(values)
|
130
211
|
else
|
@@ -135,11 +216,19 @@ class LSolr
|
|
135
216
|
|
136
217
|
# Builds a normal query expression with dates and times.
|
137
218
|
#
|
138
|
-
# @
|
219
|
+
# @see https://lucene.apache.org/solr/guide/6_6/working-with-dates.html Working with Dates
|
220
|
+
#
|
221
|
+
# @param value [String, Date, Time] a filter value
|
139
222
|
#
|
140
223
|
# @return [LSolr] self instance
|
141
224
|
def date_time_match(value)
|
142
|
-
|
225
|
+
value = if value.is_a?(Date) || value.is_a?(Time)
|
226
|
+
format_date(value)
|
227
|
+
else
|
228
|
+
clean(value, symbols: RESERVED_SYMBOLS - %w[- : . / +])
|
229
|
+
end
|
230
|
+
|
231
|
+
@value = %("#{value}")
|
143
232
|
self
|
144
233
|
end
|
145
234
|
|
@@ -165,7 +254,7 @@ class LSolr
|
|
165
254
|
#
|
166
255
|
# @return [LSolr] self instance
|
167
256
|
def phrase_match(values, distance: 0)
|
168
|
-
value = values.map { |v| clean(v).split }.flatten.join(
|
257
|
+
value = values.map { |v| clean(v).split }.flatten.join(PHRASE_MATCH_DELIMITER)
|
169
258
|
proximity_match = distance > 0 ? "#{PROXIMITY}#{distance}" : ''
|
170
259
|
@value = %("#{value}"#{proximity_match})
|
171
260
|
self
|
@@ -189,10 +278,11 @@ class LSolr
|
|
189
278
|
#
|
190
279
|
# @see https://lucene.apache.org/solr/guide/7_1/the-standard-query-parser.html#range-searches Range Searches
|
191
280
|
#
|
192
|
-
# @param value [String, Integer] a filter value
|
281
|
+
# @param value [String, Integer, Date, Time] a filter value
|
193
282
|
#
|
194
283
|
# @return [LSolr] self instance
|
195
284
|
def greater_than(value)
|
285
|
+
value = format_date(value) if value.is_a?(Date) || value.is_a?(Time)
|
196
286
|
@range_first = "#{GREATER_THAN}#{value}"
|
197
287
|
self
|
198
288
|
end
|
@@ -201,10 +291,11 @@ class LSolr
|
|
201
291
|
#
|
202
292
|
# @see https://lucene.apache.org/solr/guide/7_1/the-standard-query-parser.html#range-searches Range Searches
|
203
293
|
#
|
204
|
-
# @param value [String, Integer] a filter value
|
294
|
+
# @param value [String, Integer, Date, Time] a filter value
|
205
295
|
#
|
206
296
|
# @return [LSolr] self instance
|
207
297
|
def less_than(value)
|
298
|
+
value = format_date(value) if value.is_a?(Date) || value.is_a?(Time)
|
208
299
|
@range_last = "#{value}#{LESS_THAN}"
|
209
300
|
self
|
210
301
|
end
|
@@ -213,10 +304,11 @@ class LSolr
|
|
213
304
|
#
|
214
305
|
# @see https://lucene.apache.org/solr/guide/7_1/the-standard-query-parser.html#range-searches Range Searches
|
215
306
|
#
|
216
|
-
# @param value [String, Integer] a filter value
|
307
|
+
# @param value [String, Integer, Date, Time] a filter value
|
217
308
|
#
|
218
309
|
# @return [LSolr] self instance
|
219
310
|
def greater_than_or_equal_to(value)
|
311
|
+
value = format_date(value) if value.is_a?(Date) || value.is_a?(Time)
|
220
312
|
@range_first = "#{GREATER_THAN_OR_EQUAL_TO}#{value}"
|
221
313
|
self
|
222
314
|
end
|
@@ -225,10 +317,11 @@ class LSolr
|
|
225
317
|
#
|
226
318
|
# @see https://lucene.apache.org/solr/guide/7_1/the-standard-query-parser.html#range-searches Range Searches
|
227
319
|
#
|
228
|
-
# @param value [String, Integer] a filter value
|
320
|
+
# @param value [String, Integer, Date, Time] a filter value
|
229
321
|
#
|
230
322
|
# @return [LSolr] self instance
|
231
323
|
def less_than_or_equal_to(value)
|
324
|
+
value = format_date(value) if value.is_a?(Date) || value.is_a?(Time)
|
232
325
|
@range_last = "#{value}#{LESS_THAN_OR_EQUAL_TO}"
|
233
326
|
self
|
234
327
|
end
|
@@ -287,4 +380,16 @@ class LSolr
|
|
287
380
|
while !element.prev.nil? && element.prev.present? do element = element.prev end
|
288
381
|
element
|
289
382
|
end
|
383
|
+
|
384
|
+
def format_date(date)
|
385
|
+
msec_str = case date
|
386
|
+
when Date then date.strftime(FORMAT_MILLISECOND_FOR_DATE_TYPE).gsub(date.strftime(FORMAT_SECOND), '')
|
387
|
+
when Time then date.strftime(FORMAT_MILLISECOND_FOR_TIME_TYPE)
|
388
|
+
else raise ArgumentError, "Unknown type #{date.inspect}"
|
389
|
+
end
|
390
|
+
|
391
|
+
return date.strftime(FORMAT_DATE_TIME) if msec_str == '000'
|
392
|
+
|
393
|
+
"#{date.strftime('%Y-%m-%dT%H:%M:%S')}.#{msec_str}Z"
|
394
|
+
end
|
290
395
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lsolr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Taishi Kasuga
|
@@ -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.
|
41
|
+
rubygems_version: 2.7.3
|
42
42
|
signing_key:
|
43
43
|
specification_version: 4
|
44
44
|
summary: A query builder of Apache Solr for Ruby
|