mwmitchell-solr 0.5.5 → 0.5.6

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.
@@ -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