pduey-sunspot 1.2.1.1
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/.gitignore +12 -0
- data/Gemfile +5 -0
- data/History.txt +225 -0
- data/LICENSE +18 -0
- data/Rakefile +15 -0
- data/TODO +13 -0
- data/VERSION.yml +4 -0
- data/bin/sunspot-installer +19 -0
- data/installer/config/schema.yml +95 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot.rb +568 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/composite_setup.rb +202 -0
- data/lib/sunspot/configuration.rb +46 -0
- data/lib/sunspot/data_extractor.rb +50 -0
- data/lib/sunspot/dsl.rb +5 -0
- data/lib/sunspot/dsl/adjustable.rb +47 -0
- data/lib/sunspot/dsl/field_query.rb +279 -0
- data/lib/sunspot/dsl/fields.rb +103 -0
- data/lib/sunspot/dsl/fulltext.rb +243 -0
- data/lib/sunspot/dsl/function.rb +14 -0
- data/lib/sunspot/dsl/functional.rb +44 -0
- data/lib/sunspot/dsl/more_like_this_query.rb +56 -0
- data/lib/sunspot/dsl/paginatable.rb +28 -0
- data/lib/sunspot/dsl/query_facet.rb +36 -0
- data/lib/sunspot/dsl/restriction.rb +25 -0
- data/lib/sunspot/dsl/restriction_with_near.rb +121 -0
- data/lib/sunspot/dsl/scope.rb +217 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/dsl/standard_query.rb +121 -0
- data/lib/sunspot/field.rb +193 -0
- data/lib/sunspot/field_factory.rb +129 -0
- data/lib/sunspot/indexer.rb +131 -0
- data/lib/sunspot/installer.rb +31 -0
- data/lib/sunspot/installer/library_installer.rb +45 -0
- data/lib/sunspot/installer/schema_builder.rb +219 -0
- data/lib/sunspot/installer/solrconfig_updater.rb +76 -0
- data/lib/sunspot/installer/task_helper.rb +18 -0
- data/lib/sunspot/java.rb +8 -0
- data/lib/sunspot/query.rb +11 -0
- data/lib/sunspot/query/abstract_field_facet.rb +52 -0
- data/lib/sunspot/query/boost_query.rb +24 -0
- data/lib/sunspot/query/common_query.rb +85 -0
- data/lib/sunspot/query/composite_fulltext.rb +36 -0
- data/lib/sunspot/query/connective.rb +206 -0
- data/lib/sunspot/query/date_field_facet.rb +14 -0
- data/lib/sunspot/query/dismax.rb +128 -0
- data/lib/sunspot/query/field_facet.rb +41 -0
- data/lib/sunspot/query/filter.rb +38 -0
- data/lib/sunspot/query/function_query.rb +52 -0
- data/lib/sunspot/query/geo.rb +53 -0
- data/lib/sunspot/query/highlighting.rb +55 -0
- data/lib/sunspot/query/more_like_this.rb +61 -0
- data/lib/sunspot/query/more_like_this_query.rb +12 -0
- data/lib/sunspot/query/pagination.rb +38 -0
- data/lib/sunspot/query/query_facet.rb +16 -0
- data/lib/sunspot/query/restriction.rb +262 -0
- data/lib/sunspot/query/scope.rb +9 -0
- data/lib/sunspot/query/sort.rb +95 -0
- data/lib/sunspot/query/sort_composite.rb +33 -0
- data/lib/sunspot/query/standard_query.rb +16 -0
- data/lib/sunspot/query/text_field_boost.rb +17 -0
- data/lib/sunspot/schema.rb +151 -0
- data/lib/sunspot/search.rb +9 -0
- data/lib/sunspot/search/abstract_search.rb +335 -0
- data/lib/sunspot/search/date_facet.rb +35 -0
- data/lib/sunspot/search/facet_row.rb +27 -0
- data/lib/sunspot/search/field_facet.rb +88 -0
- data/lib/sunspot/search/highlight.rb +38 -0
- data/lib/sunspot/search/hit.rb +150 -0
- data/lib/sunspot/search/more_like_this_search.rb +31 -0
- data/lib/sunspot/search/paginated_collection.rb +55 -0
- data/lib/sunspot/search/query_facet.rb +67 -0
- data/lib/sunspot/search/standard_search.rb +21 -0
- data/lib/sunspot/session.rb +260 -0
- data/lib/sunspot/session_proxy.rb +87 -0
- data/lib/sunspot/session_proxy/abstract_session_proxy.rb +29 -0
- data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +66 -0
- data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +89 -0
- data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +43 -0
- data/lib/sunspot/session_proxy/sharding_session_proxy.rb +222 -0
- data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
- data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +37 -0
- data/lib/sunspot/setup.rb +350 -0
- data/lib/sunspot/text_field_setup.rb +29 -0
- data/lib/sunspot/type.rb +372 -0
- data/lib/sunspot/util.rb +243 -0
- data/lib/sunspot/version.rb +3 -0
- data/pduey-sunspot.gemspec +38 -0
- data/script/console +10 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/binding_spec.rb +50 -0
- data/spec/api/indexer/attributes_spec.rb +149 -0
- data/spec/api/indexer/batch_spec.rb +46 -0
- data/spec/api/indexer/dynamic_fields_spec.rb +42 -0
- data/spec/api/indexer/fixed_fields_spec.rb +57 -0
- data/spec/api/indexer/fulltext_spec.rb +43 -0
- data/spec/api/indexer/removal_spec.rb +53 -0
- data/spec/api/indexer/spec_helper.rb +1 -0
- data/spec/api/indexer_spec.rb +14 -0
- data/spec/api/query/advanced_manipulation_examples.rb +35 -0
- data/spec/api/query/connectives_examples.rb +189 -0
- data/spec/api/query/dsl_spec.rb +18 -0
- data/spec/api/query/dynamic_fields_examples.rb +165 -0
- data/spec/api/query/faceting_examples.rb +397 -0
- data/spec/api/query/fulltext_examples.rb +313 -0
- data/spec/api/query/function_spec.rb +70 -0
- data/spec/api/query/geo_examples.rb +68 -0
- data/spec/api/query/highlighting_examples.rb +223 -0
- data/spec/api/query/more_like_this_spec.rb +140 -0
- data/spec/api/query/ordering_pagination_examples.rb +95 -0
- data/spec/api/query/scope_examples.rb +275 -0
- data/spec/api/query/spec_helper.rb +1 -0
- data/spec/api/query/standard_spec.rb +28 -0
- data/spec/api/query/text_field_scoping_examples.rb +30 -0
- data/spec/api/query/types_spec.rb +20 -0
- data/spec/api/search/dynamic_fields_spec.rb +33 -0
- data/spec/api/search/faceting_spec.rb +360 -0
- data/spec/api/search/highlighting_spec.rb +69 -0
- data/spec/api/search/hits_spec.rb +131 -0
- data/spec/api/search/paginated_collection_spec.rb +26 -0
- data/spec/api/search/results_spec.rb +66 -0
- data/spec/api/search/search_spec.rb +23 -0
- data/spec/api/search/spec_helper.rb +1 -0
- data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +85 -0
- data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +30 -0
- data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +41 -0
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +77 -0
- data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
- data/spec/api/session_proxy/spec_helper.rb +9 -0
- data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +39 -0
- data/spec/api/session_spec.rb +220 -0
- data/spec/api/spec_helper.rb +3 -0
- data/spec/api/sunspot_spec.rb +18 -0
- data/spec/ext.rb +11 -0
- data/spec/helpers/indexer_helper.rb +29 -0
- data/spec/helpers/query_helper.rb +38 -0
- data/spec/helpers/search_helper.rb +80 -0
- data/spec/integration/dynamic_fields_spec.rb +57 -0
- data/spec/integration/faceting_spec.rb +238 -0
- data/spec/integration/highlighting_spec.rb +24 -0
- data/spec/integration/indexing_spec.rb +33 -0
- data/spec/integration/keyword_search_spec.rb +317 -0
- data/spec/integration/local_search_spec.rb +64 -0
- data/spec/integration/more_like_this_spec.rb +43 -0
- data/spec/integration/scoped_search_spec.rb +354 -0
- data/spec/integration/spec_helper.rb +7 -0
- data/spec/integration/stored_fields_spec.rb +12 -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 +21 -0
- data/spec/mocks/connection.rb +126 -0
- data/spec/mocks/mock_adapter.rb +30 -0
- data/spec/mocks/mock_class_sharding_session_proxy.rb +24 -0
- data/spec/mocks/mock_record.rb +52 -0
- data/spec/mocks/mock_sharding_session_proxy.rb +15 -0
- data/spec/mocks/photo.rb +11 -0
- data/spec/mocks/post.rb +85 -0
- data/spec/mocks/super_class.rb +2 -0
- data/spec/mocks/user.rb +13 -0
- data/spec/spec_helper.rb +28 -0
- data/tasks/rdoc.rake +27 -0
- data/tasks/schema.rake +19 -0
- data/tasks/todo.rake +4 -0
- metadata +369 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'search with dynamic fields' do
|
|
4
|
+
it 'returns dynamic string facet' do
|
|
5
|
+
stub_facet(:"custom_string:test_ss", 'two' => 2, 'one' => 1)
|
|
6
|
+
result = session.search(Post) { dynamic(:custom_string) { facet(:test) }}
|
|
7
|
+
result.facet(:custom_string, :test).rows.map { |row| row.value }.should == ['two', 'one']
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'returns dynamic field facet with custom label' do
|
|
11
|
+
stub_facet(:"bogus", 'two' => 2, 'one' => 1)
|
|
12
|
+
result = session.search(Post) { dynamic(:custom_string) { facet(:test, :name => :bogus) }}
|
|
13
|
+
result.facet(:bogus).rows.map { |row| row.value }.should == ['two', 'one']
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns query facet specified in dynamic call' do
|
|
17
|
+
stub_query_facet(
|
|
18
|
+
'custom_string\:test_ss:(foo OR bar)' => 3
|
|
19
|
+
)
|
|
20
|
+
search = session.search(Post) do
|
|
21
|
+
dynamic :custom_string do
|
|
22
|
+
facet :test do
|
|
23
|
+
row :foo_bar do
|
|
24
|
+
with :test, %w(foo bar)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
facet = search.facet(:test)
|
|
30
|
+
facet.rows.first.value.should == :foo_bar
|
|
31
|
+
facet.rows.first.count.should == 3
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'faceting', :type => :search do
|
|
4
|
+
it 'returns field name for facet' do
|
|
5
|
+
stub_facet(:title_ss, {})
|
|
6
|
+
result = session.search Post do
|
|
7
|
+
facet :title
|
|
8
|
+
end
|
|
9
|
+
result.facet(:title).field_name.should == :title
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'returns facet specified by string' do
|
|
13
|
+
stub_facet(:title_ss, {})
|
|
14
|
+
result = session.search Post do
|
|
15
|
+
facet :title
|
|
16
|
+
end
|
|
17
|
+
result.facet('title').field_name.should == :title
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'returns all facets specified by search' do
|
|
21
|
+
stub_facet(:title_ss, { 'Author 1' => 1 })
|
|
22
|
+
stub_facet(:blog_id_i, { '1' => 3 })
|
|
23
|
+
result = session.search(Post) do
|
|
24
|
+
facet :title
|
|
25
|
+
facet :blog_id
|
|
26
|
+
end
|
|
27
|
+
result.facets.first.field_name.should == :title
|
|
28
|
+
result.facets.last.field_name.should == :blog_id
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'returns string facet' do
|
|
32
|
+
stub_facet(:title_ss, 'Author 1' => 2, 'Author 2' => 1)
|
|
33
|
+
result = session.search Post do
|
|
34
|
+
facet :title
|
|
35
|
+
end
|
|
36
|
+
facet_values(result, :title).should == ['Author 1', 'Author 2']
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'returns counts for facet' do
|
|
40
|
+
stub_facet(:title_ss, 'Author 1' => 2, 'Author 2' => 1)
|
|
41
|
+
result = session.search Post do
|
|
42
|
+
facet :title
|
|
43
|
+
end
|
|
44
|
+
facet_counts(result, :title).should == [2, 1]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'returns integer facet' do
|
|
48
|
+
stub_facet(:blog_id_i, '3' => 2, '1' => 1)
|
|
49
|
+
result = session.search Post do
|
|
50
|
+
facet :blog_id
|
|
51
|
+
end
|
|
52
|
+
facet_values(result, :blog_id).should == [3, 1]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'returns float facet' do
|
|
56
|
+
stub_facet(:average_rating_ft, '9.3' => 2, '1.1' => 1)
|
|
57
|
+
result = session.search Post do
|
|
58
|
+
facet :average_rating
|
|
59
|
+
end
|
|
60
|
+
facet_values(result, :average_rating).should == [9.3, 1.1]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'returns time facet' do
|
|
64
|
+
stub_facet(
|
|
65
|
+
:published_at_dt,
|
|
66
|
+
'2009-04-07T20:25:23Z' => 3,
|
|
67
|
+
'2009-04-07T20:26:19Z' => 2,
|
|
68
|
+
'2050-04-07T20:27:15Z' => 1
|
|
69
|
+
)
|
|
70
|
+
result = session.search Post do
|
|
71
|
+
facet :published_at
|
|
72
|
+
end
|
|
73
|
+
# In JRuby, Time doesn't have 32-bit range constraint, apparently.
|
|
74
|
+
future_time =
|
|
75
|
+
begin
|
|
76
|
+
Time.gm(2050, 4, 7, 20, 27, 15)
|
|
77
|
+
rescue ArgumentError
|
|
78
|
+
DateTime.civil(2050, 4, 7, 20, 27, 15)
|
|
79
|
+
end
|
|
80
|
+
facet_values(result, :published_at).should ==
|
|
81
|
+
[Time.gm(2009, 4, 7, 20, 25, 23),
|
|
82
|
+
Time.gm(2009, 4, 7, 20, 26, 19),
|
|
83
|
+
future_time]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'returns date facet' do
|
|
87
|
+
stub_facet(
|
|
88
|
+
:expire_date_d,
|
|
89
|
+
'2009-07-13T00:00:00Z' => 3,
|
|
90
|
+
'2009-04-01T00:00:00Z' => 1
|
|
91
|
+
)
|
|
92
|
+
result = session.search(Post) do
|
|
93
|
+
facet :expire_date
|
|
94
|
+
end
|
|
95
|
+
facet_values(result, :expire_date).should ==
|
|
96
|
+
[Date.new(2009, 07, 13),
|
|
97
|
+
Date.new(2009, 04, 01)]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'returns trie integer facet' do
|
|
101
|
+
stub_facet(:size_it, '3' => 2, '1' => 1)
|
|
102
|
+
result = session.search Photo do
|
|
103
|
+
facet :size
|
|
104
|
+
end
|
|
105
|
+
facet_values(result, :size).should == [3, 1]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'returns float facet' do
|
|
109
|
+
stub_facet(:average_rating_ft, '9.3' => 2, '1.1' => 1)
|
|
110
|
+
result = session.search Photo do
|
|
111
|
+
facet :average_rating
|
|
112
|
+
end
|
|
113
|
+
facet_values(result, :average_rating).should == [9.3, 1.1]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'returns time facet' do
|
|
117
|
+
stub_facet(
|
|
118
|
+
:created_at_dt,
|
|
119
|
+
'2009-04-07T20:25:23Z' => 3,
|
|
120
|
+
'2009-04-07T20:26:19Z' => 1
|
|
121
|
+
)
|
|
122
|
+
result = session.search Photo do
|
|
123
|
+
facet :created_at
|
|
124
|
+
end
|
|
125
|
+
facet_values(result, :created_at).should ==
|
|
126
|
+
[Time.gm(2009, 04, 07, 20, 25, 23),
|
|
127
|
+
Time.gm(2009, 04, 07, 20, 26, 19)]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'returns boolean facet' do
|
|
131
|
+
stub_facet(:featured_bs, 'true' => 3, 'false' => 1)
|
|
132
|
+
result = session.search(Post) { facet(:featured) }
|
|
133
|
+
facet_values(result, :featured).should == [true, false]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
{ 'string' => 'blog', 'symbol' => :blog }.each_pair do |type, name|
|
|
138
|
+
it "returns field facet with #{type} custom name" do
|
|
139
|
+
stub_facet(:blog, '2' => 1, '1' => 4)
|
|
140
|
+
result = session.search(Post) { facet(:blog_id, :name => name) }
|
|
141
|
+
facet_values(result, :blog).should == [1, 2]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "assigns #{type} custom name to field facet" do
|
|
145
|
+
stub_facet(:blog, '2' => 1)
|
|
146
|
+
result = session.search(Post) { facet(:blog_id, :name => name) }
|
|
147
|
+
result.facet(:blog).name.should == :blog
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "retains field name for #{type} custom-named field facet" do
|
|
151
|
+
stub_facet(:blog, '2' => 1)
|
|
152
|
+
result = session.search(Post) { facet(:blog_id, :name => name) }
|
|
153
|
+
result.facet(:blog).field_name.should == :blog_id
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'returns class facet' do
|
|
158
|
+
stub_facet(:class_name, 'Post' => 3, 'Namespaced::Comment' => 1)
|
|
159
|
+
result = session.search(Post) { facet(:class) }
|
|
160
|
+
facet_values(result, :class).should == [Post, Namespaced::Comment]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'returns special :any facet' do
|
|
164
|
+
stub_query_facet(
|
|
165
|
+
'category_ids_im:[* TO *]' => 3
|
|
166
|
+
)
|
|
167
|
+
search = session.search(Post) { facet(:category_ids, :extra => :any) }
|
|
168
|
+
row = search.facet(:category_ids).rows.first
|
|
169
|
+
row.value.should == :any
|
|
170
|
+
row.count.should == 3
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it 'returns special :none facet' do
|
|
174
|
+
stub_query_facet(
|
|
175
|
+
'-category_ids_im:[* TO *]' => 3
|
|
176
|
+
)
|
|
177
|
+
search = session.search(Post) { facet(:category_ids, :extra => :none) }
|
|
178
|
+
row = search.facet(:category_ids).rows.first
|
|
179
|
+
row.value.should == :none
|
|
180
|
+
row.count.should == 3
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'returns date range facet' do
|
|
184
|
+
stub_date_facet(:published_at_dt, 60*60*24, '2009-07-08T04:00:00Z' => 2, '2009-07-07T04:00:00Z' => 1)
|
|
185
|
+
start_time = Time.utc(2009, 7, 7, 4)
|
|
186
|
+
end_time = start_time + 2*24*60*60
|
|
187
|
+
result = session.search(Post) { facet(:published_at, :time_range => start_time..end_time) }
|
|
188
|
+
facet = result.facet(:published_at)
|
|
189
|
+
facet.rows.first.value.should == (start_time..(start_time+24*60*60))
|
|
190
|
+
facet.rows.last.value.should == ((start_time+24*60*60)..end_time)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'returns date range facet sorted by count' do
|
|
194
|
+
stub_date_facet(:published_at_dt, 60*60*24, '2009-07-08T04:00:00Z' => 2, '2009-07-07T04:00:00Z' => 1)
|
|
195
|
+
start_time = Time.utc(2009, 7, 7, 4)
|
|
196
|
+
end_time = start_time + 2*24*60*60
|
|
197
|
+
result = session.search(Post) { facet(:published_at, :time_range => start_time..end_time, :sort => :count) }
|
|
198
|
+
facet = result.facet(:published_at)
|
|
199
|
+
facet.rows.first.value.should == ((start_time+24*60*60)..end_time)
|
|
200
|
+
facet.rows.last.value.should == (start_time..(start_time+24*60*60))
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it 'returns query facet' do
|
|
204
|
+
stub_query_facet(
|
|
205
|
+
'average_rating_ft:[3\.0 TO 5\.0]' => 3,
|
|
206
|
+
'average_rating_ft:[1\.0 TO 3\.0]' => 1
|
|
207
|
+
)
|
|
208
|
+
search = session.search(Post) do
|
|
209
|
+
facet :average_rating do
|
|
210
|
+
row 3.0..5.0 do
|
|
211
|
+
with :average_rating, 3.0..5.0
|
|
212
|
+
end
|
|
213
|
+
row 1.0..3.0 do
|
|
214
|
+
with :average_rating, 1.0..3.0
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
facet = search.facet(:average_rating)
|
|
219
|
+
facet.rows.first.value.should == (3.0..5.0)
|
|
220
|
+
facet.rows.first.count.should == 3
|
|
221
|
+
facet.rows.last.value.should == (1.0..3.0)
|
|
222
|
+
facet.rows.last.count.should == 1
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
describe 'query facet option handling' do
|
|
226
|
+
def facet_values_from_options(options = {})
|
|
227
|
+
session.search(Post) do
|
|
228
|
+
facet :average_rating, options do
|
|
229
|
+
row(1) { with(:average_rating, 1.0..2.0) }
|
|
230
|
+
row(3) { with(:average_rating, 3.0..4.0) }
|
|
231
|
+
row(2) { with(:average_rating, 2.0..3.0) }
|
|
232
|
+
row(4) { with(:average_rating, 4.0..5.0) }
|
|
233
|
+
end
|
|
234
|
+
end.facet(:average_rating).rows.map { |row| row.value }
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
before :each do
|
|
238
|
+
stub_query_facet(
|
|
239
|
+
'average_rating_ft:[1\.0 TO 2\.0]' => 2,
|
|
240
|
+
'average_rating_ft:[2\.0 TO 3\.0]' => 3,
|
|
241
|
+
'average_rating_ft:[3\.0 TO 4\.0]' => 1,
|
|
242
|
+
'average_rating_ft:[4\.0 TO 5\.0]' => 0
|
|
243
|
+
)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it 'sorts in order of specification if no limit is given' do
|
|
247
|
+
facet_values_from_options.should == [1, 3, 2]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'sorts lexically if lexical option is specified' do
|
|
251
|
+
facet_values_from_options(:sort => :index).should == [1, 2, 3]
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it 'sorts by count by default if limit is given' do
|
|
255
|
+
facet_values_from_options(:limit => 2).should == [2, 1]
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'sorts by count if count option is specified' do
|
|
259
|
+
facet_values_from_options(:sort => :count).should == [2, 1, 3]
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it 'sorts lexically if lexical option is specified even if limit is given' do
|
|
263
|
+
facet_values_from_options(:sort => :index, :limit => 2).should == [1, 2]
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it 'limits facets if limit option is given' do
|
|
267
|
+
facet_values_from_options(:limit => 1).should == [2]
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it 'does not limit facets if limit option is negative' do
|
|
271
|
+
facet_values_from_options(:limit => -2).should == [1, 3, 2]
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it 'returns all facets if limit greater than number of facets' do
|
|
275
|
+
facet_values_from_options(:limit => 10).should == [2, 1, 3]
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it 'allows zero count if specified' do
|
|
279
|
+
facet_values_from_options(:zeros => true).should == [1, 3, 2, 4]
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it 'sets minimum count' do
|
|
283
|
+
facet_values_from_options(:minimum_count => 2).should == [1, 2]
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it 'returns limited field facet' do
|
|
288
|
+
stub_query_facet(
|
|
289
|
+
'category_ids_im:1' => 3,
|
|
290
|
+
'category_ids_im:3' => 1
|
|
291
|
+
)
|
|
292
|
+
search = session.search(Post) do
|
|
293
|
+
facet :category_ids, :only => [1, 3, 5]
|
|
294
|
+
end
|
|
295
|
+
facet = search.facet(:category_ids)
|
|
296
|
+
facet.rows.first.value.should == 1
|
|
297
|
+
facet.rows.first.count.should == 3
|
|
298
|
+
facet.rows.last.value.should == 3
|
|
299
|
+
facet.rows.last.count.should == 1
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it 'returns instantiated facet values' do
|
|
303
|
+
blogs = Array.new(2) { Blog.new }
|
|
304
|
+
stub_facet(:blog_id_i, blogs[0].id.to_s => 2, blogs[1].id.to_s => 1)
|
|
305
|
+
search = session.search(Post) { facet(:blog_id) }
|
|
306
|
+
search.facet(:blog_id).rows.map { |row| row.instance }.should == blogs
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it 'returns all instantiated facet rows, whether or not the instances exist' do
|
|
310
|
+
blogs = Array.new(2) { Blog.new }
|
|
311
|
+
blogs.last.destroy
|
|
312
|
+
stub_facet(:blog_id_i, blogs[0].id.to_s => 2, blogs[1].id.to_s => 1)
|
|
313
|
+
search = session.search(Post) { facet(:blog_id) }
|
|
314
|
+
search.facet(:blog_id).rows.map { |row| row.instance }.should == [blogs.first, nil]
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it 'returns only rows with available instances if specified' do
|
|
318
|
+
blogs = Array.new(2) { Blog.new }
|
|
319
|
+
blogs.last.destroy
|
|
320
|
+
stub_facet(:blog_id_i, blogs[0].id.to_s => 2, blogs[1].id.to_s => 1)
|
|
321
|
+
search = session.search(Post) { facet(:blog_id) }
|
|
322
|
+
search.facet(:blog_id).rows(:verify => true).map { |row| row.instance }.should == blogs[0..0]
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
it 'returns both verified and unverified rows from the same facet' do
|
|
326
|
+
blogs = Array.new(2) { Blog.new }
|
|
327
|
+
blogs.last.destroy
|
|
328
|
+
stub_facet(:blog_id_i, blogs[0].id.to_s => 2, blogs[1].id.to_s => 1)
|
|
329
|
+
search = session.search(Post) { facet(:blog_id) }
|
|
330
|
+
search.facet(:blog_id).rows(:verify => true).map { |row| row.instance }.should == blogs[0..0]
|
|
331
|
+
search.facet(:blog_id).rows.map { |row| row.instance }.should == [blogs.first, nil]
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it 'ignores :verify option if facet not a reference facet' do
|
|
335
|
+
stub_facet(:category_ids_im, '1' => 2, '2' => 1)
|
|
336
|
+
search = session.search(Post) { facet(:category_ids) }
|
|
337
|
+
search.facet(:category_ids).should have(2).rows(:verify => true)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
it 'returns instantiated facet values for limited field facet' do
|
|
341
|
+
blogs = Array.new(2) { Blog.new }
|
|
342
|
+
stub_query_facet(
|
|
343
|
+
"blog_id_i:#{blogs[0].id}" => 3,
|
|
344
|
+
"blog_id_i:#{blogs[1].id}" => 1
|
|
345
|
+
)
|
|
346
|
+
search = session.search(Post) do
|
|
347
|
+
facet(:blog_id, :only => blogs.map { |blog| blog.id })
|
|
348
|
+
end
|
|
349
|
+
search.facet(:blog_id).rows.map { |row| row.instance }.should == blogs
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
it 'only queries the persistent store once for an instantiated facet' do
|
|
353
|
+
query_count = Blog.query_count
|
|
354
|
+
blogs = Array.new(2) { Blog.new }
|
|
355
|
+
stub_facet(:blog_id_i, blogs[0].id.to_s => 2, blogs[1].id.to_s => 1)
|
|
356
|
+
result = session.search(Post) { facet(:blog_id) }
|
|
357
|
+
result.facet(:blog_id).rows.each { |row| row.instance }
|
|
358
|
+
(Blog.query_count - query_count).should == 1
|
|
359
|
+
end
|
|
360
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'search with highlighting results', :type => :search do
|
|
4
|
+
before :each do
|
|
5
|
+
@posts = Array.new(2) { Post.new }
|
|
6
|
+
stub_results_with_highlighting(
|
|
7
|
+
@posts[0],
|
|
8
|
+
{ 'title_text' => ['one @@@hl@@@two@@@endhl@@@ three'] },
|
|
9
|
+
@posts[1],
|
|
10
|
+
{ 'title_text' => ['three four @@@hl@@@five@@@endhl@@@'],
|
|
11
|
+
'body_text' => ['@@@hl@@@five@@@ six seven', '@@@hl@@@eight@@@endhl@@@ nine @@@hl@@@ten@@@endhl@@@'] }
|
|
12
|
+
)
|
|
13
|
+
@search = session.search(Post)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns all highlights' do
|
|
17
|
+
@search.hits.last.should have(3).highlights
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'returns all highlights for a specified field' do
|
|
21
|
+
@search.hits.last.should have(2).highlights(:body)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'returns first highlight for a specified field' do
|
|
25
|
+
@search.hits.first.highlight(:title).format.should == 'one <em>two</em> three'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'returns an empty array if a given field does not have a highlight' do
|
|
29
|
+
@search.hits.first.highlights(:body).should == []
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'formats hits with <em> by default' do
|
|
33
|
+
highlight = @search.hits.first.highlights(:title).first.formatted
|
|
34
|
+
highlight.should == 'one <em>two</em> three'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'formats hits with provided block' do
|
|
38
|
+
highlight = @search.hits.first.highlights(:title).first.format do |word|
|
|
39
|
+
"<i>#{word}</i>"
|
|
40
|
+
end
|
|
41
|
+
highlight.should == 'one <i>two</i> three'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'handles multiple highlighted words' do
|
|
45
|
+
highlight = @search.hits.last.highlights(:body).last.format do |word|
|
|
46
|
+
"<b>#{word}</b>"
|
|
47
|
+
end
|
|
48
|
+
highlight.should == '<b>eight</b> nine <b>ten</b>'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def stub_results_with_highlighting(*instances_and_highlights)
|
|
54
|
+
docs, highlights = [], []
|
|
55
|
+
instances_and_highlights.each_slice(2) do |doc, highlight|
|
|
56
|
+
docs << doc
|
|
57
|
+
highlights << highlight
|
|
58
|
+
end
|
|
59
|
+
response = stub_full_results(*docs.map { |doc| { 'instance' => doc }})
|
|
60
|
+
highlighting = response['highlighting'] = {}
|
|
61
|
+
highlights.each_with_index do |highlight, i|
|
|
62
|
+
if highlight
|
|
63
|
+
instance = docs[i]
|
|
64
|
+
highlighting["#{instance.class.name} #{instance.id}"] = highlight
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
response
|
|
68
|
+
end
|
|
69
|
+
end
|