delsolr 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -30,10 +30,10 @@ Example:
30
30
 
31
31
  c = DelSolr::Client.new(:server => 'solr1', :port => 8983)
32
32
  rsp = c.query('dismax', :query => 'mp3 player',
33
- :filters => {:cost => (50..100)},
33
+ :filters => {:cost => (50..100), :localparams => {:tag => 'cost_filter'}},
34
34
  :facets => [{:field => 'brand', :limit => 10},
35
35
  {:query => {:onsale => true, :brand => 'Apple'},
36
- :name => 'cheap_apple'}])
36
+ :localparams => {:key => 'cheap_apple', :ex => 'cost_filter'}}])
37
37
 
38
38
  # output total matches
39
39
  puts rsp.total
@@ -47,7 +47,7 @@ Example:
47
47
  end
48
48
 
49
49
  # output a query facet
50
- puts "Cheap Apple stuff: #{rsp.facet_query_count_by_name('cheap_apple')}"
50
+ puts "Cheap Apple stuff: #{rsp.facet_query_count_by_key('cheap_apple')}"
51
51
 
52
52
  # adding things
53
53
  doc = DelSolr::Document.new
@@ -60,10 +60,13 @@ Example:
60
60
  rsp = c.query('dismax', :query => 'shuffle mp3 player')
61
61
  puts rsp.ids[0]
62
62
 
63
+ # using local params for filters / facets
64
+ Use :localparams => {} syntax to add local params to filters and facets
65
+
63
66
 
64
67
  == REQUIREMENTS:
65
68
 
66
- You need Solr installed somewhere so you can query it ;)
69
+ You need Solr(1.4 or higher) installed somewhere so you can query it ;)
67
70
 
68
71
  == INSTALL:
69
72
 
@@ -1,13 +1,13 @@
1
1
  require 'cgi'
2
2
 
3
3
  module DelSolr
4
-
4
+
5
5
  class Client
6
-
6
+
7
7
  class QueryBuilder
8
-
8
+
9
9
  FL_DEFAULTS = 'id,unique_id,score' # redefine if you really want to change this.
10
-
10
+
11
11
  attr_accessor :query_name, :options
12
12
 
13
13
  # ops can basically be straight solr URL params, but it also supports some other formats
@@ -21,22 +21,17 @@ module DelSolr
21
21
  def request_string
22
22
  @request_string ||= build_request_string
23
23
  end
24
-
25
- # returns the query string of the facet query for the given query name (used for resolving counts for given queries)
26
- def facet_query_by_name(query_name)
27
- name_to_facet_query[query_name]
28
- end
29
-
30
- private
31
-
24
+
25
+ private
26
+
32
27
  def build_request_string()
33
28
  raise "query_name must be set" if query_name.blank?
34
-
29
+
35
30
  opts = self.options.dup
36
-
31
+
37
32
  # cleanup the nils
38
33
  opts.delete_if {|k,v| v.nil?}
39
-
34
+
40
35
  # resolve "rubyish" names to solr names
41
36
  opts[:q] ||= opts[:query]
42
37
  opts[:rows] ||= opts[:limit] || 10
@@ -46,9 +41,9 @@ module DelSolr
46
41
  opts[:bq] ||= opts[:boost]
47
42
  opts[:suggestionCount] ||= opts[:suggestion_count]
48
43
  opts[:onlyMorePopular] ||= opts[:only_more_popular]
49
-
44
+
50
45
  raise ":query or :q must be set" if opts[:q].nil? || opts[:q].empty?
51
-
46
+
52
47
  # clear out the "rubyish" versions, what's left will go straight to solr
53
48
  opts.delete(:query)
54
49
  opts.delete(:limit)
@@ -57,7 +52,7 @@ module DelSolr
57
52
  opts.delete(:boost)
58
53
  opts.delete(:suggestion_count)
59
54
  opts.delete(:only_more_popular)
60
-
55
+
61
56
  # needs to be an array of hashs because it's acceptable to have the same key present > once.
62
57
  params = []
63
58
 
@@ -88,7 +83,7 @@ module DelSolr
88
83
  raise 'facets must either be a Hash or an Array'
89
84
  end
90
85
  end
91
-
86
+
92
87
  # handle friendly highlight name
93
88
  if opts.delete(:highlight)
94
89
  params << {:hl => 'true'}
@@ -109,12 +104,12 @@ module DelSolr
109
104
  raise "All params should be a Hash or String"
110
105
  end
111
106
  end
112
-
107
+
113
108
  "/select?#{param_strings.join('&')}"
114
109
  end
115
-
110
+
116
111
  # returns the query param
117
- def build_query(key, queries)
112
+ def build_query(key, queries, localparams = "")
118
113
  query_string = ''
119
114
  case queries
120
115
  when String
@@ -128,7 +123,9 @@ module DelSolr
128
123
  end
129
124
  query_string = query_string_array.join(' ')
130
125
  end
131
-
126
+
127
+ query_string = localparams + query_string
128
+
132
129
  {key => query_string}
133
130
  end
134
131
 
@@ -144,7 +141,7 @@ module DelSolr
144
141
  str = "#{k}:[#{v.begin} TO #{v.end}]"
145
142
  elsif v.is_a?(String)
146
143
  if v =~ /\s/ && # if it contains a space, we may need to quote it
147
- !(v =~ /^\[.+ TO .+\]$/) # HACK: if the string is a range query, do not wrap it in quotes
144
+ !(v =~ /^\[.+ TO .+\]$/) # HACK: if the string is a range query, do not wrap it in quotes
148
145
  str = "#{k}:\"#{v}\""
149
146
  else
150
147
  str = "#{k}:#{v}"
@@ -154,10 +151,10 @@ module DelSolr
154
151
  end
155
152
  str
156
153
  end
157
-
154
+
158
155
  def build_filters(key, filters)
159
156
  params = []
160
-
157
+
161
158
  # handle "ruby-ish" filters
162
159
  case filters
163
160
  when String
@@ -167,13 +164,15 @@ module DelSolr
167
164
  params += build_filters(key, f) # recusively add all the filters in the array
168
165
  end
169
166
  when Hash
167
+ filters_local_params = build_local_params(filters['localparams'] || filters[:localparams])
170
168
  filters.each do |k,v|
171
- params << {key => key_value_pair_string(k, v)} unless v.nil?
169
+ next if ['localparams', :localparams].include?(k.to_s)
170
+ params << {key => filters_local_params + key_value_pair_string(k, v)} unless v.nil?
172
171
  end
173
172
  end
174
173
  params
175
174
  end
176
-
175
+
177
176
  def build_facets(facet_array)
178
177
  params = []
179
178
  facet_array.each do |facet_hash|
@@ -181,34 +180,53 @@ module DelSolr
181
180
  end
182
181
  params
183
182
  end
184
-
183
+
185
184
  def build_facet(facet_hash)
186
185
  params = []
187
186
  facet_name = facet_hash['name'] || facet_hash[:name]
187
+ unless facet_name.blank?
188
+ facet_hash[:localparams] ||= {}
189
+ facet_hash[:localparams][:key] ||= facet_name
190
+ end
191
+ facet_local_params = build_local_params(facet_hash['localparams'] || facet_hash[:localparams])
188
192
  facet_hash.each do |k,v|
189
193
  # handle some cases specially
190
194
  if 'field' == k.to_s
191
- params << {"facet.field" => v}
195
+ params << {"facet.field" => "#{facet_local_params}#{v}"}
192
196
  elsif 'query' == k.to_s
193
- q = build_query("facet.query", v)
194
- params << q
195
- if facet_name
196
- # keep track of names => facet_queries
197
- name_to_facet_query[facet_name] = q['facet.query']
198
- end
199
- elsif ['name', :name].include?(k.to_s)
197
+ params << build_query("facet.query", v, facet_local_params)
198
+ elsif ['localparams', :localparams, 'name', :name].include?(k.to_s)
200
199
  # do nothing
201
200
  else
202
- params << {"f.#{facet_hash[:field]}.facet.#{k}" => v}
201
+ params << {"f.#{facet_hash[:field]}.facet.#{k}" => "#{facet_local_params}#{v}"}
203
202
  end
204
203
  end
205
204
  params
206
205
  end
207
-
208
- def name_to_facet_query
209
- @name_to_facet_query ||= {}
206
+
207
+ def build_local_params_array(local_params)
208
+ local_params_array = []
209
+ case local_params
210
+ when String
211
+ local_params_array << local_params
212
+ when Array
213
+ local_params.each do |p|
214
+ local_params_array << build_local_params_array(p)
215
+ end
216
+ when Hash
217
+ local_params.each do |k,v|
218
+ local_params_array << "#{k}=#{v}"
219
+ end
220
+ end
221
+ local_params_array
210
222
  end
211
-
223
+
224
+ def build_local_params(local_params)
225
+ local_params_array = build_local_params_array(local_params)
226
+
227
+ local_params_array.empty? ? "" : "{!#{local_params_array.join(" ")}}"
228
+ end
229
+
212
230
  end
213
231
  end
214
232
  end
@@ -174,10 +174,10 @@ module DelSolr
174
174
  end
175
175
 
176
176
  # Returns the counts for a given facet_query_name
177
- def facet_query_count_by_name(facet_query_name)
178
- query_string = query_builder.facet_query_by_name(facet_query_name)
179
- facet_queries[query_string] if query_string
177
+ def facet_query_count_by_key(facet_query_key)
178
+ facet_queries[facet_query_key.to_s]
180
179
  end
180
+ alias :facet_query_count_by_name :facet_query_count_by_key
181
181
 
182
182
  # Returns the url sent to solr
183
183
  def request_url
data/lib/delsolr.rb CHANGED
@@ -100,7 +100,7 @@ module DelSolr
100
100
  #
101
101
  # c.query('standard', :query => 'abc',
102
102
  # :facets => [:query => {:city => 'seattle', :instock => true},
103
- # :name => 'seattle_instock'}])
103
+ # :prefix => {:key => 'seattle_instock'}}])
104
104
  #
105
105
  # ...will request counts for the number of documents where "seattle" matches on the "city" field and "instock" is set to true.
106
106
  # Faceting by query requires you to assign a name to the facet so the counts can easily be fetched from the response. Solr
@@ -109,7 +109,7 @@ module DelSolr
109
109
  #
110
110
  # The count for this facet query can be pulled like so:
111
111
  #
112
- # rsp.facet_query_count_by_name('seattle_instock').
112
+ # rsp.facet_query_count_by_key('seattle_instock').
113
113
  #
114
114
  # [<b><tt>:sorts</tt></b>]
115
115
  # (optional) array or string of sorts in Lucene syntax (<fieldname> <asc/desc>)
@@ -18,10 +18,10 @@ class QueryBuilderTest < Test::Unit::TestCase
18
18
  assert(qb)
19
19
 
20
20
  p = get_params(qb.request_string)
21
- assert_equal(p['start'], '3')
22
- assert_equal(p['rows'], '13')
23
- assert_equal(p['fl'], 'id')
24
- assert_equal(p['q'], 'good book')
21
+ assert_equal('3', p['start'])
22
+ assert_equal('13', p['rows'])
23
+ assert_equal('id', p['fl'])
24
+ assert_equal('good book', p['q'])
25
25
  end
26
26
 
27
27
  def test_002
@@ -36,8 +36,8 @@ class QueryBuilderTest < Test::Unit::TestCase
36
36
  assert(qb)
37
37
 
38
38
  p = get_params(qb.request_string)
39
- assert_equal(p['fl'], 'id,unique_id,score')
40
- assert_equal(p['q'], 'blahblah')
39
+ assert_equal('id,unique_id,score', p['fl'])
40
+ assert_equal('blahblah', p['q'])
41
41
  end
42
42
 
43
43
  def test_003
@@ -52,8 +52,8 @@ class QueryBuilderTest < Test::Unit::TestCase
52
52
  assert(qb)
53
53
 
54
54
  p = get_params(qb.request_string)
55
- assert_equal(p['fl'], 'id,unique_id,score')
56
- assert_equal(p['q'], 'index_type:books')
55
+ assert_equal('id,unique_id,score', p['fl'])
56
+ assert_equal('index_type:books', p['q'])
57
57
  end
58
58
 
59
59
  def test_004
@@ -68,8 +68,8 @@ class QueryBuilderTest < Test::Unit::TestCase
68
68
  assert(qb)
69
69
 
70
70
  p = get_params(qb.request_string)
71
- assert_equal(p['fq'], 'location:seattle')
72
- assert_equal(p['q'], 'index_type:books')
71
+ assert_equal('location:seattle', p['fq'])
72
+ assert_equal('index_type:books', p['q'])
73
73
  end
74
74
 
75
75
  def test_005
@@ -85,8 +85,8 @@ class QueryBuilderTest < Test::Unit::TestCase
85
85
 
86
86
  p = get_params(qb.request_string)
87
87
 
88
- assert_equal(p['fq'], 'location:seattle')
89
- assert_equal(p['q'], 'index_type:books')
88
+ assert_equal('location:seattle', p['fq'])
89
+ assert_equal('index_type:books', p['q'])
90
90
  end
91
91
 
92
92
  def test_facets_001
@@ -101,9 +101,9 @@ class QueryBuilderTest < Test::Unit::TestCase
101
101
 
102
102
  p = get_params(qb.request_string)
103
103
 
104
- assert_equal(p['facet'], 'true')
105
- assert_equal(p['facet.field'].sort, ['instock_b', 'on_sale_b'].sort)
106
- assert_equal(p['f.on_sale_b.facet.limit'], '1')
104
+ assert_equal('true', p['facet'])
105
+ assert_equal(['instock_b', 'on_sale_b'].sort, p['facet.field'].sort)
106
+ assert_equal('1', p['f.on_sale_b.facet.limit'])
107
107
  end
108
108
 
109
109
  def test_facets_002
@@ -118,11 +118,28 @@ class QueryBuilderTest < Test::Unit::TestCase
118
118
 
119
119
  p = get_params(qb.request_string)
120
120
 
121
- assert_equal(p['facet'], 'true')
122
- assert_equal(p['facet.field'], 'language_idm')
123
- assert_equal(p['facet.query'], 'city_idm:19596')
121
+ assert_equal('true', p['facet'])
122
+ assert_equal('language_idm', p['facet.field'])
123
+ assert_equal('{!key=seattle}city_idm:19596', p['facet.query'])
124
124
  end
125
-
125
+
126
+ def test_facets_003
127
+ qb = nil
128
+ opts = {}
129
+ opts[:query] = "games"
130
+ opts[:facets] = [{:query => {:city_idm => 19596}, :localparams => {:key => 'seattle', :ex => 'exclusion'}}, {:field => 'language_idm'}]
131
+
132
+ assert_nothing_raised { qb = DelSolr::Client::QueryBuilder.new('onebox-books', opts) }
133
+
134
+ assert(qb)
135
+
136
+ p = get_params(qb.request_string)
137
+
138
+ assert_equal('true', p['facet'])
139
+ assert_equal('language_idm', p['facet.field'])
140
+ assert_equal('{!key=seattle ex=exclusion}city_idm:19596', p['facet.query'])
141
+ end
142
+
126
143
  def test_range
127
144
  qb = nil
128
145
  opts = {}
@@ -135,7 +152,7 @@ class QueryBuilderTest < Test::Unit::TestCase
135
152
 
136
153
  p = get_params(qb.request_string)
137
154
 
138
- assert_equal('id:[1 TO 3]', p['fq'])
155
+ assert_equal(p['fq'], 'id:[1 TO 3]')
139
156
  end
140
157
 
141
158
 
@@ -75,7 +75,7 @@ class ResponseTest < Test::Unit::TestCase
75
75
  },
76
76
  'facet_counts'=>{
77
77
  'facet_queries'=>{
78
- 'city_idm:19596' => 392},
78
+ '19596' => 392},
79
79
  'facet_fields'=>{
80
80
  'available_b'=>[
81
81
  'false',1328],
@@ -97,7 +97,7 @@ class ResponseTest < Test::Unit::TestCase
97
97
 
98
98
  def test_001
99
99
  r = nil
100
- qb = DelSolr::Client::QueryBuilder.new('standard', :query => {:index_type => 'widget'}, :facets => {:query => 'city_idm:19596', :name => 19596} )
100
+ qb = DelSolr::Client::QueryBuilder.new('standard', :query => {:index_type => 'widget'}, :facets => {:query => 'city_idm:19596', :prefix => {:key => 19596}} )
101
101
  qb.request_string # need to generate this...
102
102
  assert_nothing_raised { r = DelSolr::Client::Response.new(@@test_001, qb) }
103
103
 
@@ -114,12 +114,12 @@ class ResponseTest < Test::Unit::TestCase
114
114
  assert_equal(1182, r.facet_field_count('onsale_b', false))
115
115
  assert_equal(174, r.facet_field_count('onsale_b', true))
116
116
  assert_equal(1328, r.facet_field_count('available_b', false))
117
- assert_equal(392, r.facet_query_count_by_name(19596))
117
+ assert_equal(392, r.facet_query_count_by_key(19596))
118
118
  end
119
119
 
120
120
  def test_shortcuts
121
121
  r = nil
122
- qb = DelSolr::Client::QueryBuilder.new('standard', :query => {:index_type => 'widget'}, :facets => {:query => 'city_idm:19596', :name => 19596} )
122
+ qb = DelSolr::Client::QueryBuilder.new('standard', :query => {:index_type => 'widget'}, :facets => {:query => 'city_idm:19596', :prefix => {:key => 19596}} )
123
123
  qb.request_string # need to generate this...
124
124
  assert_nothing_raised { r = DelSolr::Client::Response.new(@@test_001, qb, :shortcuts => [:index_type, :id]) }
125
125
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 6
9
- version: 0.0.6
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ben VandenBos