solr_lite 0.0.9 → 0.0.10

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
  SHA256:
3
- metadata.gz: e3b829f8f239974df1f4e84eff2803d00210c7ee60561cd353b7a9174ff6dd96
4
- data.tar.gz: 35fcb552f2ad0384b4ae9312287791f4fc46850aa130852efe19a5adfdea6a69
3
+ metadata.gz: 72f7691a991ab4b1e073a57a357586676ba2406b2d237bb0645daa4a3afb4a29
4
+ data.tar.gz: 262d3a594d470b3968a9197bf7e4f7d806c39930562f906f2e067c492041678e
5
5
  SHA512:
6
- metadata.gz: 4eacb399b8c0afadf285d706b736612684a82d06acae08929688d87cbf95c5035cc3dfc7bcab3fe9157960f68e5ee7477b4f57c3fa3324cdc212a805342ba5e2
7
- data.tar.gz: 61a6fba302260f1d992346196e5cf0ea9f5651dd890f2ec4583cbdbbbdbf2daff30df7f14931824a9e1ed5cd80499a56631bf4576570771a2f036d5e5d9f202c
6
+ metadata.gz: 3bc6667f32f3ca2bb0adf22c73e90ec99b37189236ba0c72156d361dcf96423208809907c121679de3e5042ead3a6280fe4956bcbef7644bf125aed376e49b29
7
+ data.tar.gz: '02904a6967e638370c1218fe4c2621c6e61e11a64169c55dd2ff8fb30c2443f440246382b19f22e594169b699da90954d6b234061547c33607be5ae72c63c4eb'
data/lib/facet_field.rb CHANGED
@@ -2,30 +2,51 @@ module SolrLite
2
2
  class FacetField
3
3
 
4
4
  class FacetValue
5
- attr_accessor :text, :count, :remove_url, :add_url
5
+ attr_accessor :text, :count, :remove_url, :add_url, :range_start, :range_end
6
6
  def initialize(text = "", count = 0, remove_url = nil)
7
7
  @text = text
8
8
  @count = count
9
9
  @remove_url = remove_url
10
10
  @add_url = nil
11
+ @range_start = nil
12
+ @range_end = nil
11
13
  end
12
14
  end
13
15
 
14
- attr_accessor :name, :title, :values
16
+ attr_accessor :name, :title, :values,
17
+ :range, :range_start, :range_end, :range_gap
18
+
15
19
  def initialize(name, display_value)
16
20
  @name = name # field name in Solr
17
21
  @title = display_value
18
22
  @values = []
23
+ @ranges = []
24
+ @range = false
25
+ @range_start = nil
26
+ @range_end = nil
27
+ @range_gap = nil
19
28
  end
20
29
 
21
30
  def to_qs(text)
22
31
  "#{@name}|#{CGI.escape(text)}"
23
32
  end
24
33
 
34
+ def to_qs_range(range_start, range_end)
35
+ "#{@name}^#{range_start},#{range_end}"
36
+ end
37
+
25
38
  def add_value(text, count)
26
39
  @values << FacetValue.new(text, count)
27
40
  end
28
41
 
42
+ def add_range(range_start, range_end, count)
43
+ text = "#{range_start} - #{range_end}"
44
+ value = FacetValue.new(text, count)
45
+ value.range_start = range_start
46
+ value.range_end = range_end
47
+ @values << value
48
+ end
49
+
29
50
  def value_count(text)
30
51
  v = @values.find {|v| v.text == text}
31
52
  return 0 if v == nil
data/lib/filter_query.rb CHANGED
@@ -8,22 +8,19 @@ module SolrLite
8
8
  attr_accessor :field, :value, :solr_value, :qs_value, :form_value
9
9
  attr_accessor :title, :remove_url
10
10
 
11
- def initialize(field, values)
12
- @field = field
13
- @value = values.join("|")
14
- @solr_value = to_solr_fq_value(field, values)
15
- @qs_value = "#{field}"
16
- values.each do |v|
17
- @qs_value += "|#{CGI.escape(v)}" # URL friendly (no : or quotes)
11
+ def initialize(field, values, is_range = false)
12
+ if is_range
13
+ init_from_range(field, values.first)
14
+ else
15
+ init_from_values(field, values)
18
16
  end
19
- @form_value = "#{field}|#{@value}" # HTML Form friendly (no encoding, the form auto-encodes on POST)
20
- @title = field # default to field name
21
- @remove_url = nil
22
17
  end
23
18
 
24
19
  # qs is assumed to be the value taken from the query string
25
20
  # in the form `field|value` or `field|value1|valueN`.
26
21
  #
22
+ # For range values the format is: `field^start,end`
23
+ #
27
24
  # Sometimes(*) the string comes URL encoded, for example:
28
25
  # `field|hello`
29
26
  # `field|hello%20world`
@@ -32,9 +29,19 @@ module SolrLite
32
29
  # (*) Values coming from HTML forms submitted via HTTP POST tend
33
30
  # to be encoded slighly different than value submitted via
34
31
  # HTTP GET requests.
32
+ #
33
+ # TODO: Should I remove support for multi-values
34
+ # (e.g. `field|value1|valueN`) since we are
35
+ # not using them? It will make the code here
36
+ # and in init_from_values() cleaner.
35
37
  def self.from_query_string(qs)
38
+ is_range = false
36
39
  tokens = CGI.unescape(qs).split("|")
37
- return nil if tokens.count < 2
40
+ if tokens.count < 2
41
+ tokens = CGI.unescape(qs).split("^")
42
+ return nil if tokens.count != 2
43
+ is_range = true
44
+ end
38
45
  field = ""
39
46
  values = []
40
47
  tokens.each_with_index do |token, i|
@@ -44,7 +51,7 @@ module SolrLite
44
51
  values << token
45
52
  end
46
53
  end
47
- FilterQuery.new(field, values)
54
+ FilterQuery.new(field, values, is_range)
48
55
  end
49
56
 
50
57
  private
@@ -52,6 +59,8 @@ module SolrLite
52
59
  # an array of values. Handles single and multi-value gracefully.
53
60
  # For single-value it returns "(field:value)". For multi-value
54
61
  # it returns "(field:value1) OR (field:value2)"
62
+ #
63
+ # TODO: Should multivalue use an AND instead of an OR?
55
64
  def to_solr_fq_value(field, values)
56
65
  solr_value = ""
57
66
  values.each_with_index do |v, i|
@@ -64,5 +73,39 @@ module SolrLite
64
73
  # Very important to escape the : otherwise URL.parse throws an error in Linux
65
74
  CGI.escape(solr_value)
66
75
  end
76
+
77
+ def to_solr_fq_value_range(field, range_start, range_end)
78
+ solr_value = '(' + field + ':[' + range_start + ' TO ' + range_end + '])'
79
+ # Very important to escape the : otherwise URL.parse throws an error in Linux
80
+ CGI.escape(solr_value)
81
+ end
82
+
83
+ # range_string is expected in the form "start,end"
84
+ def init_from_range(field, range_string)
85
+ @field = field
86
+ tokens = (range_string || "").split(",")
87
+ return nil if tokens.count != 2
88
+ range_start = tokens[0]
89
+ range_end = tokens[1]
90
+ @value = "#{range_start} - #{range_end}"
91
+ @solr_value = to_solr_fq_value_range(field, range_start, range_end)
92
+ @qs_value = "#{field}^#{range_string}"
93
+ @form_value = "#{field}^#{range_string}" # HTML Form friendly (no encoding, the form auto-encodes on POST)
94
+ @title = field # default to field name
95
+ @remove_url = nil
96
+ end
97
+
98
+ def init_from_values(field, values)
99
+ @field = field
100
+ @value = values.join("|")
101
+ @solr_value = to_solr_fq_value(field, values)
102
+ @qs_value = "#{field}"
103
+ values.each do |v|
104
+ @qs_value += "|#{CGI.escape(v)}" # URL friendly (no : or quotes)
105
+ end
106
+ @form_value = "#{field}|#{@value}" # HTML Form friendly (no encoding, the form auto-encodes on POST)
107
+ @title = field # default to field name
108
+ @remove_url = nil
109
+ end
67
110
  end # class
68
111
  end # module
data/lib/response.rb CHANGED
@@ -135,6 +135,7 @@ module SolrLite
135
135
 
136
136
  def set_facet_values()
137
137
  return if @solr_response["facet_counts"] == nil
138
+ solr_ranges = @solr_response["facet_counts"]["facet_ranges"] || {}
138
139
  solr_facets = @solr_response["facet_counts"]["facet_fields"]
139
140
  solr_facets.each do |solr_facet|
140
141
  # solr_facet is an array with two elements, e.g.
@@ -144,16 +145,33 @@ module SolrLite
144
145
  # the second element is an array with of value/count pairs (PEOPLE/32, ORG/4)
145
146
  field_name = solr_facet[0]
146
147
  facet_field = @params.facet_for_field(field_name)
147
- values = solr_facet[1]
148
- pairs = values.count/2
149
- for pair in (1..pairs)
150
- index = (pair-1) * 2
151
- text = values[index]
152
- count = values[index+1]
153
- facet_field.add_value(text, count)
148
+ if facet_field.range
149
+ # Use the range values as the facet values.
150
+ #
151
+ # Notice that we are overloading the "values" field and therefore
152
+ # we lose (i.e. don't store) the actual facet values and their counts.
153
+ # We might want to rethink this and keep them both.
154
+ values = solr_ranges[facet_field.name]["counts"] || []
155
+ pairs_count = values.count/2
156
+ for pair in (1..pairs_count)
157
+ index = (pair-1) * 2
158
+ start_range = values[index].to_i
159
+ end_range = start_range + facet_field.range_gap - 1
160
+ count = values[index+1]
161
+ facet_field.add_range(start_range, end_range, count)
162
+ end
163
+ else
164
+ # Regular facet values
165
+ values = solr_facet[1]
166
+ pairs = values.count/2
167
+ for pair in (1..pairs)
168
+ index = (pair-1) * 2
169
+ text = values[index]
170
+ count = values[index+1]
171
+ facet_field.add_value(text, count)
172
+ end
154
173
  end
155
174
  end
156
- # TODO: make sure we sort the FacetField.VALUES descending by count
157
175
  end
158
176
 
159
177
  def explainer()
data/lib/search_params.rb CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  require "filter_query.rb"
2
3
  require "facet_field.rb"
3
4
  module SolrLite
@@ -158,21 +159,27 @@ module SolrLite
158
159
  if @q != ""
159
160
  qs += "&q=#{@q}"
160
161
  end
162
+
163
+ # Filter query
161
164
  @fq.each do |filter|
162
165
  qs += "&fq=#{filter.solr_value}"
163
166
  end
167
+
164
168
  extra_fqs.each do |filter|
165
169
  qs += "&fq=#{filter.solr_value}"
166
170
  end
171
+
167
172
  qs += "&rows=#{@page_size}"
168
173
  qs += "&start=#{start_row()}"
169
174
  if sort != ""
170
175
  qs += "&sort=#{CGI.escape(@sort)}"
171
176
  end
177
+
172
178
  if @spellcheck
173
179
  qs += "&spellcheck=on"
174
180
  end
175
- # hit highlighting parameters
181
+
182
+ # Hit highlighting parameters
176
183
  if @hl
177
184
  qs += "&hl=true"
178
185
  if @hl_fl != nil
@@ -182,16 +189,31 @@ module SolrLite
182
189
  qs += "&hl.snippets=#{@hl_snippets}"
183
190
  end
184
191
  end
192
+
193
+ # Facets
185
194
  if @facets.count > 0
186
195
  qs += "&facet=on"
196
+
197
+ facet_ranges = @facets.select {|f| f.range == true }.map { |f| f.name }
198
+ facet_ranges.each do |field_name|
199
+ qs += "&facet.range=#{field_name}"
200
+ end
201
+
187
202
  @facets.each do |f|
188
203
  qs += "&facet.field=#{f.name}"
189
204
  qs += "&f.#{f.name}.facet.mincount=1"
190
205
  if @facet_limit != nil
191
206
  qs += "&f.#{f.name}.facet.limit=#{@facet_limit}"
192
207
  end
208
+
209
+ if f.range
210
+ qs += "&f.#{f.name}.facet.range.start=#{f.range_start}"
211
+ qs += "&f.#{f.name}.facet.range.end=#{f.range_end}"
212
+ qs += "&f.#{f.name}.facet.range.gap=#{f.range_gap}"
213
+ end
193
214
  end
194
215
  end
216
+
195
217
  qs
196
218
  end
197
219
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solr_lite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hector Correa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-14 00:00:00.000000000 Z
11
+ date: 2019-01-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A lightweight gem to connect to Solr and run queries. Requires no extra
14
14
  dependencies.