mwmitchell-solr 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,27 +1,28 @@
1
+ 0.5.6 - December 30, 2008
2
+ solr.gemspec cleanedup thanks to shairontoledo on github! :)
3
+ Added Solr::Response::Query::Facet module with helpers from the delsolr project
4
+ Also added test stub in test/connection/search_ext_test_methods.rb
5
+ Fixed pagination math errors
6
+ Added new SearchExt helper field: :phrase_filters
7
+ This will add quoted values to the :filters (fq solr param) hash for doing easier facet requests
8
+
9
+ Be sure to check out the new demo app: http://github.com/mwmitchell/consuminator/tree/master
10
+
1
11
  0.5.5 - December 29, 2008
2
-
3
12
  Fixed bug where accessing a field by method name failed:
4
-
5
13
  docs.each do |doc|
6
14
  doc.timestamp
7
15
  end
8
-
9
16
  Fixed bug where using the #has? method on a doc failed:
10
-
11
17
  docs.each do |doc|
12
18
  doc.has?('timestamp')
13
19
  end
14
-
15
20
  Removed invalid autoload in Solr module
16
-
17
21
  Fixed spelling error in Solr::Connection::SearchExt (thanks to matthewrudy)
18
22
 
19
23
  0.5.4 - December 29, 2008
20
-
21
24
  Re-organized the main Solr adapters, they're now in Solr::Connection::Adapter instead of Solr::Adapter
22
-
23
25
  All responses from HTTPClient and Connection::Adapter::Direct return a hash with the following keys:
24
-
25
26
  :status_code
26
27
  :body
27
28
  :params
@@ -29,18 +30,12 @@
29
30
  :path
30
31
  :headers
31
32
  :data
32
-
33
33
  This hash is now available in the solr response objects as #source - this will be useful in testing and debugging by allowing you to see the generated params and queries... example:
34
-
35
34
  response = Solr.query(:q=>'*:*')
36
35
  response.source[:params]
37
36
  response.source[:body]
38
37
  response.source[:url]
39
-
40
38
  Added MultiValue field support in Solr::Message, thanks to Fouad Mardini
41
-
42
39
  Bug in Solr::Connection::SearchExt where the :q params was not getting generated - fixed by Fouad Mardini
43
-
44
40
  Organized tests a bit, moved connection tests into test/connection
45
-
46
41
  Fixed a bug in Solr::Connection::Adapter::HTTP where invalid HTTP POST headers were being generated
@@ -7,7 +7,7 @@ proc {|base, files|
7
7
 
8
8
  module Solr
9
9
 
10
- VERSION = '0.5.5'
10
+ VERSION = '0.5.6'
11
11
 
12
12
  autoload :Message, 'solr/message'
13
13
  autoload :Response, 'solr/response'
@@ -103,10 +103,11 @@ class Solr::Connection::Base
103
103
  Solr::Message
104
104
  end
105
105
 
106
- def modify_params_for_pagination(params)
107
- return params unless params[:page]
108
- params = params.dup # be nice
109
- params[:per_page]||=10
106
+ def modify_params_for_pagination(orig_params)
107
+ return orig_params unless orig_params[:page] || orig_params[:per_page]
108
+ params = orig_params.dup # be nice
109
+ params[:page] ||= 1
110
+ params[:per_page] ||= 10
110
111
  params[:rows] = params.delete(:per_page).to_i
111
112
  params[:start] = calculate_start(params.delete(:page).to_i, params[:rows])
112
113
  params
@@ -6,6 +6,18 @@ module Solr::Connection::SearchExt
6
6
  params[:fl] = fields.is_a?(Array) ? fields.join(' ') : fields
7
7
  end
8
8
 
9
+ # adds quoted values to the :filters hash
10
+ if params[:phrase_filters]
11
+ phrase_filters = params.delete(:phrase_filters)
12
+ params[:filters] ||= {}
13
+ phrase_filters.each do |filter,values|
14
+ params[:filters][filter] ||= []
15
+ values.each do |v|
16
+ params[:filters][filter] << "\"#{v}\""
17
+ end
18
+ end
19
+ end
20
+
9
21
  params[:fq] = build_filters(params.delete(:filters)) if params[:filters]
10
22
  facets = params.delete(:facets) if params[:facets]
11
23
 
@@ -19,11 +19,15 @@ module Solr::Mapper
19
19
  # returns an array with one or more mapped hashes
20
20
  def map(source, override_mapping=nil)
21
21
  source = [source] if source.is_a?(Hash)
22
- m = override_mapping || @mapping
22
+ mapping = override_mapping || @mapping
23
+ index = -1
24
+ # collect a bunch of hashes...
23
25
  source.collect do |src|
24
- m.inject({}) do |mapped_data, (field_name, mapped_value)|
25
- value = mapped_field_value(src, mapped_value)
26
- value.to_s.empty? ? mapped_data : mapped_data.merge!({field_name=>value})
26
+ index += 1
27
+ # for each mapping item, inject data into a new hash
28
+ mapping.inject({}) do |a_new_hash, (map_key, map_value)|
29
+ value = mapped_field_value(src, map_value, index)
30
+ value.to_s.empty? ? a_new_hash : a_new_hash.merge!({map_key=>value})
27
31
  end
28
32
  end
29
33
  end
@@ -31,20 +35,20 @@ module Solr::Mapper
31
35
  protected
32
36
 
33
37
  # This is a hook method useful for subclassing
34
- def source_field_value(source, field_name)
38
+ def source_field_value(source, field_name, index)
35
39
  source[field_name]
36
40
  end
37
41
 
38
- def mapped_field_value(source, mapped_value)
42
+ def mapped_field_value(source, mapped_value, index)
39
43
  case mapped_value
40
44
  when String
41
45
  mapped_value
42
46
  when Symbol
43
- source_field_value(source, mapped_value)
47
+ source_field_value(source, mapped_value, index)
44
48
  when Proc
45
- mapped_value.call(source, self)
49
+ mapped_value.call(source, index)
46
50
  when Enumerable
47
- mapped_value.collect {|key| source_field_value(source, key)}.flatten
51
+ mapped_value.collect {|key| source_field_value(source, key, index)}.flatten
48
52
  else
49
53
  # try to turn it into a string, else raise UnkownMappingValue
50
54
  mapped_value.respond_to?(:to_s) ? mapped_value.to_s : raise(UnkownMappingValue.new(mapped_value))
@@ -20,9 +20,9 @@ class Solr::Mapper::RSS < Solr::Mapper::Base
20
20
  # sends methods chain down into the @rss object
21
21
  # example: :'channel.title' == @rss.channel.title
22
22
  # if the method chain doesn't exist, the super #source_field_value method is called
23
- def source_field_value(source, method_path)
23
+ def source_field_value(source, method_path, index)
24
24
  method_path.to_s.split('.').inject(@rss) do |rss, m|
25
- rss.respond_to?(m) ? rss.send(m.to_sym) : super(source, method_path)
25
+ rss.respond_to?(m) ? rss.send(m.to_sym) : super(source, method_path, index)
26
26
  end
27
27
  end
28
28
 
@@ -28,7 +28,7 @@ class Solr::Message
28
28
  sorted_items = item.inject({}) {|acc,(k,v)| acc.merge({k.to_s=>v})}
29
29
  sorted_items.keys.sort.each do |k|
30
30
  doc_attrs = {:name=>k}
31
- yield doc_attrs if block_given?
31
+ yield item, doc_attrs if block_given?
32
32
  [sorted_items[k]].flatten.each do |v| # multiValued attributes
33
33
  doc_xml.field(v, doc_attrs)
34
34
  end
@@ -33,36 +33,109 @@ module Solr::Response::Query
33
33
 
34
34
  end
35
35
 
36
+ # from the delsolr project -> http://github.com/avvo/delsolr/tree/master/lib/delsolr/response.rb
37
+ module Facets
38
+
39
+ def facets
40
+ @facets ||= data['facet_counts'] || {}
41
+ end
42
+
43
+ # Returns the hash of all the facet_fields (ie: {'instock_b' => ['true', 123, 'false', 20]}
44
+ def facet_fields
45
+ @facet_fields ||= facets['facet_fields'] || {}
46
+ end
47
+
48
+ # Returns all of the facet queries
49
+ def facet_queries
50
+ @facet_queries ||= facets['facet_queries'] || {}
51
+ end
52
+
53
+ # Returns a hash of hashs rather than a hash of arrays (ie: {'instock_b' => {'true' => 123', 'false', => 20} })
54
+ def facet_fields_by_hash
55
+ @facet_fields_by_hash ||= begin
56
+ f = {}
57
+ if facet_fields
58
+ facet_fields.each do |field,value_and_counts|
59
+ f[field] = {}
60
+ value_and_counts.each_with_index do |v, i|
61
+ if i % 2 == 0
62
+ f[field][v] = value_and_counts[i+1]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ f
68
+ end
69
+ end
70
+
71
+ # Returns an array of value/counts for a given field (ie: ['true', 123, 'false', 20]
72
+ def facet_field(field)
73
+ facet_fields[field.to_s]
74
+ end
75
+
76
+ # Returns the array of field values for the given field in the order they were returned from solr
77
+ def facet_field_values(field)
78
+ facet_field_values ||= {}
79
+ facet_field_values[field.to_s] ||= begin
80
+ a = []
81
+ return unless facet_field(field)
82
+ facet_field(field).each_with_index do |val_or_count, i|
83
+ a << val_or_count if i % 2 == 0 && facet_field(field)[i+1] > 0
84
+ end
85
+ a
86
+ end
87
+ end
88
+
89
+ # Returns a hash of value/counts for a given field (ie: {'true' => 123, 'false' => 20}
90
+ def facet_field_by_hash(field)
91
+ facet_fields_by_hash[field.to_s]
92
+ end
93
+
94
+ # Returns the count for the given field/value pair
95
+ def facet_field_count(field, value)
96
+ facet_fields_by_hash[field.to_s][value.to_s] if facet_fields_by_hash[field.to_s]
97
+ end
98
+
99
+ # Returns the counts for a given facet_query_name
100
+ def facet_query_count_by_name(facet_query_name)
101
+ query_string = query_builder.facet_query_by_name(facet_query_name)
102
+ facet_queries[query_string] if query_string
103
+ end
104
+
105
+ end
106
+
107
+ #
108
+ #
109
+ #
36
110
  module Pagination
37
111
 
38
112
  # alias to the Solr param, 'rows'
39
113
  def per_page
40
- @per_page = params['rows'].to_s.to_i
114
+ @per_page ||= params['rows'].to_s.to_i
41
115
  end
42
116
 
43
117
  # Returns the current page calculated from 'rows' and 'start'
44
118
  # WillPaginate hook
45
119
  def current_page
46
- @current_page = self.per_page > 0 ? ((self.start / self.per_page).ceil) : 1
47
- @current_page == 0 ? 1 : @current_page
120
+ @current_page ||= (self.start / self.per_page).ceil + 1
48
121
  end
49
122
 
50
123
  # Calcuates the total pages from 'numFound' and 'rows'
51
124
  # WillPaginate hook
52
125
  def total_pages
53
- self.per_page > 0 ? (self.total / self.per_page.to_f).ceil : 1
126
+ @total_pages ||= self.per_page > 0 ? (self.total / self.per_page.to_f).ceil : 1
54
127
  end
55
128
 
56
129
  # returns the previous page number or 1
57
130
  # WillPaginate hook
58
131
  def previous_page
59
- (current_page > 1) ? current_page - 1 : 1
132
+ @previous_page ||= (current_page > 1) ? current_page - 1 : 1
60
133
  end
61
134
 
62
135
  # returns the next page number or the last
63
136
  # WillPaginate hook
64
137
  def next_page
65
- (current_page < total_pages) ? current_page + 1 : total_pages
138
+ @next_page ||= (current_page < total_pages) ? current_page + 1 : total_pages
66
139
  end
67
140
 
68
141
  end
@@ -74,6 +147,7 @@ module Solr::Response::Query
74
147
  class Base < Solr::Response::Base
75
148
 
76
149
  include Solr::Response::Query::Pagination
150
+ include Solr::Response::Query::Facets
77
151
 
78
152
  attr_reader :response, :docs, :num_found, :start
79
153
 
@@ -0,0 +1,17 @@
1
+ raise 'Not yet implemented!'
2
+
3
+ module SearchExtTestMethods
4
+
5
+ def test_facet_response_methods
6
+ @response.facets
7
+ @response.facet_fields
8
+ @response.facet_queries
9
+ @response.facet_fields_by_hash
10
+ @response.facet_field(:feed_language_facet)
11
+ @response.facet_field_values(:feed_language_facet)
12
+ @response.facet_field_by_hash(:feed_language_facet)
13
+ @response.facet_field_by_hash(:feed_language_facet)
14
+ @response.facet_field_count(:feed_title_facet, 'ScienceDaily: Latest Science News')
15
+ end
16
+
17
+ end
@@ -18,6 +18,11 @@ class MapperTest < Test::Unit::TestCase
18
18
  assert_equal expected, mapper.map(data)
19
19
  end
20
20
 
21
+ # TODO
22
+ def test_add_and_set_doc_attributes
23
+ assert false
24
+ end
25
+
21
26
  # test enumerable/array mappings
22
27
  def test_array_multi_value
23
28
  data = {
@@ -40,8 +45,8 @@ class MapperTest < Test::Unit::TestCase
40
45
  def test_proc
41
46
  data = [{:name=>'-bach;'}]
42
47
  mapping = {
43
- :name=>proc{|d,mapper|
44
- assert_equal Solr::Mapper::Base, mapper.class
48
+ :name=>proc{|d,index|
49
+ assert_equal Fixnum, index.class
45
50
  d[:name].gsub(/\W+/, '')
46
51
  }
47
52
  }
@@ -63,10 +68,10 @@ class MapperTest < Test::Unit::TestCase
63
68
  :channel=>rss.channel.title,
64
69
  :url=>rss.channel.link,
65
70
  :total=>rss.items.size,
66
- :title=>proc {|item,m| item.title },
67
- :link=>proc{|item,m| item.link },
68
- :published=>proc{|item,m| item.date },
69
- :description=>proc{|item,m| item.description }
71
+ :title=>proc {|item,index| item.title },
72
+ :link=>proc{|item,index| item.link },
73
+ :published=>proc{|item,index| item.date },
74
+ :description=>proc{|item,index| item.description }
70
75
  }
71
76
  mapper = Solr::Mapper::Base.new(mapping)
72
77
  mapper.map(rss.items)
@@ -81,10 +86,10 @@ class MapperTest < Test::Unit::TestCase
81
86
  :channel=>:'channel.title',
82
87
  :url=>:'channel.link',
83
88
  :total=>:'items.size',
84
- :title=>proc {|item,m| item.title },
85
- :link=>proc {|item,m| item.link },
86
- :published=>proc {|item,m| item.date },
87
- :description=>proc {|item,m| item.description }
89
+ :title=>proc {|item,index| item.title },
90
+ :link=>proc {|item,index| item.link },
91
+ :published=>proc {|item,index| item.date },
92
+ :description=>proc {|item,index| item.description }
88
93
  }
89
94
  m.map(rss_file, mapping)
90
95
  end
@@ -51,7 +51,7 @@ class PaginationTest < Test::Unit::TestCase
51
51
  assert_equal response.params['rows'], response.per_page
52
52
  assert_equal 26, response.total
53
53
  # 2 per page, currently on the 10th item
54
- assert_equal 1, response.current_page
54
+ assert_equal 2, response.current_page
55
55
  assert_equal 9, response.total_pages
56
56
  end
57
57
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mwmitchell-solr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Mitchell
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-29 00:00:00 -08:00
12
+ date: 2008-12-30 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -27,8 +27,11 @@ executables: []
27
27
 
28
28
  extensions: []
29
29
 
30
- extra_rdoc_files: []
31
-
30
+ extra_rdoc_files:
31
+ - LICENSE
32
+ - Rakefile
33
+ - README.rdoc
34
+ - CHANGES.txt
32
35
  files:
33
36
  - examples/http.rb
34
37
  - examples/direct.rb
@@ -89,6 +92,7 @@ test_files:
89
92
  - test/connection/direct_test.rb
90
93
  - test/connection/http_test.rb
91
94
  - test/connection/test_methods.rb
95
+ - test/connection/search_ext_test_methods.rb
92
96
  - test/core_ext_test
93
97
  - test/http_client/curb_test.rb
94
98
  - test/http_client/net_http_test.rb