sunspot 0.10.5 → 0.10.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/History.txt +13 -0
  2. data/README.rdoc +3 -3
  3. data/TODO +4 -5
  4. data/VERSION.yml +1 -1
  5. data/bin/sunspot-solr +18 -6
  6. data/lib/sunspot/dsl/field_query.rb +69 -18
  7. data/lib/sunspot/dsl/fields.rb +6 -5
  8. data/lib/sunspot/dsl/fulltext.rb +57 -1
  9. data/lib/sunspot/dsl/query.rb +30 -3
  10. data/lib/sunspot/dsl/query_facet.rb +8 -3
  11. data/lib/sunspot/dsl/search.rb +1 -1
  12. data/lib/sunspot/dsl.rb +1 -1
  13. data/lib/sunspot/field_factory.rb +6 -3
  14. data/lib/sunspot/query/abstract_field_facet.rb +43 -0
  15. data/lib/sunspot/query/date_field_facet.rb +14 -0
  16. data/lib/sunspot/query/dismax.rb +26 -7
  17. data/lib/sunspot/query/field_facet.rb +2 -122
  18. data/lib/sunspot/query/highlighting.rb +17 -5
  19. data/lib/sunspot/query/query.rb +12 -23
  20. data/lib/sunspot/query/query_facet.rb +4 -66
  21. data/lib/sunspot/query.rb +5 -1
  22. data/lib/sunspot/search/date_facet.rb +35 -0
  23. data/lib/sunspot/search/facet_row.rb +27 -0
  24. data/lib/sunspot/search/field_facet.rb +44 -0
  25. data/lib/sunspot/search/hit.rb +10 -6
  26. data/lib/sunspot/search/query_facet.rb +62 -0
  27. data/lib/sunspot/search.rb +22 -44
  28. data/lib/sunspot/setup.rb +22 -7
  29. data/lib/sunspot/type.rb +4 -0
  30. data/lib/sunspot/util.rb +8 -0
  31. data/lib/sunspot.rb +7 -6
  32. data/solr/solr/conf/solrconfig.xml +1 -2
  33. data/solr/solr/lib/locallucene.jar +0 -0
  34. data/solr/solr/lib/localsolr.jar +0 -0
  35. data/spec/api/indexer/attributes_spec.rb +5 -0
  36. data/spec/api/query/faceting_spec.rb +24 -0
  37. data/spec/api/query/fulltext_spec.rb +80 -1
  38. data/spec/api/query/highlighting_spec.rb +84 -6
  39. data/spec/api/search/faceting_spec.rb +45 -9
  40. data/spec/api/search/highlighting_spec.rb +2 -2
  41. data/spec/api/search/hits_spec.rb +5 -0
  42. data/spec/integration/faceting_spec.rb +19 -0
  43. data/spec/integration/keyword_search_spec.rb +101 -4
  44. data/spec/mocks/photo.rb +3 -0
  45. data/tasks/gemspec.rake +8 -2
  46. data/tasks/rcov.rake +2 -2
  47. metadata +9 -11
  48. data/lib/sunspot/facet.rb +0 -24
  49. data/lib/sunspot/facet_data.rb +0 -169
  50. data/lib/sunspot/facet_row.rb +0 -12
  51. data/lib/sunspot/instantiated_facet.rb +0 -39
  52. data/lib/sunspot/instantiated_facet_row.rb +0 -27
  53. data/lib/sunspot/query/fulltext_base_query.rb +0 -47
  54. data/lib/sunspot/query/query_facet_row.rb +0 -19
  55. data/lib/sunspot/query/query_field_facet.rb +0 -20
@@ -128,21 +128,118 @@ describe 'keyword search' do
128
128
  Sunspot.index!(
129
129
  @posts = [
130
130
  Post.new(:title => 'Rhino', :featured => true),
131
- Post.new(:title => 'Rhino', :featured => false)
131
+ Post.new(:title => 'Rhino', :ratings_average => 3.3),
132
+ Post.new(:title => 'Rhino')
132
133
  ]
133
134
  )
134
135
  end
135
136
 
136
- it 'should assign a higher boost to the document matching the boost query' do
137
- search = Sunspot.search(Post) do
138
- keywords('rhino') do
137
+ it 'should assign a higher score to the document matching the boost query' do
138
+ search = Sunspot.search(Post) do |query|
139
+ query.keywords('rhino') do
139
140
  boost(2.0) do
140
141
  with(:featured, true)
141
142
  end
142
143
  end
144
+ query.without(@posts[1])
145
+ end
146
+ search.results.should == [@posts[0], @posts[2]]
147
+ search.hits[0].score.should > search.hits[1].score
148
+ end
149
+
150
+ it 'should assign scores in order of multiple boost query match' do
151
+ search = Sunspot.search(Post) do
152
+ keywords 'rhino' do
153
+ boost(2.0) { with(:featured, true) }
154
+ boost(1.5) { with(:average_rating).greater_than(3.0) }
155
+ end
143
156
  end
144
157
  search.results.should == @posts
145
158
  search.hits[0].score.should > search.hits[1].score
159
+ search.hits[1].score.should > search.hits[2].score
160
+ end
161
+ end
162
+
163
+ describe 'minimum match' do
164
+ before do
165
+ Sunspot.remove_all
166
+ @posts = [
167
+ Post.new(:title => 'Pepperoni Sausage Anchovies'),
168
+ Post.new(:title => 'Pepperoni Tomatoes Mushrooms')
169
+ ]
170
+ Sunspot.index!(@posts)
171
+ @search = Sunspot.search(Post) do
172
+ keywords 'pepperoni sausage extra cheese', :minimum_match => 2
173
+ end
174
+ end
175
+
176
+ it 'should match documents that contain the minimum_match number of search terms' do
177
+ @search.results.should include(@posts[0])
178
+ end
179
+
180
+ it 'should not match documents that do not contain the minimum_match number of search terms' do
181
+ @search.results.should_not include(@posts[1])
182
+ end
183
+ end
184
+
185
+ describe 'query phrase slop' do
186
+ before do
187
+ Sunspot.remove_all
188
+ @posts = [
189
+ Post.new(:title => 'One four'),
190
+ Post.new(:title => 'One three four'),
191
+ Post.new(:title => 'One two three four')
192
+ ]
193
+ Sunspot.index!(@posts)
194
+ @search = Sunspot.search(Post) do
195
+ keywords '"one four"', :query_phrase_slop => 1
196
+ end
197
+ end
198
+
199
+ it 'should match exact phrase' do
200
+ @search.results.should include(@posts[0])
201
+ end
202
+
203
+ it 'should match phrase divided by query phrase slop terms' do
204
+ @search.results.should include(@posts[1])
205
+ end
206
+
207
+ it 'should not match phrase divided by more than query phrase slop terms' do
208
+ @search.results.should_not include(@posts[2])
209
+ end
210
+ end
211
+
212
+ describe 'phrase field slop' do
213
+ before do
214
+ Sunspot.remove_all
215
+ @comments = [
216
+ Namespaced::Comment.new(:author_name => 'one four'),
217
+ Namespaced::Comment.new(:body => 'one four'),
218
+ Namespaced::Comment.new(:author_name => 'one three four'),
219
+ Namespaced::Comment.new(:body => 'one three four'),
220
+ Namespaced::Comment.new(:author_name => 'one two three four'),
221
+ Namespaced::Comment.new(:body => 'one two three four')
222
+ ]
223
+ Sunspot.index!(@comments)
224
+ @search = Sunspot.search(Namespaced::Comment) do
225
+ keywords 'one four' do
226
+ phrase_fields :author_name => 3.0
227
+ phrase_slop 1
228
+ end
229
+ end
230
+ @sorted_hits = @search.hits.sort_by { |hit| @comments.index(hit.instance) }
231
+ end
232
+
233
+ it 'should give phrase field boost to exact match' do
234
+ @sorted_hits[0].score.should > @sorted_hits[1].score
235
+ end
236
+
237
+ it 'should give phrase field boost to match within slop' do
238
+ @sorted_hits[2].score.should > @sorted_hits[3].score
239
+ end
240
+
241
+ it 'should not give phrase field boost to match beyond slop' do
242
+ @sorted_hits[4].score.should == @sorted_hits[5].score
146
243
  end
147
244
  end
148
245
  end
data/spec/mocks/photo.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  class Photo < MockRecord
2
2
  attr_accessor :caption
3
+ attr_accessor :lat
4
+ attr_accessor :lng
3
5
  end
4
6
 
5
7
  Sunspot.setup(Photo) do
6
8
  text :caption, :default_boost => 1.5
7
9
  boost 0.75
10
+ coordinates { [lat, lng] }
8
11
  end
data/tasks/gemspec.rake CHANGED
@@ -14,7 +14,7 @@ TEXT
14
14
  s.authors = ['Mat Brown', 'Peer Allan', 'Dmitriy Dzema', 'Benjamin Krause', 'Marcel de Graaf', 'Brandon Keepers', 'Peter Berkenbosch', 'Brian Atkinson', 'Tom Coleman']
15
15
  s.rubyforge_project = 'sunspot'
16
16
  s.files = FileList['[A-Z]*', '{bin,lib,spec,tasks,templates}/**/*', 'solr/{etc,lib,webapps}/**/*', 'solr/solr/{conf,lib}/*', 'solr/start.jar']
17
- s.add_dependency 'mwmitchell-rsolr', '= 0.9.6'
17
+ s.add_dependency 'rsolr', '= 0.9.6'
18
18
  s.add_dependency 'daemons', '~> 1.0'
19
19
  s.add_development_dependency 'rspec', '~> 1.1'
20
20
  s.add_development_dependency 'ruby-debug', '~> 0.10'
@@ -31,6 +31,12 @@ TEXT
31
31
  end
32
32
 
33
33
  namespace :release do
34
+ task :tag do
35
+ version = Jeweler::VersionHelper.new(File.join(File.dirname(__FILE__), '..')).to_s
36
+ `git tag -a -m "Version #{version}" v#{version}`
37
+ `git push origin v#{version}:v#{version}`
38
+ end
39
+
34
40
  desc "Release gem to RubyForge and GitHub"
35
- task :all => [:release, :"rubyforge:release:gem", :"gemcutter:release"]
41
+ task :all => [:gemspec, :tag, :"rubyforge:release:gem", :"gemcutter:release"]
36
42
  end
data/tasks/rcov.rake CHANGED
@@ -12,7 +12,7 @@ end
12
12
  namespace :rcov do
13
13
  desc 'run api specs with rcov'
14
14
  Spec::Rake::SpecTask.new('api') do |t|
15
- t.spec_files = FileList['spec/api/*_spec.rb']
15
+ t.spec_files = FileList['spec/api/**/*_spec.rb']
16
16
  t.rcov = true
17
17
  t.rcov_dir = File.join('coverage', 'api')
18
18
  t.rcov_opts.concat(['--exclude', 'spec', '--sort', 'coverage', '--only-uncovered'])
@@ -20,7 +20,7 @@ namespace :rcov do
20
20
 
21
21
  desc 'run integration specs with rcov'
22
22
  Spec::Rake::SpecTask.new('integration') do |t|
23
- t.spec_files = FileList['spec/integration/*_spec.rb']
23
+ t.spec_files = FileList['spec/integration/**/*_spec.rb']
24
24
  t.rcov = true
25
25
  t.rcov_dir = File.join('coverage', 'integration')
26
26
  t.rcov_opts.concat(['--exclude', 'spec', '--sort', 'coverage', '--only-uncovered'])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sunspot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.5
4
+ version: 0.10.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mat Brown
@@ -17,11 +17,11 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2009-10-22 00:00:00 -04:00
20
+ date: 2009-11-05 00:00:00 -05:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
24
- name: mwmitchell-rsolr
24
+ name: rsolr
25
25
  type: :runtime
26
26
  version_requirement:
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -105,27 +105,21 @@ files:
105
105
  - lib/sunspot/dsl/restriction.rb
106
106
  - lib/sunspot/dsl/scope.rb
107
107
  - lib/sunspot/dsl/search.rb
108
- - lib/sunspot/facet.rb
109
- - lib/sunspot/facet_data.rb
110
- - lib/sunspot/facet_row.rb
111
108
  - lib/sunspot/field.rb
112
109
  - lib/sunspot/field_factory.rb
113
110
  - lib/sunspot/indexer.rb
114
- - lib/sunspot/instantiated_facet.rb
115
- - lib/sunspot/instantiated_facet_row.rb
116
111
  - lib/sunspot/query.rb
112
+ - lib/sunspot/query/abstract_field_facet.rb
117
113
  - lib/sunspot/query/boost_query.rb
118
114
  - lib/sunspot/query/connective.rb
115
+ - lib/sunspot/query/date_field_facet.rb
119
116
  - lib/sunspot/query/dismax.rb
120
117
  - lib/sunspot/query/field_facet.rb
121
- - lib/sunspot/query/fulltext_base_query.rb
122
118
  - lib/sunspot/query/highlighting.rb
123
119
  - lib/sunspot/query/local.rb
124
120
  - lib/sunspot/query/pagination.rb
125
121
  - lib/sunspot/query/query.rb
126
122
  - lib/sunspot/query/query_facet.rb
127
- - lib/sunspot/query/query_facet_row.rb
128
- - lib/sunspot/query/query_field_facet.rb
129
123
  - lib/sunspot/query/restriction.rb
130
124
  - lib/sunspot/query/scope.rb
131
125
  - lib/sunspot/query/sort.rb
@@ -133,8 +127,12 @@ files:
133
127
  - lib/sunspot/query/text_field_boost.rb
134
128
  - lib/sunspot/schema.rb
135
129
  - lib/sunspot/search.rb
130
+ - lib/sunspot/search/date_facet.rb
131
+ - lib/sunspot/search/facet_row.rb
132
+ - lib/sunspot/search/field_facet.rb
136
133
  - lib/sunspot/search/highlight.rb
137
134
  - lib/sunspot/search/hit.rb
135
+ - lib/sunspot/search/query_facet.rb
138
136
  - lib/sunspot/session.rb
139
137
  - lib/sunspot/setup.rb
140
138
  - lib/sunspot/text_field_setup.rb
data/lib/sunspot/facet.rb DELETED
@@ -1,24 +0,0 @@
1
- module Sunspot
2
- class Facet
3
- def initialize(facet_data) #:nodoc:
4
- @facet_data = facet_data
5
- end
6
-
7
- #
8
- # For field facets, this is the field name. For query facets, this is the
9
- # name given to the #facet method in the DSL.
10
- #
11
- def name
12
- @facet_data.name
13
- end
14
- alias_method :field_name, :name
15
-
16
- #
17
- # Collection of FacetRow objects containing the individual values returned
18
- # by the facet.
19
- #
20
- def rows
21
- @facet_data.rows { |value, count| FacetRow.new(value, count) }
22
- end
23
- end
24
- end
@@ -1,169 +0,0 @@
1
- require 'enumerator'
2
-
3
- module Sunspot
4
- #
5
- # The FacetData classes encapsulate various sources of facet data (field
6
- # facet, # date facet, query facet), presenting a polymorphic API to the Facet
7
- # class.
8
- #
9
- module FacetData #:nodoc:all
10
- #
11
- # Base class for facet data.
12
- #
13
- class Abstract
14
- attr_reader :field #:nodoc:
15
-
16
- #
17
- # The class that the field references, if any.
18
- #
19
- def reference
20
- @field.reference if @field
21
- end
22
-
23
- #
24
- # Cast the given value to the field's type, if it has one; otherwise just
25
- # return the string.
26
- #
27
- def cast(value)
28
- if @field
29
- @field.cast(value)
30
- else
31
- value
32
- end
33
- end
34
-
35
- #
36
- # Given the raw facet row value, return what the Sunspot facet row object
37
- # should present as the value. This can be overridden by subclasses.
38
- #
39
- def row_value(value)
40
- cast(value)
41
- end
42
- end
43
-
44
- #
45
- # FieldFacetData encapsulates the data returned by field facets
46
- #
47
- class FieldFacetData < Abstract
48
- def initialize(facet_values, field)
49
- @facet_values, @field = facet_values, field
50
- end
51
-
52
- # The name of the field that contains this facet's values
53
- #
54
- # ==== Returns
55
- #
56
- # Symbol:: The field name
57
- #
58
- def name
59
- @field.name
60
- end
61
-
62
- # The rows returned for this facet.
63
- #
64
- # ==== Returns
65
- #
66
- # Array:: Collection of FacetRow objects, in the order returned by Solr
67
- #
68
- def rows
69
- @rows ||=
70
- begin
71
- rows = []
72
- @facet_values.each_slice(2) do |value, count|
73
- rows << yield(row_value(value), count)
74
- end
75
- rows
76
- end
77
- end
78
- end
79
-
80
- #
81
- # DateFacetData encapsulates facet date for date-range facets.
82
- #
83
- class DateFacetData < FieldFacetData
84
- def initialize(facet_values, field)
85
- @gap = facet_values.delete('gap')[/\+(\d+)SECONDS/,1].to_i
86
- %w(start end).each { |key| facet_values.delete(key) }
87
- super(facet_values.to_a.flatten, field)
88
- end
89
-
90
- #
91
- # Get the rows of this date facet, which are instances of DateFacetRow.
92
- # The rows will always be sorted in chronological order.
93
- #
94
- #--
95
- #
96
- # The date facet info comes back from Solr as a hash, so we need to sort
97
- # it manually. FIXME this currently assumes we want to do a "lexical"
98
- # sort, but we should support count sort as well, even if it's not a
99
- # common use case.
100
- #
101
- def rows(&block)
102
- super(&block).sort { |a, b| a.value.first <=> b.value.first }
103
- end
104
-
105
- private
106
-
107
- def row_value(value)
108
- cast(value)..(cast(value) + @gap)
109
- end
110
- end
111
-
112
- #
113
- # QueryFacetData encapsulates the data returned by a query facet.
114
- #
115
- class QueryFacetData < Abstract
116
- def initialize(outgoing_query_facet, row_data) #:nodoc:
117
- @outgoing_query_facet, @row_data = outgoing_query_facet, row_data
118
- @field = @outgoing_query_facet.field
119
- end
120
-
121
- #
122
- # Use the name defined by the user
123
- #
124
- def name
125
- outgoing_query_facet.name
126
- end
127
-
128
- #
129
- # Get the rows associated with this query facet. Returned rows are always
130
- # ordered by count.
131
- #
132
- # ==== Returns
133
- #
134
- # Array:: Collection of QueryFacetRow objects, ordered by count
135
- #
136
- def rows
137
- @rows ||=
138
- begin
139
- rows = []
140
- options = @outgoing_query_facet.options
141
- minimum_count =
142
- if options[:zeros] then 0
143
- elsif options[:minimum_count] then options[:minimum_count]
144
- else 1
145
- end
146
- for outgoing_row in @outgoing_query_facet.rows
147
- row_query = outgoing_row.to_boolean_phrase
148
- if @row_data.has_key?(row_query)
149
- row = yield(outgoing_row.label, @row_data[row_query])
150
- rows << row if row.count >= minimum_count
151
- end
152
- end
153
- if options[:sort] == :index || !options[:limit] && options[:sort] != :count
154
- if rows.all? { |row| row.value.respond_to?(:<=>) }
155
- rows.sort! { |x, y| x.value <=> y.value }
156
- end
157
- else
158
- rows.sort! { |x, y| y.count <=> x.count }
159
- end
160
- if limit = options[:limit]
161
- rows[0, limit]
162
- else
163
- rows
164
- end
165
- end
166
- end
167
- end
168
- end
169
- end
@@ -1,12 +0,0 @@
1
- module Sunspot
2
- #
3
- # This class encapsulates a facet row (value) for a facet.
4
- #
5
- class FacetRow
6
- attr_reader :value, :count
7
-
8
- def initialize(value, count) #:nodoc:
9
- @value, @count = value, count
10
- end
11
- end
12
- end
@@ -1,39 +0,0 @@
1
- module Sunspot
2
- #
3
- # InstantiatedFacet instances allow access to a model instance based on a
4
- # primary key stored in facet rows' values. The rows are hydrated lazily, but
5
- # all rows are hydrated the first time #instance is called on any of the rows.
6
- #
7
- # Instatiated facets are possible for fields which are defined with a
8
- # :references option.
9
- #
10
- # The #rows method returns InstantiatedFacetRow objects.
11
- #
12
- class InstantiatedFacet < Facet
13
- #
14
- # Hydrate all rows for the facet. For data accessors that can efficiently
15
- # batch load, this is more efficient than individually lazy-loading
16
- # instances for each row, but allows us to still stay lazy and not do work
17
- # in the persistent store if the instances are not needed.
18
- #
19
- def populate_instances! #:nodoc:
20
- ids = rows.map { |row| row.value }
21
- reference_class = Sunspot::Util.full_const_get(@facet_data.reference.to_s)
22
- accessor = Adapters::DataAccessor.create(reference_class)
23
- instance_map = accessor.load_all(ids).inject({}) do |map, instance|
24
- map[Adapters::InstanceAdapter.adapt(instance).id] = instance
25
- map
26
- end
27
- for row in rows
28
- row.instance = instance_map[row.value]
29
- end
30
- end
31
-
32
- #
33
- # A collection of InstantiatedFacetRow objects
34
- #
35
- def rows
36
- @facet_data.rows { |value, count| InstantiatedFacetRow.new(value, count, self) }
37
- end
38
- end
39
- end
@@ -1,27 +0,0 @@
1
- module Sunspot
2
- #
3
- # InstantiatedFacetRow objects represent a single value for an instantiated
4
- # facet. As well as the usual FacetRow methods, InstantedFacetRow objects
5
- # provide access to the persistent object referenced by the row's value.
6
- #
7
- class InstantiatedFacetRow < FacetRow
8
- attr_writer :instance #:nodoc:
9
-
10
- def initialize(value, count, facet) #:nodoc:
11
- super(value, count)
12
- @facet = facet
13
- end
14
-
15
- #
16
- # Get the persistent object referenced by this row's value. Instances are
17
- # batch-lazy-loaded, which means that for a given facet, all of the
18
- # instances are loaded the first time any row's instance is requested.
19
- #
20
- def instance
21
- unless defined?(@instance)
22
- @facet.populate_instances!
23
- end
24
- @instance
25
- end
26
- end
27
- end
@@ -1,47 +0,0 @@
1
- module Sunspot
2
- module Query
3
- class FulltextBaseQuery < BaseQuery #:nodoc:
4
- def initialize(keywords, options, types, setup)
5
- super(types, setup)
6
- @keywords = keywords
7
-
8
- if highlight_options = options.delete(:highlight)
9
- set_highlight(highlight_options == true ? [] : highlight_options)
10
- end
11
-
12
- if fulltext_fields = options.delete(:fields)
13
- Array(fulltext_fields).each do |field|
14
- add_fulltext_field(field)
15
- end
16
- end
17
- end
18
-
19
-
20
- private
21
-
22
- def text_fields(field_names)
23
- field_names.inject([]) do |fields, name|
24
- fields.concat(@setup.text_fields(name))
25
- end
26
- end
27
-
28
- #
29
- # Returns the names of text fields that should be queried in a keyword
30
- # search. If specific fields are requested, use those; otherwise use the
31
- # union of all fields configured for the types under search.
32
- #
33
- def query_fields
34
- @query_fields ||=
35
- begin
36
- fulltext_fields =
37
- @fulltext_fields || @setup.all_text_fields.map do |field|
38
- TextFieldBoost.new(field)
39
- end
40
- fulltext_fields.map do |fulltext_field|
41
- fulltext_field.to_boosted_field
42
- end.join(' ')
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -1,19 +0,0 @@
1
- module Sunspot
2
- module Query
3
- #
4
- # QueryFacetRow objects encapsulate restrictions for a particular
5
- # QueryFacet. They also contain a label attribute, which is used as the
6
- # value for the search result's corresponding facet row object.
7
- #
8
- # See Query::Scope for the API provided.
9
- #
10
- class QueryFacetRow < Connective::Conjunction #:nodoc:
11
- attr_reader :label
12
-
13
- def initialize(label, setup)
14
- super(setup)
15
- @label = label
16
- end
17
- end
18
- end
19
- end
@@ -1,20 +0,0 @@
1
- module Sunspot
2
- module Query
3
- #
4
- # QueryFieldFacets are used for the "restricted field facet" feature, which
5
- # allows an :only parameter for field facets, specifying a set of values in
6
- # which the searcher is interested. Since Solr does not support this feature
7
- # directly in field facets, build query facets that replicate field facet
8
- # behavior.
9
- #
10
- class QueryFieldFacet < QueryFacet #:nodoc:
11
- def initialize(field, values, options)
12
- super(field.name, options)
13
- @field = field
14
- values.each do |value|
15
- add_row(value).add_component(Restriction::EqualTo.new(field, value))
16
- end
17
- end
18
- end
19
- end
20
- end