erichummel-sunspot 1.2.1 → 2.0.0.pre.111215
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/Gemfile +2 -1
- data/History.txt +30 -0
- data/Rakefile +5 -9
- data/lib/sunspot.rb +13 -3
- data/lib/sunspot/batcher.rb +62 -0
- data/lib/sunspot/class_set.rb +23 -0
- data/lib/sunspot/configuration.rb +7 -0
- data/lib/sunspot/dsl.rb +1 -1
- data/lib/sunspot/dsl/field_group.rb +57 -0
- data/lib/sunspot/dsl/field_query.rb +48 -0
- data/lib/sunspot/dsl/function.rb +13 -0
- data/lib/sunspot/dsl/paginatable.rb +5 -1
- data/lib/sunspot/dsl/restriction_with_near.rb +39 -0
- data/lib/sunspot/dsl/scope.rb +4 -4
- data/lib/sunspot/dsl/search.rb +2 -2
- data/lib/sunspot/dsl/standard_query.rb +2 -0
- data/lib/sunspot/indexer.rb +12 -7
- data/lib/sunspot/query.rb +3 -3
- data/lib/sunspot/query/bbox.rb +15 -0
- data/lib/sunspot/query/common_query.rb +13 -2
- data/lib/sunspot/query/dismax.rb +5 -1
- data/lib/sunspot/query/field_group.rb +36 -0
- data/lib/sunspot/query/geofilt.rb +16 -0
- data/lib/sunspot/query/highlighting.rb +8 -1
- data/lib/sunspot/query/pagination.rb +8 -4
- data/lib/sunspot/query/sort.rb +14 -0
- data/lib/sunspot/query/sort_composite.rb +3 -2
- data/lib/sunspot/search.rb +1 -1
- data/lib/sunspot/search/abstract_search.rb +53 -65
- data/lib/sunspot/search/field_group.rb +32 -0
- data/lib/sunspot/search/group.rb +50 -0
- data/lib/sunspot/search/hit.rb +21 -7
- data/lib/sunspot/search/hit_enumerable.rb +72 -0
- data/lib/sunspot/search/paginated_collection.rb +5 -3
- data/lib/sunspot/session.rb +3 -1
- data/lib/sunspot/type.rb +21 -0
- data/lib/sunspot/util.rb +9 -0
- data/lib/sunspot/version.rb +1 -1
- data/spec/api/batcher_spec.rb +112 -0
- data/spec/api/class_set_spec.rb +24 -0
- data/spec/api/hit_enumerable_spec.rb +47 -0
- data/spec/api/indexer/batch_spec.rb +29 -3
- data/spec/api/query/function_spec.rb +9 -0
- data/spec/api/query/group_spec.rb +32 -0
- data/spec/api/query/highlighting_examples.rb +22 -0
- data/spec/api/query/ordering_pagination_examples.rb +21 -0
- data/spec/api/query/spatial_examples.rb +27 -0
- data/spec/api/query/standard_spec.rb +1 -0
- data/spec/api/search/hits_spec.rb +11 -0
- data/spec/api/search/paginated_collection_spec.rb +10 -0
- data/spec/api/search/results_spec.rb +6 -0
- data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +0 -11
- data/spec/api/session_spec.rb +12 -0
- data/spec/api/sunspot_spec.rb +11 -0
- data/spec/helpers/indexer_helper.rb +0 -12
- data/spec/helpers/integration_helper.rb +8 -0
- data/spec/helpers/mock_session_helper.rb +13 -0
- data/spec/helpers/query_helper.rb +0 -12
- data/spec/helpers/search_helper.rb +0 -12
- data/spec/integration/dynamic_fields_spec.rb +2 -0
- data/spec/integration/faceting_spec.rb +14 -1
- data/spec/integration/field_grouping_spec.rb +66 -0
- data/spec/integration/geospatial_spec.rb +85 -0
- data/spec/integration/highlighting_spec.rb +22 -0
- data/spec/integration/indexing_spec.rb +23 -1
- data/spec/integration/keyword_search_spec.rb +1 -1
- data/spec/integration/local_search_spec.rb +1 -1
- data/spec/integration/more_like_this_spec.rb +1 -1
- data/spec/integration/scoped_search_spec.rb +1 -1
- data/spec/integration/stored_fields_spec.rb +2 -0
- data/spec/integration/test_pagination.rb +13 -2
- data/spec/integration/unicode_spec.rb +15 -0
- data/spec/mocks/connection.rb +4 -4
- data/spec/mocks/post.rb +1 -0
- data/spec/spec_helper.rb +21 -11
- data/sunspot.gemspec +42 -0
- data/tasks/rdoc.rake +2 -2
- metadata +95 -135
- data/VERSION.yml +0 -4
- data/bin/sunspot-installer +0 -19
- data/bin/sunspot-solr +0 -74
- data/installer/config/schema.yml +0 -95
- data/lib/sunspot/installer.rb +0 -31
- data/lib/sunspot/installer/library_installer.rb +0 -45
- data/lib/sunspot/installer/schema_builder.rb +0 -219
- data/lib/sunspot/installer/solrconfig_updater.rb +0 -76
- data/lib/sunspot/installer/task_helper.rb +0 -18
- data/lib/sunspot/server.rb +0 -152
- data/solr-1.3/etc/jetty.xml +0 -212
- data/solr-1.3/etc/webdefault.xml +0 -379
- data/solr-1.3/lib/jetty-6.1.3.jar +0 -0
- data/solr-1.3/lib/jetty-util-6.1.3.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr-1.3/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr-1.3/solr/conf/elevate.xml +0 -36
- data/solr-1.3/solr/conf/protwords.txt +0 -21
- data/solr-1.3/solr/conf/schema.xml +0 -64
- data/solr-1.3/solr/conf/solrconfig.xml +0 -725
- data/solr-1.3/solr/conf/stopwords.txt +0 -57
- data/solr-1.3/solr/conf/synonyms.txt +0 -31
- data/solr-1.3/solr/lib/geoapi-nogenerics-2.1-M2.jar +0 -0
- data/solr-1.3/solr/lib/gt2-referencing-2.3.1.jar +0 -0
- data/solr-1.3/solr/lib/jsr108-0.01.jar +0 -0
- data/solr-1.3/solr/lib/locallucene.jar +0 -0
- data/solr-1.3/solr/lib/localsolr.jar +0 -0
- data/solr-1.3/start.jar +0 -0
- data/solr-1.3/webapps/solr.war +0 -0
- data/solr/README.txt +0 -42
- data/solr/etc/jetty.xml +0 -218
- data/solr/etc/webdefault.xml +0 -379
- 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/.gitignore +0 -1
- data/solr/solr/README.txt +0 -54
- data/solr/solr/conf/admin-extra.html +0 -31
- data/solr/solr/conf/elevate.xml +0 -36
- data/solr/solr/conf/mapping-ISOLatin1Accent.txt +0 -246
- data/solr/solr/conf/protwords.txt +0 -21
- data/solr/solr/conf/schema.xml +0 -238
- data/solr/solr/conf/scripts.conf +0 -24
- data/solr/solr/conf/solrconfig.xml +0 -934
- data/solr/solr/conf/spellings.txt +0 -2
- data/solr/solr/conf/stopwords.txt +0 -58
- data/solr/solr/conf/synonyms.txt +0 -31
- data/solr/solr/conf/xslt/example.xsl +0 -132
- data/solr/solr/conf/xslt/example_atom.xsl +0 -67
- data/solr/solr/conf/xslt/example_rss.xsl +0 -66
- data/solr/solr/conf/xslt/luke.xsl +0 -337
- data/solr/start.jar +0 -0
- data/solr/webapps/solr.war +0 -0
- data/spec/api/server_spec.rb +0 -91
- data/spec/integration/spec_helper.rb +0 -7
@@ -1,8 +1,9 @@
|
|
1
1
|
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
describe 'batch indexing', :type => :indexer do
|
4
|
+
let(:posts) { Array.new(2) { |index| Post.new :title => "Post number #{index}!" } }
|
5
|
+
|
4
6
|
it 'should send all batched adds in a single request' do
|
5
|
-
posts = Array.new(2) { Post.new }
|
6
7
|
session.batch do
|
7
8
|
for post in posts
|
8
9
|
session.index(post)
|
@@ -12,7 +13,6 @@ describe 'batch indexing', :type => :indexer do
|
|
12
13
|
end
|
13
14
|
|
14
15
|
it 'should add all batched adds' do
|
15
|
-
posts = Array.new(2) { Post.new }
|
16
16
|
session.batch do
|
17
17
|
for post in posts
|
18
18
|
session.index(post)
|
@@ -36,11 +36,37 @@ describe 'batch indexing', :type => :indexer do
|
|
36
36
|
pending 'batching all operations'
|
37
37
|
connection.should_not_receive(:add)
|
38
38
|
connection.should_not_receive(:remove)
|
39
|
-
posts = Array.new(2) { Post.new }
|
40
39
|
session.batch do
|
41
40
|
session.index(posts[0])
|
42
41
|
session.remove(posts[1])
|
43
42
|
end
|
44
43
|
connection.adds
|
45
44
|
end
|
45
|
+
|
46
|
+
describe "nesting of batches" do
|
47
|
+
let(:a_nested_batch) do
|
48
|
+
session.batch do
|
49
|
+
session.index posts[0]
|
50
|
+
|
51
|
+
session.batch do
|
52
|
+
session.index posts[1]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "behaves like two sets of batches, does the inner first, then outer" do
|
58
|
+
session.batch { session.index posts[1] }
|
59
|
+
session.batch { session.index posts[0] }
|
60
|
+
|
61
|
+
two_sets_of_batches_adds = connection.adds.dup
|
62
|
+
connection.adds.clear
|
63
|
+
|
64
|
+
a_nested_batch
|
65
|
+
nested_batches_adds = connection.adds
|
66
|
+
|
67
|
+
nested_batches_adds.first.first.field_by_name(:title_ss).value.should eq(
|
68
|
+
two_sets_of_batches_adds.first.first.field_by_name(:title_ss).value
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
46
72
|
end
|
@@ -36,6 +36,15 @@ describe 'function query' do
|
|
36
36
|
end
|
37
37
|
connection.should have_last_search_including(:bf, 'product(average_rating_ft,10)')
|
38
38
|
end
|
39
|
+
|
40
|
+
it "should handle the sub function in a function query block" do
|
41
|
+
session.search Post do
|
42
|
+
keywords('pizza') do
|
43
|
+
boost(function { sub(:average_rating, 10) })
|
44
|
+
end
|
45
|
+
end
|
46
|
+
connection.should have_last_search_including(:bf, 'sub(average_rating_ft,10)')
|
47
|
+
end
|
39
48
|
|
40
49
|
it "should handle nested functions in a function query block" do
|
41
50
|
session.search Post do
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "field grouping" do
|
4
|
+
it "sends grouping parameters to solr" do
|
5
|
+
session.search Post do
|
6
|
+
group :title
|
7
|
+
end
|
8
|
+
|
9
|
+
connection.should have_last_search_including(:group, "true")
|
10
|
+
connection.should have_last_search_including(:"group.field", "title_ss")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "sends grouping limit parameters to solr" do
|
14
|
+
session.search Post do
|
15
|
+
group :title do
|
16
|
+
limit 2
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
connection.should have_last_search_including(:"group.limit", 2)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "sends grouping sort parameters to solr" do
|
24
|
+
session.search Post do
|
25
|
+
group :title do
|
26
|
+
order_by :average_rating
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
connection.should have_last_search_including(:"group.sort", "average_rating_ft asc")
|
31
|
+
end
|
32
|
+
end
|
@@ -220,4 +220,26 @@ shared_examples_for "query with highlighting support" do
|
|
220
220
|
:"f.body_textsv.hl.snippets" => 1
|
221
221
|
)
|
222
222
|
end
|
223
|
+
|
224
|
+
it 'sets the formatter for highlight output' do
|
225
|
+
search do
|
226
|
+
keywords 'test' do
|
227
|
+
highlight :title, :formatter => 'formatter'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
connection.should have_last_search_with(
|
231
|
+
:"f.title_text.hl.formatter" => 'formatter'
|
232
|
+
)
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'sets the text snippet generator for highlighted text' do
|
236
|
+
search do
|
237
|
+
keywords 'test' do
|
238
|
+
highlight :title, :fragmenter => 'example_fragmenter'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
connection.should have_last_search_with(
|
242
|
+
:"f.title_text.hl.fragmenter" => 'example_fragmenter'
|
243
|
+
)
|
244
|
+
end
|
223
245
|
end
|
@@ -25,6 +25,20 @@ shared_examples_for 'sortable query' do
|
|
25
25
|
connection.should have_last_search_with(:rows => 15, :start => 0)
|
26
26
|
end
|
27
27
|
|
28
|
+
it 'paginates with an offset' do
|
29
|
+
search do
|
30
|
+
paginate :per_page => 15, :offset => 3
|
31
|
+
end
|
32
|
+
connection.should have_last_search_with(:rows => 15, :start => 3)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'paginates with an offset as a string' do
|
36
|
+
search do
|
37
|
+
paginate :per_page => 15, :offset => '3'
|
38
|
+
end
|
39
|
+
connection.should have_last_search_with(:rows => 15, :start => 3)
|
40
|
+
end
|
41
|
+
|
28
42
|
it 'paginates from string argument' do
|
29
43
|
search do
|
30
44
|
paginate :page => '3', :per_page => '15'
|
@@ -61,6 +75,13 @@ shared_examples_for 'sortable query' do
|
|
61
75
|
connection.should have_last_search_with(:sort => 'score desc')
|
62
76
|
end
|
63
77
|
|
78
|
+
it 'orders by geodist' do
|
79
|
+
search do
|
80
|
+
order_by_geodist :coordinates_new, 32, -68, :desc
|
81
|
+
end
|
82
|
+
connection.should have_last_search_with(:sort => 'geodist(coordinates_new_ll,32,-68) desc')
|
83
|
+
end
|
84
|
+
|
64
85
|
it 'throws an ArgumentError if a bogus order direction is given' do
|
65
86
|
lambda do
|
66
87
|
search do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
shared_examples_for "spatial query" do
|
4
|
+
it 'filters by radius' do
|
5
|
+
search do
|
6
|
+
with(:coordinates_new).in_radius(23, -46, 100)
|
7
|
+
end
|
8
|
+
|
9
|
+
connection.should have_last_search_including(:fq, "{!geofilt sfield=coordinates_new_ll pt=23,-46 d=100}")
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'filters by radius via bbox (inexact)' do
|
13
|
+
search do
|
14
|
+
with(:coordinates_new).in_radius(23, -46, 100, :bbox => true)
|
15
|
+
end
|
16
|
+
|
17
|
+
connection.should have_last_search_including(:fq, "{!bbox sfield=coordinates_new_ll pt=23,-46 d=100}")
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'filters by bounding box' do
|
21
|
+
search do
|
22
|
+
with(:coordinates_new).in_bounding_box([45, -94], [46, -93])
|
23
|
+
end
|
24
|
+
|
25
|
+
connection.should have_last_search_including(:fq, "coordinates_new_ll:[45,-94 TO 46,-93]")
|
26
|
+
end
|
27
|
+
end
|
@@ -11,6 +11,7 @@ describe 'standard query', :type => :query do
|
|
11
11
|
it_should_behave_like "sortable query"
|
12
12
|
it_should_behave_like "query with text field scoping"
|
13
13
|
it_should_behave_like "geohash query"
|
14
|
+
it_should_behave_like "spatial query"
|
14
15
|
|
15
16
|
it 'adds a no-op query to :q parameter when no :q provided' do
|
16
17
|
session.search Post do
|
@@ -32,6 +32,12 @@ describe 'hits', :type => :search do
|
|
32
32
|
session.search(Post).hits.first.instance.should == posts.first
|
33
33
|
end
|
34
34
|
|
35
|
+
it 'should return the instance primary key when you use it as a param' do
|
36
|
+
posts = Array.new(2) { Post.new }
|
37
|
+
stub_results(*posts)
|
38
|
+
session.search(Post).hits.first.to_param.should == posts.first.id.to_s
|
39
|
+
end
|
40
|
+
|
35
41
|
it 'should provide iterator over hits with instances' do
|
36
42
|
posts = Array.new(2) { Post.new }
|
37
43
|
stub_results(*posts)
|
@@ -102,6 +108,11 @@ describe 'hits', :type => :search do
|
|
102
108
|
session.search(Post, Namespaced::Comment).hits.first.stored(:featured).should be_true
|
103
109
|
end
|
104
110
|
|
111
|
+
it 'should return stored boolean fields that evaluate to false' do
|
112
|
+
stub_full_results('instance' => Post.new, 'featured_bs' => false)
|
113
|
+
session.search(Post, Namespaced::Comment).hits.first.stored(:featured).should == false
|
114
|
+
end
|
115
|
+
|
105
116
|
it 'should return stored dynamic fields' do
|
106
117
|
stub_full_results('instance' => Post.new, 'custom_string:test_ss' => 'Custom')
|
107
118
|
session.search(Post, Namespaced::Comment).hits.first.stored(:custom_string, :test).should == 'Custom'
|
@@ -14,6 +14,16 @@ describe "PaginatedCollection" do
|
|
14
14
|
it { subject.next_page.should eql(2) }
|
15
15
|
it { subject.out_of_bounds?.should_not be_true }
|
16
16
|
it { subject.offset.should eql(0) }
|
17
|
+
|
18
|
+
it 'should allow setting total_count' do
|
19
|
+
subject.total_count = 1
|
20
|
+
subject.total_count.should eql(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should allow setting total_entries' do
|
24
|
+
subject.total_entries = 1
|
25
|
+
subject.total_entries.should eql(1)
|
26
|
+
end
|
17
27
|
end
|
18
28
|
|
19
29
|
context "behaves like Kaminari" do
|
@@ -42,6 +42,12 @@ describe 'search results', :type => :search do
|
|
42
42
|
session.search(Post) { paginate(:page => 1) }.total.should == 4
|
43
43
|
end
|
44
44
|
|
45
|
+
it 'returns query time' do
|
46
|
+
stub_nil_results
|
47
|
+
connection.response['responseHeader'] = { 'QTime' => 42 }
|
48
|
+
session.search(Post) { paginate(:page => 1) }.query_time.should == 42
|
49
|
+
end
|
50
|
+
|
45
51
|
it 'returns total for nil search' do
|
46
52
|
stub_nil_results
|
47
53
|
session.search(Post).total.should == 0
|
@@ -25,17 +25,6 @@ describe Sunspot::SessionProxy::ThreadLocalSessionProxy do
|
|
25
25
|
@proxy.session.should_not eql(proxy2.session)
|
26
26
|
end
|
27
27
|
|
28
|
-
it 'should garbage collect session instance when proxy dereferenced' do
|
29
|
-
ref = WeakRef.new(@proxy.session)
|
30
|
-
@proxy = nil
|
31
|
-
GC.start
|
32
|
-
# need to do this a second time since the reference to the session is
|
33
|
-
# destroyed in the finalizer during the first GC run, and thus isn't picked
|
34
|
-
# up by that run.
|
35
|
-
GC.start
|
36
|
-
lambda { ref.inspect }.should raise_error(WeakRef::RefError)
|
37
|
-
end
|
38
|
-
|
39
28
|
(Sunspot::Session.public_instance_methods(false) - ['config', :config]).each do |method|
|
40
29
|
it "should delegate #{method.inspect} to its session" do
|
41
30
|
args = Array.new(Sunspot::Session.instance_method(method).arity.abs) do
|
data/spec/api/session_spec.rb
CHANGED
@@ -85,6 +85,18 @@ describe 'Session' do
|
|
85
85
|
Sunspot.commit
|
86
86
|
connection.opts[:url].should == 'http://127.0.0.1:8981/solr'
|
87
87
|
end
|
88
|
+
|
89
|
+
it 'should open a connection with custom read timeout' do
|
90
|
+
Sunspot.config.solr.read_timeout = 0.5
|
91
|
+
Sunspot.commit
|
92
|
+
connection.opts[:read_timeout].should == 0.5
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should open a connection with custom open timeout' do
|
96
|
+
Sunspot.config.solr.open_timeout = 0.5
|
97
|
+
Sunspot.commit
|
98
|
+
connection.opts[:open_timeout].should == 0.5
|
99
|
+
end
|
88
100
|
end
|
89
101
|
|
90
102
|
context 'custom session' do
|
data/spec/api/sunspot_spec.rb
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
describe Sunspot do
|
4
|
+
|
5
|
+
describe "setup" do
|
6
|
+
it "should register the class in Sunspot.searchable" do
|
7
|
+
Sunspot.setup(Blog) do
|
8
|
+
text :name
|
9
|
+
end
|
10
|
+
Sunspot.searchable.should_not be_empty
|
11
|
+
Sunspot.searchable.should include(Blog)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
describe "reset!" do
|
5
16
|
it "should reset current session" do
|
6
17
|
old_session = Sunspot.send(:session)
|
@@ -1,16 +1,4 @@
|
|
1
1
|
module IndexerHelper
|
2
|
-
def config
|
3
|
-
Sunspot::Configuration.build
|
4
|
-
end
|
5
|
-
|
6
|
-
def connection
|
7
|
-
@connection ||= Mock::Connection.new
|
8
|
-
end
|
9
|
-
|
10
|
-
def session
|
11
|
-
@session ||= Sunspot::Session.new(config, connection)
|
12
|
-
end
|
13
|
-
|
14
2
|
def post(attrs = {})
|
15
3
|
@post ||= Post.new(attrs)
|
16
4
|
end
|
@@ -1,16 +1,4 @@
|
|
1
1
|
module QueryHelper
|
2
|
-
def config
|
3
|
-
@config ||= Sunspot::Configuration.build
|
4
|
-
end
|
5
|
-
|
6
|
-
def connection
|
7
|
-
@connection ||= Mock::Connection.new
|
8
|
-
end
|
9
|
-
|
10
|
-
def session
|
11
|
-
@session ||= Sunspot::Session.new(config, connection)
|
12
|
-
end
|
13
|
-
|
14
2
|
def get_filter_tag(boolean_query)
|
15
3
|
connection.searches.last[:fq].each do |fq|
|
16
4
|
if match = fq.match(/^\{!tag=(.+)\}#{Regexp.escape(boolean_query)}$/)
|
@@ -65,16 +65,4 @@ module SearchHelper
|
|
65
65
|
def facet_counts(result, field_name)
|
66
66
|
result.facet(field_name).rows.map { |row| row.count }
|
67
67
|
end
|
68
|
-
|
69
|
-
def config
|
70
|
-
@config ||= Sunspot::Configuration.build
|
71
|
-
end
|
72
|
-
|
73
|
-
def connection
|
74
|
-
@connection ||= Mock::Connection.new
|
75
|
-
end
|
76
|
-
|
77
|
-
def session
|
78
|
-
@session ||= Sunspot::Session.new(config, connection)
|
79
|
-
end
|
80
68
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
describe 'search faceting' do
|
4
4
|
def self.test_field_type(name, attribute, field, *args)
|
@@ -134,6 +134,19 @@ describe 'search faceting' do
|
|
134
134
|
search.facet(:title).rows.first.value.should == :none
|
135
135
|
search.facet(:title).rows.first.count.should == 1
|
136
136
|
end
|
137
|
+
|
138
|
+
it 'gives correct facet count when group == true and truncate == true' do
|
139
|
+
search = Sunspot.search(Post) do
|
140
|
+
group :title do
|
141
|
+
truncate
|
142
|
+
end
|
143
|
+
|
144
|
+
facet :title, :extra => :any
|
145
|
+
end
|
146
|
+
|
147
|
+
# Should be 5 instead of 11
|
148
|
+
search.facet(:title).rows.first.count.should == 5
|
149
|
+
end
|
137
150
|
end
|
138
151
|
|
139
152
|
context 'multiselect faceting' do
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
|
+
require File.expand_path("../helpers/search_helper", File.dirname(__FILE__))
|
3
|
+
|
4
|
+
describe "field grouping" do
|
5
|
+
before :each do
|
6
|
+
Sunspot.remove_all
|
7
|
+
|
8
|
+
@posts = [
|
9
|
+
Post.new(:title => "Title1", :ratings_average => 4),
|
10
|
+
Post.new(:title => "Title1", :ratings_average => 5),
|
11
|
+
Post.new(:title => "Title2", :ratings_average => 3)
|
12
|
+
]
|
13
|
+
|
14
|
+
Sunspot.index!(*@posts)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allows grouping by a field" do
|
18
|
+
search = Sunspot.search(Post) do
|
19
|
+
group :title
|
20
|
+
end
|
21
|
+
|
22
|
+
search.group(:title).groups.should include { |g| g.value == "Title1" }
|
23
|
+
search.group(:title).groups.should include { |g| g.value == "Title2" }
|
24
|
+
end
|
25
|
+
|
26
|
+
it "provides access to the number of matches before grouping" do
|
27
|
+
search = Sunspot.search(Post) do
|
28
|
+
group :title
|
29
|
+
end
|
30
|
+
|
31
|
+
search.group(:title).matches.should == @posts.length
|
32
|
+
end
|
33
|
+
|
34
|
+
it "allows grouping by multiple fields" do
|
35
|
+
search = Sunspot.search(Post) do
|
36
|
+
group :title, :sort_title
|
37
|
+
end
|
38
|
+
|
39
|
+
search.group(:title).groups.should_not be_empty
|
40
|
+
search.group(:sort_title).groups.should_not be_empty
|
41
|
+
end
|
42
|
+
|
43
|
+
it "allows specification of the number of documents per group" do
|
44
|
+
search = Sunspot.search(Post) do
|
45
|
+
group :title do
|
46
|
+
limit 2
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
title1_group = search.group(:title).groups.detect { |g| g.value == "Title1" }
|
51
|
+
title1_group.hits.length.should == 2
|
52
|
+
end
|
53
|
+
|
54
|
+
it "allows specification of the sort within groups" do
|
55
|
+
search = Sunspot.search(Post) do
|
56
|
+
group :title do
|
57
|
+
order_by(:average_rating, :desc)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
highest_ranked_post = @posts.sort_by { |p| -p.ratings_average }.first
|
62
|
+
|
63
|
+
title1_group = search.group(:title).groups.detect { |g| g.value == "Title1" }
|
64
|
+
title1_group.hits.first.primary_key.to_i.should == highest_ranked_post.id
|
65
|
+
end
|
66
|
+
end
|