outoftime-sunspot 0.0.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/README.rdoc +26 -33
- data/TODO +7 -0
- data/VERSION.yml +2 -2
- data/lib/light_config.rb +5 -5
- data/lib/sunspot/adapters.rb +209 -33
- data/lib/sunspot/configuration.rb +25 -10
- data/lib/sunspot/dsl/fields.rb +42 -11
- data/lib/sunspot/dsl/query.rb +150 -6
- data/lib/sunspot/dsl/scope.rb +16 -26
- data/lib/sunspot/facet.rb +37 -0
- data/lib/sunspot/facet_row.rb +34 -0
- data/lib/sunspot/facets.rb +21 -0
- data/lib/sunspot/field.rb +112 -56
- data/lib/sunspot/indexer.rb +49 -46
- data/lib/sunspot/query.rb +217 -49
- data/lib/sunspot/restriction.rb +158 -14
- data/lib/sunspot/search.rb +79 -28
- data/lib/sunspot/session.rb +75 -8
- data/lib/sunspot/setup.rb +171 -0
- data/lib/sunspot/type.rb +116 -32
- data/lib/sunspot/util.rb +141 -7
- data/lib/sunspot.rb +260 -31
- data/spec/api/build_search_spec.rb +139 -33
- data/spec/api/indexer_spec.rb +33 -2
- data/spec/api/search_retrieval_spec.rb +85 -2
- data/spec/api/session_spec.rb +14 -6
- data/spec/integration/faceting_spec.rb +39 -0
- data/spec/integration/keyword_search_spec.rb +1 -1
- data/spec/integration/scoped_search_spec.rb +175 -0
- data/spec/mocks/mock_adapter.rb +7 -10
- data/spec/mocks/post.rb +7 -2
- data/tasks/rdoc.rake +7 -0
- data/tasks/spec.rake +3 -0
- data/tasks/todo.rake +4 -0
- metadata +12 -7
- data/lib/sunspot/builder.rb +0 -78
- data/spec/api/standard_search_builder_spec.rb +0 -76
- data/spec/custom_expectation.rb +0 -53
- data/spec/integration/field_types_spec.rb +0 -62
@@ -27,15 +27,79 @@ describe 'retrieving search' do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
it 'should return raw results without loading instances' do
|
31
|
+
post_1, post_2 = Array.new(2) { Post.new }
|
32
|
+
stub_results(post_1, post_2)
|
33
|
+
%w(load load_all).each { |message| MockAdapter::DataAccessor.should_not_receive(message) }
|
34
|
+
session.search(Post, :page => 1).raw_results.map do |raw_result|
|
35
|
+
[raw_result.class_name, raw_result.primary_key]
|
36
|
+
end.should == [['Post', post_1.id.to_s], ['Post', post_2.id.to_s]]
|
37
|
+
end
|
38
|
+
|
30
39
|
it 'should return total' do
|
31
40
|
stub_results(Post.new, Post.new, 4)
|
32
41
|
session.search(Post, :page => 1).total.should == 4
|
33
42
|
end
|
34
43
|
|
44
|
+
it 'should return field name for facet' do
|
45
|
+
stub_facet(:title_s, {})
|
46
|
+
result = session.search Post do
|
47
|
+
facet :title
|
48
|
+
end
|
49
|
+
result.facet(:title).field_name.should == :title
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should return string facet' do
|
53
|
+
stub_facet(:title_s, 'Author 1' => 2, 'Author 2' => 1)
|
54
|
+
result = session.search Post do
|
55
|
+
facet :title
|
56
|
+
end
|
57
|
+
facet_values(result, :title).should == ['Author 1', 'Author 2']
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should return counts for facet' do
|
61
|
+
stub_facet(:title_s, 'Author 1' => 2, 'Author 2' => 1)
|
62
|
+
result = session.search Post do
|
63
|
+
facet :title
|
64
|
+
end
|
65
|
+
facet_counts(result, :title).should == [2, 1]
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should return integer facet' do
|
69
|
+
stub_facet(:blog_id_i, '3' => 2, '1' => 1)
|
70
|
+
result = session.search Post do
|
71
|
+
facet :blog_id
|
72
|
+
end
|
73
|
+
facet_values(result, :blog_id).should == [3, 1]
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should return float facet' do
|
77
|
+
stub_facet(:average_rating_f, '9.3' => 2, '1.1' => 1)
|
78
|
+
result = session.search Post do
|
79
|
+
facet :average_rating
|
80
|
+
end
|
81
|
+
facet_values(result, :average_rating).should == [9.3, 1.1]
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should return time facet' do
|
85
|
+
stub_facet(:published_at_d, '2009-04-07T20:25:23Z' => 3, '2009-04-07T20:26:19Z' => 1)
|
86
|
+
result = session.search Post do
|
87
|
+
facet :published_at
|
88
|
+
end
|
89
|
+
facet_values(result, :published_at).should == [Time.gm(2009, 04, 07, 20, 25, 23),
|
90
|
+
Time.gm(2009, 04, 07, 20, 26, 19)]
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should return boolean facet' do
|
94
|
+
stub_facet(:featured_b, 'true' => 3, 'false' => 1)
|
95
|
+
result = session.search(Post) { facet(:featured) }
|
96
|
+
facet_values(result, :featured).should == [true, false]
|
97
|
+
end
|
98
|
+
|
35
99
|
private
|
36
100
|
|
37
101
|
def stub_results(*results)
|
38
|
-
total_hits = if results.last.is_a?(Integer) then results.pop
|
102
|
+
total_hits = if results.last.is_a?(Integer) then results.pop
|
39
103
|
else results.length
|
40
104
|
end
|
41
105
|
response = mock('response')
|
@@ -44,9 +108,28 @@ describe 'retrieving search' do
|
|
44
108
|
connection.stub!(:query).and_return(response)
|
45
109
|
end
|
46
110
|
|
111
|
+
def stub_facet(name, values)
|
112
|
+
response = mock('response')
|
113
|
+
facets = values.map do |data, count|
|
114
|
+
value = Solr::Response::Standard::FacetValue.new
|
115
|
+
value.name = data
|
116
|
+
value.value = count
|
117
|
+
value
|
118
|
+
end.sort_by { |value| -value.value }
|
119
|
+
response.stub!(:field_facets).with(name.to_s).and_return(facets)
|
120
|
+
connection.stub!(:query).and_return(response)
|
121
|
+
end
|
122
|
+
|
123
|
+
def facet_values(result, field_name)
|
124
|
+
result.facet(field_name).rows.map { |row| row.value }
|
125
|
+
end
|
126
|
+
|
127
|
+
def facet_counts(result, field_name)
|
128
|
+
result.facet(field_name).rows.map { |row| row.count }
|
129
|
+
end
|
130
|
+
|
47
131
|
def config
|
48
132
|
@config ||= Sunspot::Configuration.build
|
49
|
-
|
50
133
|
end
|
51
134
|
|
52
135
|
def connection
|
data/spec/api/session_spec.rb
CHANGED
@@ -4,41 +4,49 @@ describe 'Session' do
|
|
4
4
|
context 'using singleton session' do
|
5
5
|
before :each do
|
6
6
|
Sunspot.reset!
|
7
|
-
connection.should_receive(:add)
|
7
|
+
connection.should_receive(:add).twice
|
8
|
+
connection.should_receive(:commit).twice
|
8
9
|
connection.should_receive(:query)
|
9
10
|
end
|
10
11
|
|
11
12
|
it 'should open connection with defaults if nothing specified' do
|
12
|
-
Solr::Connection.stub!(:new).with('http://localhost:8983/solr'
|
13
|
+
Solr::Connection.stub!(:new).with('http://localhost:8983/solr').and_return(connection)
|
13
14
|
Sunspot.index(Post.new)
|
15
|
+
Sunspot.index!(Post.new)
|
16
|
+
Sunspot.commit
|
14
17
|
Sunspot.search(Post)
|
15
18
|
end
|
16
19
|
|
17
20
|
it 'should open a connection with custom host' do
|
18
|
-
Solr::Connection.stub!(:new).with('http://127.0.0.1:8981/solr'
|
21
|
+
Solr::Connection.stub!(:new).with('http://127.0.0.1:8981/solr').and_return(connection)
|
19
22
|
Sunspot.config.solr.url = 'http://127.0.0.1:8981/solr'
|
20
23
|
Sunspot.index(Post.new)
|
24
|
+
Sunspot.index!(Post.new)
|
25
|
+
Sunspot.commit
|
21
26
|
Sunspot.search(Post)
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
30
|
context 'using custom session' do
|
26
31
|
before :each do
|
27
|
-
connection.should_receive(:add)
|
32
|
+
connection.should_receive(:add).twice
|
33
|
+
connection.should_receive(:commit).twice
|
28
34
|
connection.should_receive(:query)
|
29
35
|
end
|
30
36
|
|
31
37
|
it 'should open a connection with custom host' do
|
32
|
-
Solr::Connection.stub!(:new).with('http://127.0.0.1:8982/solr'
|
38
|
+
Solr::Connection.stub!(:new).with('http://127.0.0.1:8982/solr').and_return(connection)
|
33
39
|
session = Sunspot::Session.new do |config|
|
34
40
|
config.solr.url = 'http://127.0.0.1:8982/solr'
|
35
41
|
end
|
36
42
|
session.index(Post.new)
|
43
|
+
session.index!(Post.new)
|
44
|
+
session.commit
|
37
45
|
session.search(Post)
|
38
46
|
end
|
39
47
|
end
|
40
48
|
|
41
49
|
def connection
|
42
|
-
@connection ||=
|
50
|
+
@connection ||= mock('Connection').as_null_object
|
43
51
|
end
|
44
52
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe 'search faceting' do
|
2
|
+
def self.test_field_type(name, attribute, field, value1, value2)
|
3
|
+
context "with field of type #{name}" do
|
4
|
+
before :all do
|
5
|
+
Sunspot.remove_all
|
6
|
+
2.times do
|
7
|
+
Sunspot.index(Post.new(attribute => value1))
|
8
|
+
end
|
9
|
+
Sunspot.index(Post.new(attribute => value2))
|
10
|
+
Sunspot.commit
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@search = Sunspot.search(Post) do
|
15
|
+
facet(field)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return value #{value1.inspect} with count 2" do
|
20
|
+
row = @search.facet(field).rows[0]
|
21
|
+
row.value.should == value1
|
22
|
+
row.count.should == 2
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return value #{value2.inspect} with count 1" do
|
26
|
+
row = @search.facet(field).rows[1]
|
27
|
+
row.value.should == value2
|
28
|
+
row.count.should == 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
test_field_type('String', :title, :title, 'Title 1', 'Title 2')
|
34
|
+
test_field_type('Integer', :blog_id, :blog_id, 3, 4)
|
35
|
+
test_field_type('Float', :ratings_average, :average_rating, 2.2, 1.1)
|
36
|
+
test_field_type('Time', :published_at, :published_at, Time.mktime(2008, 02, 17, 17, 45, 04),
|
37
|
+
Time.mktime(2008, 07, 02, 03, 56, 22))
|
38
|
+
test_field_type('Boolean', :featured, :featured, true, false)
|
39
|
+
end
|
@@ -10,7 +10,7 @@ describe 'keyword search' do
|
|
10
10
|
:body => 'The interpreted strain scans the buffer around the upper temper')
|
11
11
|
@posts << Post.new(:title => 'The toast abbreviates the recovering spirit',
|
12
12
|
:body => 'Does the wind interpret the buffer?')
|
13
|
-
Sunspot.index(*@posts)
|
13
|
+
Sunspot.index!(*@posts)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'matches a single keyword out of a single field' do
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'scoped_search' do
|
4
|
+
def self.test_field_type(name, attribute, field, *values)
|
5
|
+
raise(ArgumentError, 'Please supply five values') unless values.length == 5
|
6
|
+
|
7
|
+
context "with field of type #{name}" do
|
8
|
+
before :all do
|
9
|
+
Sunspot.remove_all
|
10
|
+
@posts = values.map do |value|
|
11
|
+
post = Post.new(attribute => value)
|
12
|
+
Sunspot.index(post)
|
13
|
+
post
|
14
|
+
end
|
15
|
+
Sunspot.commit
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should filter by exact match' do
|
19
|
+
Sunspot.search(Post) { with(field, values[2]) }.results.should == [@posts[2]]
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should reject by inexact match' do
|
23
|
+
results = Sunspot.search(Post) { without(field, values[2]) }.results
|
24
|
+
[0, 1, 3, 4].each { |i| results.should include(@posts[i]) }
|
25
|
+
results.should_not include(@posts[2])
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should filter by less than' do
|
29
|
+
results = Sunspot.search(Post) { with(field).less_than values[2] }.results
|
30
|
+
(0..2).each { |i| results.should include(@posts[i]) }
|
31
|
+
(3..4).each { |i| results.should_not include(@posts[i]) }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should reject by less than' do
|
35
|
+
results = Sunspot.search(Post) { without(field).less_than values[2] }.results
|
36
|
+
(0..2).each { |i| results.should_not include(@posts[i]) }
|
37
|
+
(3..4).each { |i| results.should include(@posts[i]) }
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should filter by greater than' do
|
41
|
+
results = Sunspot.search(Post) { with(field).greater_than values[2] }.results
|
42
|
+
(2..4).each { |i| results.should include(@posts[i]) }
|
43
|
+
(0..1).each { |i| results.should_not include(@posts[i]) }
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should reject by greater than' do
|
47
|
+
results = Sunspot.search(Post) { without(field).greater_than values[2] }.results
|
48
|
+
(2..4).each { |i| results.should_not include(@posts[i]) }
|
49
|
+
(0..1).each { |i| results.should include(@posts[i]) }
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should filter by between' do
|
53
|
+
results = Sunspot.search(Post) { with(field).between(values[1]..values[3]) }.results
|
54
|
+
(1..3).each { |i| results.should include(@posts[i]) }
|
55
|
+
[0, 4].each { |i| results.should_not include(@posts[i]) }
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should reject by between' do
|
59
|
+
results = Sunspot.search(Post) { without(field).between(values[1]..values[3]) }.results
|
60
|
+
(1..3).each { |i| results.should_not include(@posts[i]) }
|
61
|
+
[0, 4].each { |i| results.should include(@posts[i]) }
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should filter by any of' do
|
65
|
+
results = Sunspot.search(Post) { with(field).any_of(values.values_at(1, 3)) }.results
|
66
|
+
[1, 3].each { |i| results.should include(@posts[i]) }
|
67
|
+
[0, 2, 4].each { |i| results.should_not include(@posts[i]) }
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should reject by any of' do
|
71
|
+
results = Sunspot.search(Post) { without(field).any_of(values.values_at(1, 3)) }.results
|
72
|
+
[1, 3].each { |i| results.should_not include(@posts[i]) }
|
73
|
+
[0, 2, 4].each { |i| results.should include(@posts[i]) }
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should order by field ascending' do
|
77
|
+
results = Sunspot.search(Post) { order_by field, :asc }.results
|
78
|
+
results.should == @posts
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should order by field descending' do
|
82
|
+
results = Sunspot.search(Post) { order_by field, :desc }.results
|
83
|
+
results.should == @posts.reverse
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
test_field_type 'String', :title, :title, 'apple', 'banana', 'cherry', 'date', 'eggplant'
|
89
|
+
test_field_type 'Integer', :blog_id, :blog_id, -2, 0, 3, 12, 20
|
90
|
+
test_field_type 'Float', :ratings_average, :average_rating, -2.5, 0.0, 3.2, 3.5, 16.0
|
91
|
+
test_field_type 'Time', :published_at, :published_at, *(['1970-01-01 00:00:00 UTC', '1983-07-08 04:00:00 UTC', '1983-07-08 02:00:00 -0500',
|
92
|
+
'2005-11-05 10:00:00 UTC', Time.now.to_s].map { |t| Time.parse(t) })
|
93
|
+
|
94
|
+
describe 'Boolean field type' do
|
95
|
+
before :all do
|
96
|
+
Sunspot.remove_all
|
97
|
+
@posts = [Post.new(:featured => true), Post.new(:featured => false), Post.new]
|
98
|
+
Sunspot.index!(@posts)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should filter by exact match for true' do
|
102
|
+
Sunspot.search(Post) { with(:featured, true) }.results.should == [@posts[0]]
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should filter for exact match for false' do
|
106
|
+
Sunspot.search(Post) { with(:featured, false) }.results.should == [@posts[1]]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'passing nil value to equal' do
|
111
|
+
before :all do
|
112
|
+
Sunspot.remove_all
|
113
|
+
@posts = [Post.new(:title => 'apple'), Post.new]
|
114
|
+
Sunspot.index!(@posts)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should filter results without value for field' do
|
118
|
+
Sunspot.search(Post) { with(:title, nil) }.results.should == [@posts[1]]
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should exclude results without value for field' do
|
122
|
+
Sunspot.search(Post) { without(:title, nil) }.results.should == [@posts[0]]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'exclusion by identity' do
|
127
|
+
before do
|
128
|
+
@posts = (1..5).map do |i|
|
129
|
+
post = Post.new
|
130
|
+
Sunspot.index(post)
|
131
|
+
post
|
132
|
+
end
|
133
|
+
Sunspot.commit
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should not return excluded object' do
|
137
|
+
excluded_post = @posts.shift
|
138
|
+
Sunspot.search(Post) { without(excluded_post) }.results.should_not include(excluded_post)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should return objects not excluded' do
|
142
|
+
excluded_post = @posts.shift
|
143
|
+
for included_post in @posts
|
144
|
+
Sunspot.search(Post) { without(excluded_post) }.results.should include(included_post)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should not return excluded objects' do
|
149
|
+
excluded_posts = [@posts.shift, @posts.shift]
|
150
|
+
for excluded_post in excluded_posts
|
151
|
+
Sunspot.search(Post) { without(excluded_posts) }.results.should_not include(excluded_post)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe 'multiple column ordering' do
|
157
|
+
before do
|
158
|
+
Sunspot.remove_all
|
159
|
+
@posts = [
|
160
|
+
Post.new(:ratings_average => 2, :title => 'banana'),
|
161
|
+
Post.new(:ratings_average => 2, :title => 'eggplant'),
|
162
|
+
Post.new(:ratings_average => 1, :title => 'apple')
|
163
|
+
].each { |post| Sunspot.index(post) }
|
164
|
+
Sunspot.commit
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should order with precedence given' do
|
168
|
+
search = Sunspot.search(Post) do
|
169
|
+
order_by :average_rating, :desc
|
170
|
+
order_by :sort_title, :asc
|
171
|
+
end
|
172
|
+
search.results.should == @posts
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/spec/mocks/mock_adapter.rb
CHANGED
@@ -1,25 +1,22 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'post')
|
2
2
|
|
3
3
|
module MockAdapter
|
4
|
-
class InstanceAdapter
|
5
|
-
include Sunspot::Adapters::InstanceAdapter
|
6
|
-
|
4
|
+
class InstanceAdapter < Sunspot::Adapters::InstanceAdapter
|
7
5
|
def id
|
8
|
-
instance.id
|
6
|
+
@instance.id
|
9
7
|
end
|
10
8
|
end
|
11
9
|
|
12
|
-
class
|
13
|
-
include Sunspot::Adapters::ClassAdapter
|
14
|
-
|
10
|
+
class DataAccessor < Sunspot::Adapters::DataAccessor
|
15
11
|
def load(id)
|
16
|
-
clazz.get(id.to_i)
|
12
|
+
@clazz.get(id.to_i)
|
17
13
|
end
|
18
14
|
|
19
15
|
def load_all(ids)
|
20
|
-
clazz.get_all(ids.map { |id| id.to_i })
|
16
|
+
@clazz.get_all(ids.map { |id| id.to_i })
|
21
17
|
end
|
22
18
|
end
|
23
19
|
end
|
24
20
|
|
25
|
-
Sunspot::Adapters.register(MockAdapter, BaseClass)
|
21
|
+
Sunspot::Adapters::DataAccessor.register(MockAdapter::DataAccessor, BaseClass)
|
22
|
+
Sunspot::Adapters::InstanceAdapter.register(MockAdapter::InstanceAdapter, BaseClass)
|
data/spec/mocks/post.rb
CHANGED
@@ -3,7 +3,8 @@ class Post < BaseClass
|
|
3
3
|
@@posts = [nil]
|
4
4
|
|
5
5
|
attr_reader :id
|
6
|
-
attr_accessor :title, :body, :blog_id, :published_at, :
|
6
|
+
attr_accessor :title, :body, :blog_id, :published_at, :ratings_average, :author_name, :featured
|
7
|
+
alias_method :featured?, :featured
|
7
8
|
|
8
9
|
|
9
10
|
def initialize(attrs = {})
|
@@ -33,9 +34,13 @@ Sunspot.setup(Post) do
|
|
33
34
|
string :title
|
34
35
|
integer :blog_id
|
35
36
|
integer :category_ids, :multiple => true
|
36
|
-
float :average_rating
|
37
|
+
float :average_rating, :using => :ratings_average
|
37
38
|
time :published_at
|
39
|
+
boolean :featured, :using => :featured?
|
38
40
|
string :sort_title do
|
39
41
|
title.downcase.sub(/^(a|an|the)\W+/, '') if title
|
40
42
|
end
|
43
|
+
integer :primary_category_id do |post|
|
44
|
+
post.category_ids.first
|
45
|
+
end
|
41
46
|
end
|
data/tasks/rdoc.rake
ADDED
data/tasks/spec.rake
CHANGED
@@ -6,16 +6,19 @@ require 'spec/rake/spectask'
|
|
6
6
|
desc 'run specs'
|
7
7
|
Spec::Rake::SpecTask.new('spec') do |t|
|
8
8
|
t.spec_files = FileList[File.join(File.dirname(__FILE__), '..', 'spec', '**', '*_spec.rb')]
|
9
|
+
t.spec_opts = ['--color']
|
9
10
|
end
|
10
11
|
|
11
12
|
namespace :spec do
|
12
13
|
desc 'run api specs (mock out Solr dependency)'
|
13
14
|
Spec::Rake::SpecTask.new('api') do |t|
|
14
15
|
t.spec_files = FileList[File.join(File.dirname(__FILE__), '..', 'spec', 'api', '*_spec.rb')]
|
16
|
+
t.spec_opts = ['--color']
|
15
17
|
end
|
16
18
|
|
17
19
|
desc 'run integration specs (be sure to run `bin/sunspot-solr start`)'
|
18
20
|
Spec::Rake::SpecTask.new('integration') do |t|
|
19
21
|
t.spec_files = FileList[File.join(File.dirname(__FILE__), '..', 'spec', 'integration', '*_spec.rb')]
|
22
|
+
t.spec_opts = ['--color']
|
20
23
|
end
|
21
24
|
end
|
data/tasks/todo.rake
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: outoftime-sunspot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mat Brown
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-04-28 00:00:00 -07:00
|
13
13
|
default_executable: sunspot-solr
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -63,18 +63,22 @@ extra_rdoc_files: []
|
|
63
63
|
files:
|
64
64
|
- Rakefile
|
65
65
|
- README.rdoc
|
66
|
+
- TODO
|
66
67
|
- History.txt
|
67
68
|
- VERSION.yml
|
68
69
|
- bin/sunspot-solr
|
69
70
|
- lib/sunspot
|
70
71
|
- lib/sunspot/session.rb
|
71
72
|
- lib/sunspot/type.rb
|
73
|
+
- lib/sunspot/facets.rb
|
74
|
+
- lib/sunspot/facet.rb
|
72
75
|
- lib/sunspot/adapters.rb
|
73
76
|
- lib/sunspot/restriction.rb
|
77
|
+
- lib/sunspot/facet_row.rb
|
74
78
|
- lib/sunspot/configuration.rb
|
75
79
|
- lib/sunspot/dsl.rb
|
76
80
|
- lib/sunspot/search.rb
|
77
|
-
- lib/sunspot/
|
81
|
+
- lib/sunspot/setup.rb
|
78
82
|
- lib/sunspot/field.rb
|
79
83
|
- lib/sunspot/indexer.rb
|
80
84
|
- lib/sunspot/query.rb
|
@@ -86,11 +90,11 @@ files:
|
|
86
90
|
- lib/sunspot.rb
|
87
91
|
- lib/light_config.rb
|
88
92
|
- spec/spec_helper.rb
|
89
|
-
- spec/custom_expectation.rb
|
90
93
|
- spec/integration
|
91
94
|
- spec/integration/spec_helper.rb
|
95
|
+
- spec/integration/faceting_spec.rb
|
96
|
+
- spec/integration/scoped_search_spec.rb
|
92
97
|
- spec/integration/keyword_search_spec.rb
|
93
|
-
- spec/integration/field_types_spec.rb
|
94
98
|
- spec/integration/test_pagination.rb
|
95
99
|
- spec/mocks
|
96
100
|
- spec/mocks/base_class.rb
|
@@ -102,10 +106,11 @@ files:
|
|
102
106
|
- spec/api/spec_helper.rb
|
103
107
|
- spec/api/session_spec.rb
|
104
108
|
- spec/api/build_search_spec.rb
|
105
|
-
- spec/api/standard_search_builder_spec.rb
|
106
109
|
- spec/api/indexer_spec.rb
|
107
110
|
- tasks/gemspec.rake
|
108
111
|
- tasks/rcov.rake
|
112
|
+
- tasks/todo.rake
|
113
|
+
- tasks/rdoc.rake
|
109
114
|
- tasks/spec.rake
|
110
115
|
- solr/etc/webdefault.xml
|
111
116
|
- solr/etc/jetty.xml
|
@@ -150,7 +155,7 @@ requirements: []
|
|
150
155
|
rubyforge_project:
|
151
156
|
rubygems_version: 1.2.0
|
152
157
|
signing_key:
|
153
|
-
specification_version:
|
158
|
+
specification_version: 3
|
154
159
|
summary: Library for expressive, powerful interaction with the Solr search engine
|
155
160
|
test_files: []
|
156
161
|
|
data/lib/sunspot/builder.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
module Sunspot
|
2
|
-
module Builder
|
3
|
-
class AbstractBuilder
|
4
|
-
attr_reader :search, :types, :field_names
|
5
|
-
|
6
|
-
def initialize(query_dsl, types, field_names)
|
7
|
-
@search, @types, @field_names = query_dsl, types, field_names
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class ParamsBuilder < AbstractBuilder
|
12
|
-
attr_reader :params
|
13
|
-
|
14
|
-
def initialize(query_dsl, types, field_names, params = {})
|
15
|
-
super(query_dsl, types, field_names)
|
16
|
-
@params = params
|
17
|
-
params.each_pair do |field_name, value|
|
18
|
-
self.send("#{field_name}=", value)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class StandardBuilder < ParamsBuilder
|
24
|
-
def initialize(query_dsl, types, field_names, params = {})
|
25
|
-
params = { :keywords => nil, :conditions => {}, :order => nil, :page => nil, :per_page => nil }.merge(params)
|
26
|
-
field_names.each { |field_name| params[:conditions][field_name.to_sym] = nil unless params[:conditions].has_key?(field_name.to_sym) }
|
27
|
-
super(query_dsl, types, field_names, params)
|
28
|
-
end
|
29
|
-
|
30
|
-
def keywords=(keywords)
|
31
|
-
search.keywords(keywords) if keywords
|
32
|
-
end
|
33
|
-
|
34
|
-
def conditions=(conditions)
|
35
|
-
conditions.each_pair do |field_name, value|
|
36
|
-
unless value.nil?
|
37
|
-
unless value.is_a?(Array)
|
38
|
-
search.with.send(field_name, value) if field_names.include?(field_name.to_s)
|
39
|
-
else
|
40
|
-
search.with.send(field_name).any_of(value)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def order=(order_string)
|
47
|
-
search.order_by(*order_string.split(' ')) if order_string
|
48
|
-
end
|
49
|
-
|
50
|
-
def page=(page)
|
51
|
-
search.paginate(:page => page, :per_page => params[:per_page]) if page
|
52
|
-
end
|
53
|
-
|
54
|
-
def per_page=(per_page) # ugly
|
55
|
-
end
|
56
|
-
|
57
|
-
def keywords
|
58
|
-
params[:keywords]
|
59
|
-
end
|
60
|
-
|
61
|
-
def conditions
|
62
|
-
::Sunspot::Util::ClosedStruct.new(params[:conditions])
|
63
|
-
end
|
64
|
-
|
65
|
-
def order
|
66
|
-
params[:order]
|
67
|
-
end
|
68
|
-
|
69
|
-
def page
|
70
|
-
params[:page]
|
71
|
-
end
|
72
|
-
|
73
|
-
def per_page
|
74
|
-
params[:per_page]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|