sunspot 0.9.8 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/History.txt +32 -0
  2. data/README.rdoc +40 -3
  3. data/TODO +10 -8
  4. data/VERSION.yml +2 -2
  5. data/bin/sunspot-configure-solr +22 -28
  6. data/bin/sunspot-solr +50 -29
  7. data/lib/sunspot/adapters.rb +1 -1
  8. data/lib/sunspot/composite_setup.rb +13 -15
  9. data/lib/sunspot/configuration.rb +14 -0
  10. data/lib/sunspot/data_extractor.rb +3 -0
  11. data/lib/sunspot/dsl/field_query.rb +33 -6
  12. data/lib/sunspot/dsl/fields.rb +14 -1
  13. data/lib/sunspot/dsl/fulltext.rb +168 -0
  14. data/lib/sunspot/dsl/query.rb +82 -5
  15. data/lib/sunspot/dsl/query_facet.rb +3 -3
  16. data/lib/sunspot/dsl/restriction.rb +7 -7
  17. data/lib/sunspot/dsl/scope.rb +17 -10
  18. data/lib/sunspot/dsl/search.rb +2 -2
  19. data/lib/sunspot/dsl.rb +2 -1
  20. data/lib/sunspot/facet.rb +9 -1
  21. data/lib/sunspot/facet_data.rb +56 -7
  22. data/lib/sunspot/facet_row.rb +2 -0
  23. data/lib/sunspot/field.rb +50 -26
  24. data/lib/sunspot/field_factory.rb +15 -0
  25. data/lib/sunspot/indexer.rb +6 -0
  26. data/lib/sunspot/instantiated_facet.rb +6 -9
  27. data/lib/sunspot/instantiated_facet_row.rb +7 -2
  28. data/lib/sunspot/query/boost_query.rb +20 -0
  29. data/lib/sunspot/query/connective.rb +98 -35
  30. data/lib/sunspot/query/dismax.rb +69 -0
  31. data/lib/sunspot/query/field_facet.rb +1 -22
  32. data/lib/sunspot/query/fulltext_base_query.rb +47 -0
  33. data/lib/sunspot/query/highlighting.rb +43 -0
  34. data/lib/sunspot/query/local.rb +24 -0
  35. data/lib/sunspot/query/pagination.rb +3 -4
  36. data/lib/sunspot/query/query.rb +93 -0
  37. data/lib/sunspot/query/query_facet.rb +14 -9
  38. data/lib/sunspot/query/query_facet_row.rb +3 -3
  39. data/lib/sunspot/query/query_field_facet.rb +10 -3
  40. data/lib/sunspot/query/restriction.rb +36 -15
  41. data/lib/sunspot/query/scope.rb +3 -159
  42. data/lib/sunspot/query/sort.rb +84 -15
  43. data/lib/sunspot/query/text_field_boost.rb +15 -0
  44. data/lib/sunspot/query.rb +2 -188
  45. data/lib/sunspot/schema.rb +7 -25
  46. data/lib/sunspot/search/highlight.rb +38 -0
  47. data/lib/sunspot/search/hit.rb +50 -3
  48. data/lib/sunspot/search.rb +51 -32
  49. data/lib/sunspot/session.rb +32 -12
  50. data/lib/sunspot/setup.rb +47 -10
  51. data/lib/sunspot/text_field_setup.rb +29 -0
  52. data/lib/sunspot/type.rb +4 -4
  53. data/lib/sunspot/util.rb +27 -1
  54. data/lib/sunspot.rb +8 -17
  55. data/solr/solr/conf/schema.xml +54 -40
  56. data/solr/solr/conf/solrconfig.xml +30 -0
  57. data/solr/solr/lib/geoapi-nogenerics-2.1-M2.jar +0 -0
  58. data/solr/solr/lib/gt2-referencing-2.3.1.jar +0 -0
  59. data/solr/solr/lib/jsr108-0.01.jar +0 -0
  60. data/solr/solr/lib/locallucene.jar +0 -0
  61. data/solr/solr/lib/localsolr.jar +0 -0
  62. data/spec/api/indexer/attributes_spec.rb +100 -0
  63. data/spec/api/indexer/batch_spec.rb +46 -0
  64. data/spec/api/indexer/dynamic_fields_spec.rb +33 -0
  65. data/spec/api/indexer/fixed_fields_spec.rb +57 -0
  66. data/spec/api/indexer/fulltext_spec.rb +43 -0
  67. data/spec/api/indexer/removal_spec.rb +46 -0
  68. data/spec/api/indexer/spec_helper.rb +1 -0
  69. data/spec/api/indexer_spec.rb +1 -308
  70. data/spec/api/query/connectives_spec.rb +162 -0
  71. data/spec/api/query/dsl_spec.rb +12 -0
  72. data/spec/api/query/dynamic_fields_spec.rb +149 -0
  73. data/spec/api/query/faceting_spec.rb +272 -0
  74. data/spec/api/query/fulltext_spec.rb +193 -0
  75. data/spec/api/query/highlighting_spec.rb +138 -0
  76. data/spec/api/query/local_spec.rb +54 -0
  77. data/spec/api/query/ordering_pagination_spec.rb +95 -0
  78. data/spec/api/query/scope_spec.rb +266 -0
  79. data/spec/api/query/spec_helper.rb +1 -0
  80. data/spec/api/query/text_field_scoping_spec.rb +30 -0
  81. data/spec/api/query/types_spec.rb +20 -0
  82. data/spec/api/search/dynamic_fields_spec.rb +27 -0
  83. data/spec/api/search/faceting_spec.rb +206 -0
  84. data/spec/api/search/highlighting_spec.rb +65 -0
  85. data/spec/api/search/hits_spec.rb +62 -0
  86. data/spec/api/search/results_spec.rb +52 -0
  87. data/spec/api/search/search_spec.rb +23 -0
  88. data/spec/api/search/spec_helper.rb +1 -0
  89. data/spec/api/spec_helper.rb +1 -1
  90. data/spec/helpers/indexer_helper.rb +29 -0
  91. data/spec/helpers/query_helper.rb +13 -0
  92. data/spec/helpers/search_helper.rb +78 -0
  93. data/spec/integration/faceting_spec.rb +1 -1
  94. data/spec/integration/highlighting_spec.rb +22 -0
  95. data/spec/integration/keyword_search_spec.rb +65 -0
  96. data/spec/integration/local_search_spec.rb +56 -0
  97. data/spec/integration/scoped_search_spec.rb +15 -1
  98. data/spec/integration/spec_helper.rb +3 -3
  99. data/spec/mocks/connection.rb +14 -1
  100. data/spec/mocks/photo.rb +1 -1
  101. data/spec/mocks/post.rb +5 -3
  102. data/spec/mocks/super_class.rb +2 -0
  103. data/spec/spec_helper.rb +13 -0
  104. data/tasks/gemspec.rake +18 -7
  105. data/tasks/schema.rake +1 -1
  106. data/tasks/spec.rake +1 -1
  107. data/templates/schema.xml.erb +36 -0
  108. metadata +117 -48
  109. data/lib/sunspot/query/base_query.rb +0 -90
  110. data/lib/sunspot/query/dynamic_query.rb +0 -69
  111. data/lib/sunspot/query/field_query.rb +0 -63
  112. data/spec/api/build_search_spec.rb +0 -1017
  113. data/spec/api/query_spec.rb +0 -153
  114. data/spec/api/search_retrieval_spec.rb +0 -362
  115. data/templates/schema.xml.haml +0 -24
@@ -1,153 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
-
3
- describe Sunspot::Query do
4
- before :each do
5
- @config ||= Sunspot::Configuration.build
6
- @connection ||= Mock::Connection.new
7
- @session ||= Sunspot::Session.new(@config, @connection)
8
- @search = @session.new_search(Post)
9
- end
10
-
11
- it 'should perform keyword search' do
12
- @search.query.keywords = 'keyword search'
13
- @search.execute!
14
- @connection.should have_last_search_with(:q => 'keyword search')
15
- end
16
-
17
- it 'should add equality restriction' do
18
- @search.query.add_restriction(:title, :equal_to, 'My Pet Post')
19
- @search.execute!
20
- @connection.should have_last_search_with(:fq => ['title_ss:My\ Pet\ Post'])
21
- end
22
-
23
- it 'should add less than restriction' do
24
- @search.query.add_restriction(:average_rating, :less_than, 3.0)
25
- @search.execute!
26
- @connection.should have_last_search_with(:fq => ['average_rating_f:[* TO 3\.0]'])
27
- end
28
-
29
- it 'should add greater than restriction' do
30
- @search.query.add_restriction(:average_rating, :greater_than, 3.0)
31
- @search.execute!
32
- @connection.should have_last_search_with(:fq => ['average_rating_f:[3\.0 TO *]'])
33
- end
34
-
35
- it 'should add between restriction' do
36
- @search.query.add_restriction(:average_rating, :between, 2.0..4.0)
37
- @search.execute!
38
- @connection.should have_last_search_with(:fq => ['average_rating_f:[2\.0 TO 4\.0]'])
39
- end
40
-
41
- it 'should add any restriction' do
42
- @search.query.add_restriction(:category_ids, :any_of, [2, 7, 12])
43
- @search.execute!
44
- @connection.should have_last_search_with(:fq => ['category_ids_im:(2 OR 7 OR 12)'])
45
- end
46
-
47
- it 'should add all restriction' do
48
- @search.query.add_restriction(:category_ids, :all_of, [2, 7, 12])
49
- @search.execute!
50
- @connection.should have_last_search_with(:fq => ['category_ids_im:(2 AND 7 AND 12)'])
51
- end
52
-
53
- it 'should negate restriction' do
54
- @search.query.add_negated_restriction(:title, :equal_to, 'Bad Post')
55
- @search.execute!
56
- @connection.should have_last_search_with(:fq => ['-title_ss:Bad\ Post'])
57
- end
58
-
59
- it 'should exclude instance' do
60
- post = Post.new
61
- @search.query.exclude_instance(post)
62
- @search.execute!
63
- @connection.should have_last_search_with(:fq => ["-id:Post\\ #{post.id}"])
64
- end
65
-
66
- it 'should paginate using default per-page' do
67
- @search.query.paginate(2)
68
- @search.execute!
69
- @connection.should have_last_search_with(:rows => 30)
70
- end
71
-
72
- it 'should paginate using provided per-page' do
73
- @search.query.paginate(4, 15)
74
- @search.execute!
75
- @connection.should have_last_search_with(:rows => 15, :start => 45)
76
- end
77
-
78
- it 'should order ascending by default' do
79
- @search.query.order_by(:average_rating)
80
- @search.execute!
81
- @connection.should have_last_search_with(:sort => 'average_rating_f asc')
82
- end
83
-
84
- it 'should order descending if specified' do
85
- @search.query.order_by(:average_rating, :desc)
86
- @search.execute!
87
- @connection.should have_last_search_with(:sort => 'average_rating_f desc')
88
- end
89
-
90
- it 'should request a field facet' do
91
- @search.query.add_field_facet(:category_ids)
92
- @search.execute!
93
- @connection.should have_last_search_with(:"facet.field" => %w(category_ids_im))
94
- end
95
-
96
- it 'should restrict by dynamic string field with equality restriction' do
97
- @search.query.dynamic_query(:custom_string).add_restriction(:test, :equal_to, 'string')
98
- @search.execute!
99
- @connection.should have_last_search_with(:fq => ['custom_string\:test_s:string'])
100
- end
101
-
102
- it 'should restrict by dynamic integer field with less than restriction' do
103
- @search.query.dynamic_query(:custom_integer).add_restriction(:test, :less_than, 1)
104
- @search.execute!
105
- @connection.should have_last_search_with(:fq => ['custom_integer\:test_i:[* TO 1]'])
106
- end
107
-
108
- it 'should restrict by dynamic float field with between restriction' do
109
- @search.query.dynamic_query(:custom_float).add_restriction(:test, :between, 2.2..3.3)
110
- @search.execute!
111
- @connection.should have_last_search_with(:fq => ['custom_float\:test_fm:[2\.2 TO 3\.3]'])
112
- end
113
-
114
- it 'should restrict by dynamic time field with any of restriction' do
115
- @search.query.dynamic_query(:custom_time).add_restriction(
116
- :test,
117
- :any_of,
118
- [Time.parse('2009-02-10 14:00:00 UTC'),
119
- Time.parse('2009-02-13 18:00:00 UTC')]
120
- )
121
- @search.execute!
122
- @connection.should have_last_search_with(
123
- :fq => ['custom_time\:test_d:(2009\-02\-10T14\:00\:00Z OR 2009\-02\-13T18\:00\:00Z)']
124
- )
125
- end
126
-
127
- it 'should restrict by dynamic boolean field with equality restriction' do
128
- @search.query.dynamic_query(:custom_boolean).add_restriction(:test, :equal_to, false)
129
- @search.execute!
130
- @connection.should have_last_search_with(:fq => ['custom_boolean\:test_b:false'])
131
- end
132
-
133
- it 'should negate a dynamic field restriction' do
134
- @search.query.dynamic_query(:custom_string).add_negated_restriction(:test, :equal_to, 'foo')
135
- @search.execute!
136
- @connection.should have_last_search_with(:fq => ['-custom_string\:test_s:foo'])
137
- end
138
-
139
- it 'should order by a dynamic field' do
140
- @search.query.dynamic_query(:custom_integer).order_by(:test, :desc)
141
- @search.execute!
142
- @connection.should have_last_search_with(:sort => 'custom_integer:test_i desc')
143
- end
144
-
145
- it 'should order by a dynamic field and static field, with given precedence' do
146
- @search.query.dynamic_query(:custom_integer).order_by(:test, :desc)
147
- @search.query.order_by(:sort_title, :asc)
148
- @search.execute!
149
- @connection.should have_last_search_with(
150
- :sort => 'custom_integer:test_i desc, sort_title_s asc'
151
- )
152
- end
153
- end
@@ -1,362 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
-
3
- describe 'retrieving search' do
4
- it 'should load search result' do
5
- post = Post.new
6
- stub_results(post)
7
- session.search(Post).results.should == [post]
8
- end
9
-
10
- it 'should load multiple search results in order' do
11
- post_1, post_2 = Post.new, Post.new
12
- stub_results(post_1, post_2)
13
- session.search(Post).results.should == [post_1, post_2]
14
- stub_results(post_2, post_1)
15
- session.search(Post).results.should == [post_2, post_1]
16
- end
17
-
18
- # This is a reduction of a crazy bug I found in production where some hits
19
- # were inexplicably not being populated.
20
- it 'properly loads results of multiple classes that have the same primary key' do
21
- Post.reset!
22
- Namespaced::Comment.reset!
23
- results = [Post.new, Namespaced::Comment.new]
24
- stub_results(*results)
25
- session.search(Post, Namespaced::Comment).results.should == results
26
- end
27
-
28
- if ENV['USE_WILL_PAGINATE']
29
-
30
- it 'should return search total as attribute of results if pagination is provided' do
31
- stub_results(Post.new, 4)
32
- session.search(Post, :page => 1).results.total_entries.should == 4
33
- end
34
-
35
- else
36
-
37
- it 'should return vanilla array if pagination is provided but WillPaginate is not available' do
38
- stub_results(Post.new)
39
- session.search(Post, :page => 1).results.should_not respond_to(:total_entries)
40
- end
41
-
42
- end
43
-
44
- it 'should return hits without loading instances' do
45
- post_1, post_2 = Array.new(2) { Post.new }
46
- stub_results(post_1, post_2)
47
- %w(load load_all).each do |message|
48
- MockAdapter::DataAccessor.should_not_receive(message)
49
- end
50
- session.search(Post).hits.map do |hit|
51
- [hit.class_name, hit.primary_key]
52
- end.should == [['Post', post_1.id.to_s], ['Post', post_2.id.to_s]]
53
- end
54
-
55
- it 'should return instance from hit' do
56
- posts = Array.new(2) { Post.new }
57
- stub_results(*posts)
58
- session.search(Post).hits.first.instance.should == posts.first
59
- end
60
-
61
- it 'should hydrate all hits when an instance is requested from a hit' do
62
- posts = Array.new(2) { Post.new }
63
- stub_results(*posts)
64
- search = session.search(Post)
65
- search.hits.first.instance
66
- %w(load load_all).each do |message|
67
- MockAdapter::DataAccessor.should_not_receive(message)
68
- end
69
- search.hits.last.instance.should == posts.last
70
- end
71
-
72
- it 'should attach score to hits' do
73
- stub_full_results('instance' => Post.new, 'score' => 1.23)
74
- session.search(Post).hits.first.score.should == 1.23
75
- end
76
-
77
- it 'should return stored field values in hits' do
78
- stub_full_results('instance' => Post.new, 'title_ss' => 'Title')
79
- session.search(Post).hits.first.stored(:title).should == 'Title'
80
- end
81
-
82
- it 'should return stored field values for searches against multiple types' do
83
- stub_full_results('instance' => Post.new, 'title_ss' => 'Title')
84
- session.search(Post, Namespaced::Comment).hits.first.stored(:title).should == 'Title'
85
- end
86
-
87
- it 'should typecast stored field values in hits' do
88
- time = Time.utc(2008, 7, 8, 2, 45)
89
- stub_full_results('instance' => Post.new, 'last_indexed_at_ds' => time.xmlschema)
90
- session.search(Post).hits.first.stored(:last_indexed_at).should == time
91
- end
92
-
93
- it 'should allow access to the data accessor' do
94
- stub_results(posts = Post.new)
95
- search = session.search Post do
96
- data_accessor_for(Post).custom_title = 'custom title'
97
- end
98
- search.results.first.title.should == 'custom title'
99
- end
100
-
101
- it 'should return total' do
102
- stub_results(Post.new, Post.new, 4)
103
- session.search(Post, :page => 1).total.should == 4
104
- end
105
-
106
- it 'should return field name for facet' do
107
- stub_facet(:title_ss, {})
108
- result = session.search Post do
109
- facet :title
110
- end
111
- result.facet(:title).field_name.should == :title
112
- end
113
-
114
- it 'should return string facet' do
115
- stub_facet(:title_ss, 'Author 1' => 2, 'Author 2' => 1)
116
- result = session.search Post do
117
- facet :title
118
- end
119
- facet_values(result, :title).should == ['Author 1', 'Author 2']
120
- end
121
-
122
- it 'should return counts for facet' do
123
- stub_facet(:title_ss, 'Author 1' => 2, 'Author 2' => 1)
124
- result = session.search Post do
125
- facet :title
126
- end
127
- facet_counts(result, :title).should == [2, 1]
128
- end
129
-
130
- it 'should return integer facet' do
131
- stub_facet(:blog_id_i, '3' => 2, '1' => 1)
132
- result = session.search Post do
133
- facet :blog_id
134
- end
135
- facet_values(result, :blog_id).should == [3, 1]
136
- end
137
-
138
- it 'should return float facet' do
139
- stub_facet(:average_rating_f, '9.3' => 2, '1.1' => 1)
140
- result = session.search Post do
141
- facet :average_rating
142
- end
143
- facet_values(result, :average_rating).should == [9.3, 1.1]
144
- end
145
-
146
- it 'should return time facet' do
147
- stub_facet(
148
- :published_at_d,
149
- '2009-04-07T20:25:23Z' => 3,
150
- '2009-04-07T20:26:19Z' => 1
151
- )
152
- result = session.search Post do
153
- facet :published_at
154
- end
155
- facet_values(result, :published_at).should ==
156
- [Time.gm(2009, 04, 07, 20, 25, 23),
157
- Time.gm(2009, 04, 07, 20, 26, 19)]
158
- end
159
-
160
- it 'should return date facet' do
161
- stub_facet(
162
- :expire_date_d,
163
- '2009-07-13T00:00:00Z' => 3,
164
- '2009-04-01T00:00:00Z' => 1
165
- )
166
- result = session.search(Post) do
167
- facet :expire_date
168
- end
169
- facet_values(result, :expire_date).should ==
170
- [Date.new(2009, 07, 13),
171
- Date.new(2009, 04, 01)]
172
- end
173
-
174
- it 'should return boolean facet' do
175
- stub_facet(:featured_b, 'true' => 3, 'false' => 1)
176
- result = session.search(Post) { facet(:featured) }
177
- facet_values(result, :featured).should == [true, false]
178
- end
179
-
180
- it 'should return class facet' do
181
- stub_facet(:class_name, 'Post' => 3, 'Namespaced::Comment' => 1)
182
- result = session.search(Post) { facet(:class) }
183
- facet_values(result, :class).should == [Post, Namespaced::Comment]
184
- end
185
-
186
- it 'should return date range facet' do
187
- stub_date_facet(:published_at_d, 60*60*24, '2009-07-08T04:00:00Z' => 2, '2009-07-07T04:00:00Z' => 1)
188
- start_time = Time.utc(2009, 7, 7, 4)
189
- end_time = start_time + 2*24*60*60
190
- result = session.search(Post) { facet(:published_at, :time_range => start_time..end_time) }
191
- facet = result.facet(:published_at)
192
- facet.rows.first.value.should == (start_time..(start_time+24*60*60))
193
- facet.rows.last.value.should == ((start_time+24*60*60)..end_time)
194
- end
195
-
196
- it 'should return query facet' do
197
- stub_query_facet(
198
- 'average_rating_f:[3\.0 TO 5\.0]' => 3,
199
- 'average_rating_f:[1\.0 TO 3\.0]' => 1
200
- )
201
- search = session.search(Post) do
202
- facet :average_rating do
203
- row 3.0..5.0 do
204
- with :average_rating, 3.0..5.0
205
- end
206
- row 1.0..3.0 do
207
- with :average_rating, 1.0..3.0
208
- end
209
- end
210
- end
211
- facet = search.facet(:average_rating)
212
- facet.rows.first.value.should == (3.0..5.0)
213
- facet.rows.first.count.should == 3
214
- facet.rows.last.value.should == (1.0..3.0)
215
- facet.rows.last.count.should == 1
216
- end
217
-
218
- it 'should return query facet specified in dynamic call' do
219
- stub_query_facet(
220
- 'custom_string\:test_s:(foo OR bar)' => 3
221
- )
222
- search = session.search(Post) do
223
- dynamic :custom_string do
224
- facet :test do
225
- row :foo_bar do
226
- with :test, %w(foo bar)
227
- end
228
- end
229
- end
230
- end
231
- facet = search.facet(:test)
232
- facet.rows.first.value.should == :foo_bar
233
- facet.rows.first.count.should == 3
234
- end
235
-
236
- it 'returns limited field facet' do
237
- stub_query_facet(
238
- 'category_ids_im:1' => 3,
239
- 'category_ids_im:3' => 1
240
- )
241
- search = session.search(Post) do
242
- facet :category_ids, :only => [1, 3, 5]
243
- end
244
- facet = search.facet(:category_ids)
245
- facet.rows.first.value.should == 1
246
- facet.rows.first.count.should == 3
247
- facet.rows.last.value.should == 3
248
- facet.rows.last.count.should == 1
249
- end
250
-
251
- it 'should return dynamic string facet' do
252
- stub_facet(:"custom_string:test_s", 'two' => 2, 'one' => 1)
253
- result = session.search(Post) { dynamic(:custom_string) { facet(:test) }}
254
- result.dynamic_facet(:custom_string, :test).rows.map { |row| row.value }.should == ['two', 'one']
255
- end
256
-
257
- it 'should return instantiated facet values' do
258
- blogs = Array.new(2) { Blog.new }
259
- stub_facet(:blog_id_i, blogs[0].id.to_s => 2, blogs[1].id.to_s => 1)
260
- result = session.search(Post) { facet(:blog_id) }
261
- result.facet(:blog_id).rows.map { |row| row.instance }.should == blogs
262
- end
263
-
264
- it 'returns instantiated facet values for limited field facet' do
265
- blogs = Array.new(2) { Blog.new }
266
- stub_query_facet(
267
- "blog_id_i:#{blogs[0].id}" => 3,
268
- "blog_id_i:#{blogs[1].id}" => 1
269
- )
270
- search = session.search(Post) do
271
- facet(:blog_id, :only => blogs.map { |blog| blog.id })
272
- end
273
- search.facet(:blog_id).rows.map { |row| row.instance }.should == blogs
274
- end
275
-
276
- it 'should only query the persistent store once for an instantiated facet' do
277
- query_count = Blog.query_count
278
- blogs = Array.new(2) { Blog.new }
279
- stub_facet(:blog_id_i, blogs[0].id.to_s => 2, blogs[1].id.to_s => 1)
280
- result = session.search(Post) { facet(:blog_id) }
281
- result.facet(:blog_id).rows.each { |row| row.instance }
282
- (Blog.query_count - query_count).should == 1
283
- end
284
-
285
- private
286
-
287
- def stub_full_results(*results)
288
- count =
289
- if results.last.is_a?(Integer) then results.pop
290
- else results.length
291
- end
292
- docs = results.map do |result|
293
- instance = result.delete('instance')
294
- result.merge('id' => "#{instance.class.name} #{instance.id}")
295
- end
296
- response = {
297
- 'response' => {
298
- 'docs' => docs,
299
- 'numFound' => count
300
- }
301
- }
302
- connection.stub!(:select).and_return(response)
303
- end
304
-
305
- def stub_results(*results)
306
- stub_full_results(
307
- *results.map do |result|
308
- if result.is_a?(Integer)
309
- result
310
- else
311
- { 'instance' => result }
312
- end
313
- end
314
- )
315
- end
316
-
317
- def stub_facet(name, values)
318
- connection.stub!(:select).and_return(
319
- 'facet_counts' => {
320
- 'facet_fields' => {
321
- name.to_s => values.to_a.sort_by { |value, count| -count }.flatten
322
- }
323
- }
324
- )
325
- end
326
-
327
- def stub_date_facet(name, gap, values)
328
- connection.stub!(:select).and_return(
329
- 'facet_counts' => {
330
- 'facet_dates' => {
331
- name.to_s => { 'gap' => "+#{gap}SECONDS" }.merge(values)
332
- }
333
- }
334
- )
335
- end
336
-
337
- def stub_query_facet(values)
338
- connection.stub!(:select).and_return(
339
- 'facet_counts' => { 'facet_queries' => values }
340
- )
341
- end
342
-
343
- def facet_values(result, field_name)
344
- result.facet(field_name).rows.map { |row| row.value }
345
- end
346
-
347
- def facet_counts(result, field_name)
348
- result.facet(field_name).rows.map { |row| row.count }
349
- end
350
-
351
- def config
352
- @config ||= Sunspot::Configuration.build
353
- end
354
-
355
- def connection
356
- @connection ||= mock('connection')
357
- end
358
-
359
- def session
360
- @session ||= Sunspot::Session.new(config, connection)
361
- end
362
- end
@@ -1,24 +0,0 @@
1
- !!! XML
2
- %schema{ :name => 'sunspot', :version => 0.9 }
3
- %types
4
- %fieldtype{ :name => 'text', :class => 'solr.TextField', :positionIncrementGap => 100 }
5
- %analyzer
6
- %tokenizer{ :class => schema.tokenizer }/
7
- - for filter in schema.filters
8
- %filter{ :class => filter }/
9
- %fieldtype{ :name => 'rand', :class => 'solr.RandomSortField' }
10
- - schema.types.each do |type|
11
- %fieldtype{ :name => type.name, :class => "solr.#{type.class_name}Field", :omitNorms => 'true' }/
12
- %fields
13
- %field{ :name => 'id', :type => 'string', :indexed => 'true', :stored => 'true', :multiValued => 'false' }/
14
- %field{ :name => 'type', :type => 'string', :indexed => 'true', :stored => 'false', :multiValued => 'true' }/
15
- %field{ :name => 'class_name', :type => 'string', :indexed => 'true', :stored => 'false', :multiValued => 'false' }/
16
- %field{ :name => 'text', :type => 'text', :indexed => 'true', :stored => 'false', :multiValued => 'true' }/
17
- %dynamicField{ :name => '*_text', :type => 'text', :indexed => 'true', :stored => 'false', :multiValued => 'true' }/
18
- %dynamicField{ :name => 'random_*', :type => 'rand', :indexed => 'true', :stored => 'false' }/
19
- - for dynamic_field in schema.dynamic_fields
20
- %dynamicField{ :name => dynamic_field.name, :type => dynamic_field.type, :indexed => 'true', :stored => dynamic_field.stored?, :multiValued => dynamic_field.multiValued? }/
21
- %uniqueKey id
22
- %defaultSearchField text
23
- %solrQueryParser{ :defaultOperator => 'AND' }/
24
- %copyField{ :source => '*_text', :dest => 'text' }/