sunspot 0.9.7
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.
- data/History.txt +83 -0
- data/LICENSE +18 -0
- data/README.rdoc +154 -0
- data/Rakefile +9 -0
- data/TODO +9 -0
- data/VERSION.yml +4 -0
- data/bin/sunspot-configure-solr +46 -0
- data/bin/sunspot-solr +62 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot.rb +469 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/composite_setup.rb +186 -0
- data/lib/sunspot/configuration.rb +38 -0
- data/lib/sunspot/data_extractor.rb +47 -0
- data/lib/sunspot/dsl.rb +3 -0
- data/lib/sunspot/dsl/field_query.rb +72 -0
- data/lib/sunspot/dsl/fields.rb +86 -0
- data/lib/sunspot/dsl/query.rb +59 -0
- data/lib/sunspot/dsl/query_facet.rb +31 -0
- data/lib/sunspot/dsl/restriction.rb +25 -0
- data/lib/sunspot/dsl/scope.rb +193 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/facet.rb +16 -0
- data/lib/sunspot/facet_data.rb +120 -0
- data/lib/sunspot/facet_row.rb +10 -0
- data/lib/sunspot/field.rb +157 -0
- data/lib/sunspot/field_factory.rb +126 -0
- data/lib/sunspot/indexer.rb +123 -0
- data/lib/sunspot/instantiated_facet.rb +42 -0
- data/lib/sunspot/instantiated_facet_row.rb +22 -0
- data/lib/sunspot/query.rb +191 -0
- data/lib/sunspot/query/base_query.rb +90 -0
- data/lib/sunspot/query/connective.rb +126 -0
- data/lib/sunspot/query/dynamic_query.rb +69 -0
- data/lib/sunspot/query/field_facet.rb +151 -0
- data/lib/sunspot/query/field_query.rb +63 -0
- data/lib/sunspot/query/pagination.rb +39 -0
- data/lib/sunspot/query/query_facet.rb +73 -0
- data/lib/sunspot/query/query_facet_row.rb +19 -0
- data/lib/sunspot/query/query_field_facet.rb +13 -0
- data/lib/sunspot/query/restriction.rb +233 -0
- data/lib/sunspot/query/scope.rb +165 -0
- data/lib/sunspot/query/sort.rb +36 -0
- data/lib/sunspot/query/sort_composite.rb +33 -0
- data/lib/sunspot/schema.rb +165 -0
- data/lib/sunspot/search.rb +219 -0
- data/lib/sunspot/search/hit.rb +66 -0
- data/lib/sunspot/session.rb +201 -0
- data/lib/sunspot/setup.rb +271 -0
- data/lib/sunspot/type.rb +200 -0
- data/lib/sunspot/util.rb +164 -0
- data/solr/etc/jetty.xml +212 -0
- data/solr/etc/webdefault.xml +379 -0
- data/solr/lib/jetty-6.1.3.jar +0 -0
- data/solr/lib/jetty-util-6.1.3.jar +0 -0
- data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr/solr/conf/elevate.xml +36 -0
- data/solr/solr/conf/protwords.txt +21 -0
- data/solr/solr/conf/schema.xml +50 -0
- data/solr/solr/conf/solrconfig.xml +696 -0
- data/solr/solr/conf/stopwords.txt +57 -0
- data/solr/solr/conf/synonyms.txt +31 -0
- data/solr/start.jar +0 -0
- data/solr/webapps/solr.war +0 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/build_search_spec.rb +1039 -0
- data/spec/api/indexer_spec.rb +311 -0
- data/spec/api/query_spec.rb +153 -0
- data/spec/api/search_retrieval_spec.rb +362 -0
- data/spec/api/session_spec.rb +157 -0
- data/spec/api/spec_helper.rb +1 -0
- data/spec/api/sunspot_spec.rb +18 -0
- data/spec/integration/dynamic_fields_spec.rb +55 -0
- data/spec/integration/faceting_spec.rb +169 -0
- data/spec/integration/keyword_search_spec.rb +83 -0
- data/spec/integration/scoped_search_spec.rb +289 -0
- data/spec/integration/spec_helper.rb +1 -0
- data/spec/integration/stored_fields_spec.rb +10 -0
- data/spec/integration/test_pagination.rb +32 -0
- data/spec/mocks/adapters.rb +32 -0
- data/spec/mocks/blog.rb +3 -0
- data/spec/mocks/comment.rb +19 -0
- data/spec/mocks/connection.rb +84 -0
- data/spec/mocks/mock_adapter.rb +30 -0
- data/spec/mocks/mock_record.rb +48 -0
- data/spec/mocks/photo.rb +8 -0
- data/spec/mocks/post.rb +73 -0
- data/spec/mocks/user.rb +8 -0
- data/spec/spec_helper.rb +47 -0
- data/tasks/gemspec.rake +25 -0
- data/tasks/rcov.rake +28 -0
- data/tasks/rdoc.rake +22 -0
- data/tasks/schema.rake +19 -0
- data/tasks/spec.rake +24 -0
- data/tasks/todo.rake +4 -0
- data/templates/schema.xml.haml +24 -0
- metadata +246 -0
@@ -0,0 +1,311 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'indexer' do
|
4
|
+
describe 'when indexing an object' do
|
5
|
+
it 'should index id' do
|
6
|
+
session.index post
|
7
|
+
connection.should have_add_with(:id => "Post #{post.id}")
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should index type' do
|
11
|
+
session.index post
|
12
|
+
connection.should have_add_with(:type => ['Post', 'MockRecord'])
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should index class name' do
|
16
|
+
session.index post
|
17
|
+
connection.should have_add_with(:class_name => 'Post')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should index the array of objects supplied' do
|
21
|
+
posts = Array.new(2) { Post.new }
|
22
|
+
session.index posts
|
23
|
+
connection.should have_add_with(
|
24
|
+
{ :id => "Post #{posts.first.id}" },
|
25
|
+
{ :id => "Post #{posts.last.id}" }
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should index an array containing more than one type of object' do
|
30
|
+
post1, comment, post2 = objects = [Post.new, Namespaced::Comment.new, Post.new]
|
31
|
+
session.index objects
|
32
|
+
connection.should have_add_with(
|
33
|
+
{ :id => "Post #{post1.id}", :type => ['Post', 'MockRecord'] },
|
34
|
+
{ :id => "Post #{post2.id}", :type => ['Post', 'MockRecord'] }
|
35
|
+
)
|
36
|
+
connection.should have_add_with(:id => "Namespaced::Comment #{comment.id}", :type => ['Namespaced::Comment', 'MockRecord'])
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should index text' do
|
40
|
+
session.index(post(:title => 'A Title', :body => 'A Post'))
|
41
|
+
connection.should have_add_with(:title_text => 'A Title', :body_text => 'A Post')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should index text with boost' do
|
45
|
+
session.index(post(:title => 'A Title'))
|
46
|
+
connection.adds.last.first.field_by_name(:title_text).attrs[:boost].should == 2
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should index multiple values for a text field' do
|
50
|
+
session.index(post(:body => %w(some title)))
|
51
|
+
connection.should have_add_with(:body_text => %w(some title))
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should index text via a virtual field' do
|
55
|
+
session.index(post(:title => 'backwards'))
|
56
|
+
connection.should have_add_with(:backwards_title_text => 'backwards'.reverse)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should correctly index a stored string attribute field' do
|
60
|
+
session.index(post(:title => 'A Title'))
|
61
|
+
connection.should have_add_with(:title_ss => 'A Title')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should correctly index an integer attribute field' do
|
65
|
+
session.index(post(:blog_id => 4))
|
66
|
+
connection.should have_add_with(:blog_id_i => '4')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should correctly index a float attribute field' do
|
70
|
+
session.index(post(:ratings_average => 2.23))
|
71
|
+
connection.should have_add_with(:average_rating_f => '2.23')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should allow indexing by a multiple-value field' do
|
75
|
+
session.index(post(:category_ids => [3, 14]))
|
76
|
+
connection.should have_add_with(:category_ids_im => ['3', '14'])
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should correctly index a time field' do
|
80
|
+
session.index(
|
81
|
+
post(:published_at => Time.parse('1983-07-08 05:00:00 -0400'))
|
82
|
+
)
|
83
|
+
connection.should have_add_with(:published_at_d => '1983-07-08T09:00:00Z')
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should correctly index a date field' do
|
87
|
+
session.index(post(:expire_date => Date.new(2009, 07, 13)))
|
88
|
+
connection.should have_add_with(:expire_date_d => '2009-07-13T00:00:00Z')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should correctly index a boolean field' do
|
92
|
+
session.index(post(:featured => true))
|
93
|
+
connection.should have_add_with(:featured_b => 'true')
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should correctly index a false boolean field' do
|
97
|
+
session.index(post(:featured => false))
|
98
|
+
connection.should have_add_with(:featured_b => 'false')
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should not index a nil boolean field' do
|
102
|
+
session.index(post)
|
103
|
+
connection.should_not have_add_with(:featured_b)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should correctly index a virtual field' do
|
107
|
+
session.index(post(:title => 'The Blog Post'))
|
108
|
+
connection.should have_add_with(:sort_title_s => 'blog post')
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should correctly index an external virtual field' do
|
112
|
+
session.index(post(:category_ids => [1, 2, 3]))
|
113
|
+
connection.should have_add_with(:primary_category_id_i => '1')
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should correctly index a field that is defined on a superclass' do
|
117
|
+
Sunspot.setup(MockRecord) { string :author_name }
|
118
|
+
session.index(post(:author_name => 'Mat Brown'))
|
119
|
+
connection.should have_add_with(:author_name_s => 'Mat Brown')
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should commit immediately after index! called' do
|
123
|
+
connection.should_receive(:add).ordered
|
124
|
+
connection.should_receive(:commit).ordered
|
125
|
+
session.index!(post)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should remove an object from the index' do
|
129
|
+
session.remove(post)
|
130
|
+
connection.should have_delete("Post #{post.id}")
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should remove an object by type and id' do
|
134
|
+
session.remove_by_id(Post, 1)
|
135
|
+
connection.should have_delete('Post 1')
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should remove an object by type and id and immediately commit' do
|
139
|
+
connection.should_receive(:delete_by_id).with('Post 1').ordered
|
140
|
+
connection.should_receive(:commit).ordered
|
141
|
+
session.remove_by_id!(Post, 1)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should remove an object from the index and immediately commit' do
|
145
|
+
connection.should_receive(:delete_by_id).ordered
|
146
|
+
connection.should_receive(:commit).ordered
|
147
|
+
session.remove!(post)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should remove everything from the index' do
|
151
|
+
session.remove_all
|
152
|
+
connection.should have_delete_by_query("type:[* TO *]")
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should remove everything from the index and immediately commit' do
|
156
|
+
connection.should_receive(:delete_by_query).ordered
|
157
|
+
connection.should_receive(:commit).ordered
|
158
|
+
session.remove_all!
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should be able to remove everything of a given class from the index' do
|
162
|
+
session.remove_all(Post)
|
163
|
+
connection.should have_delete_by_query("type:Post")
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should correctly escape namespaced classes when removing everything from the index' do
|
167
|
+
connection.should_receive(:delete_by_query).with('type:Namespaced\:\:Comment')
|
168
|
+
session.remove_all(Namespaced::Comment)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'batches' do
|
173
|
+
it 'should send all batched adds in a single request' do
|
174
|
+
posts = Array.new(2) { Post.new }
|
175
|
+
session.batch do
|
176
|
+
for post in posts
|
177
|
+
session.index(post)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
connection.adds.length.should == 1
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should add all batched adds' do
|
184
|
+
posts = Array.new(2) { Post.new }
|
185
|
+
session.batch do
|
186
|
+
for post in posts
|
187
|
+
session.index(post)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
add = connection.adds.last
|
191
|
+
connection.adds.first.map { |add| add.field_by_name(:id).value }.should ==
|
192
|
+
posts.map { |post| "Post #{post.id}" }
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should not index changes to models that happen after index call' do
|
196
|
+
post = Post.new
|
197
|
+
session.batch do
|
198
|
+
session.index(post)
|
199
|
+
post.title = 'Title'
|
200
|
+
end
|
201
|
+
connection.adds.first.first.field_by_name(:title_ss).should be_nil
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe 'dynamic fields' do
|
206
|
+
it 'should index string data' do
|
207
|
+
session.index(post(:custom_string => { :test => 'string' }))
|
208
|
+
connection.should have_add_with(:"custom_string:test_s" => 'string')
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should index integer data with virtual accessor' do
|
212
|
+
session.index(post(:category_ids => [1, 2]))
|
213
|
+
connection.should have_add_with(:"custom_integer:1_i" => '1', :"custom_integer:2_i" => '1')
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should index float data' do
|
217
|
+
session.index(post(:custom_fl => { :test => 1.5 }))
|
218
|
+
connection.should have_add_with(:"custom_float:test_fm" => '1.5')
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should index time data' do
|
222
|
+
session.index(post(:custom_time => { :test => Time.parse('2009-05-18 18:05:00 -0400') }))
|
223
|
+
connection.should have_add_with(:"custom_time:test_d" => '2009-05-18T22:05:00Z')
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'should index boolean data' do
|
227
|
+
session.index(post(:custom_boolean => { :test => false }))
|
228
|
+
connection.should have_add_with(:"custom_boolean:test_b" => 'false')
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'should index multiple values for a field' do
|
232
|
+
session.index(post(:custom_fl => { :test => [1.0, 2.1, 3.2] }))
|
233
|
+
connection.should have_add_with(:"custom_float:test_fm" => %w(1.0 2.1 3.2))
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should index document level boost using block' do
|
238
|
+
session.index(post(:ratings_average => 4.0))
|
239
|
+
connection.adds.last.first.attrs[:boost].should == 1.25
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'should index document level boost using attribute' do
|
243
|
+
session.index(Namespaced::Comment.new(:boost => 1.5))
|
244
|
+
connection.adds.last.first.attrs[:boost].should == 1.5
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should index document level boost defined statically' do
|
248
|
+
session.index(Photo.new)
|
249
|
+
connection.adds.last.first.attrs[:boost].should == 0.75
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should throw a NoMethodError only if a nonexistent type is defined' do
|
253
|
+
lambda { Sunspot.setup(Post) { string :author_name }}.should_not raise_error
|
254
|
+
lambda { Sunspot.setup(Post) { bogus :journey }}.should raise_error(NoMethodError)
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'should throw a NoMethodError if a nonexistent field argument is passed' do
|
258
|
+
lambda { Sunspot.setup(Post) { string :author_name, :bogus => :argument }}.should raise_error(ArgumentError)
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'should throw an ArgumentError if an attempt is made to index an object that has no configuration' do
|
262
|
+
lambda { session.index(Blog.new) }.should raise_error(Sunspot::NoSetupError)
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'should throw an ArgumentError if single-value field tries to index multiple values' do
|
266
|
+
lambda do
|
267
|
+
Sunspot.setup(Post) { string :author_name }
|
268
|
+
session.index(post(:author_name => ['Mat Brown', 'Matthew Brown']))
|
269
|
+
end.should raise_error(ArgumentError)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should throw a NoAdapterError if class without adapter is indexed' do
|
273
|
+
lambda { session.index(User.new) }.should raise_error(Sunspot::NoAdapterError)
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'should throw an ArgumentError if a non-word character is included in the field name' do
|
277
|
+
lambda do
|
278
|
+
Sunspot.setup(Post) { string :"bad name" }
|
279
|
+
end.should raise_error(ArgumentError)
|
280
|
+
end
|
281
|
+
|
282
|
+
private
|
283
|
+
|
284
|
+
def config
|
285
|
+
Sunspot::Configuration.build
|
286
|
+
end
|
287
|
+
|
288
|
+
def connection
|
289
|
+
@connection ||= Mock::Connection.new
|
290
|
+
end
|
291
|
+
|
292
|
+
def session
|
293
|
+
@session ||= Sunspot::Session.new(config, connection)
|
294
|
+
end
|
295
|
+
|
296
|
+
def post(attrs = {})
|
297
|
+
@post ||= Post.new(attrs)
|
298
|
+
end
|
299
|
+
|
300
|
+
def last_add
|
301
|
+
@connection.adds.last
|
302
|
+
end
|
303
|
+
|
304
|
+
def value_in_last_document_for(field_name)
|
305
|
+
@connection.adds.last.last.field_by_name(field_name).value
|
306
|
+
end
|
307
|
+
|
308
|
+
def values_in_last_document_for(field_name)
|
309
|
+
@connection.adds.last.last.fields_by_name(field_name).map { |field| field.value }
|
310
|
+
end
|
311
|
+
end
|
@@ -0,0 +1,153 @@
|
|
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
|