gojee-sunspot 2.0.3 → 2.0.4
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 +252 -0
- data/LICENSE +18 -0
- data/Rakefile +13 -0
- data/TODO +13 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/batcher.rb +62 -0
- data/lib/sunspot/class_set.rb +23 -0
- data/lib/sunspot/composite_setup.rb +202 -0
- data/lib/sunspot/configuration.rb +53 -0
- data/lib/sunspot/data_extractor.rb +50 -0
- data/lib/sunspot/dsl/adjustable.rb +47 -0
- data/lib/sunspot/dsl/field_group.rb +57 -0
- data/lib/sunspot/dsl/field_query.rb +327 -0
- data/lib/sunspot/dsl/fields.rb +103 -0
- data/lib/sunspot/dsl/fulltext.rb +243 -0
- data/lib/sunspot/dsl/function.rb +27 -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 +32 -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 +160 -0
- data/lib/sunspot/dsl/scope.rb +217 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/dsl/standard_query.rb +123 -0
- data/lib/sunspot/dsl.rb +5 -0
- data/lib/sunspot/field.rb +193 -0
- data/lib/sunspot/field_factory.rb +129 -0
- data/lib/sunspot/indexer.rb +136 -0
- data/lib/sunspot/query/abstract_field_facet.rb +52 -0
- data/lib/sunspot/query/bbox.rb +15 -0
- data/lib/sunspot/query/boost_query.rb +24 -0
- data/lib/sunspot/query/common_query.rb +96 -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 +132 -0
- data/lib/sunspot/query/field_facet.rb +41 -0
- data/lib/sunspot/query/field_group.rb +36 -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/geofilt.rb +16 -0
- data/lib/sunspot/query/highlighting.rb +62 -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 +42 -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 +109 -0
- data/lib/sunspot/query/sort_composite.rb +34 -0
- data/lib/sunspot/query/standard_query.rb +16 -0
- data/lib/sunspot/query/text_field_boost.rb +17 -0
- data/lib/sunspot/query.rb +11 -0
- data/lib/sunspot/schema.rb +151 -0
- data/lib/sunspot/search/abstract_search.rb +281 -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/field_group.rb +32 -0
- data/lib/sunspot/search/group.rb +50 -0
- data/lib/sunspot/search/highlight.rb +38 -0
- data/lib/sunspot/search/hit.rb +150 -0
- data/lib/sunspot/search/hit_enumerable.rb +72 -0
- data/lib/sunspot/search/more_like_this_search.rb +31 -0
- data/lib/sunspot/search/paginated_collection.rb +57 -0
- data/lib/sunspot/search/query_facet.rb +67 -0
- data/lib/sunspot/search/standard_search.rb +21 -0
- data/lib/sunspot/search.rb +9 -0
- data/lib/sunspot/session.rb +262 -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/multicore_session_proxy.rb +67 -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/session_proxy.rb +95 -0
- data/lib/sunspot/setup.rb +350 -0
- data/lib/sunspot/text_field_setup.rb +29 -0
- data/lib/sunspot/type.rb +393 -0
- data/lib/sunspot/util.rb +252 -0
- data/lib/sunspot/version.rb +3 -0
- data/lib/sunspot.rb +579 -0
- data/log/.gitignore +1 -0
- data/pkg/.gitignore +1 -0
- data/script/console +10 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/batcher_spec.rb +112 -0
- data/spec/api/binding_spec.rb +50 -0
- data/spec/api/class_set_spec.rb +24 -0
- data/spec/api/hit_enumerable_spec.rb +47 -0
- data/spec/api/indexer/attributes_spec.rb +149 -0
- data/spec/api/indexer/batch_spec.rb +72 -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 +79 -0
- data/spec/api/query/geo_examples.rb +68 -0
- data/spec/api/query/group_spec.rb +32 -0
- data/spec/api/query/highlighting_examples.rb +245 -0
- data/spec/api/query/more_like_this_spec.rb +140 -0
- data/spec/api/query/ordering_pagination_examples.rb +116 -0
- data/spec/api/query/scope_examples.rb +275 -0
- data/spec/api/query/spatial_examples.rb +27 -0
- data/spec/api/query/spec_helper.rb +1 -0
- data/spec/api/query/standard_spec.rb +29 -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 +36 -0
- data/spec/api/search/results_spec.rb +72 -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 +232 -0
- data/spec/api/spec_helper.rb +3 -0
- data/spec/api/sunspot_spec.rb +29 -0
- data/spec/ext.rb +11 -0
- data/spec/helpers/indexer_helper.rb +17 -0
- data/spec/helpers/integration_helper.rb +8 -0
- data/spec/helpers/mock_session_helper.rb +13 -0
- data/spec/helpers/query_helper.rb +26 -0
- data/spec/helpers/search_helper.rb +68 -0
- data/spec/integration/dynamic_fields_spec.rb +57 -0
- data/spec/integration/faceting_spec.rb +251 -0
- data/spec/integration/field_grouping_spec.rb +66 -0
- data/spec/integration/geospatial_spec.rb +85 -0
- data/spec/integration/highlighting_spec.rb +44 -0
- data/spec/integration/indexing_spec.rb +55 -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/stored_fields_spec.rb +12 -0
- data/spec/integration/test_pagination.rb +43 -0
- data/spec/integration/unicode_spec.rb +15 -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 +86 -0
- data/spec/mocks/super_class.rb +2 -0
- data/spec/mocks/user.rb +13 -0
- data/spec/spec_helper.rb +40 -0
- data/sunspot.gemspec +42 -0
- data/tasks/rdoc.rake +27 -0
- data/tasks/schema.rake +19 -0
- data/tasks/todo.rake +4 -0
- metadata +261 -3
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe 'function query' do
|
4
|
+
it "should send query to solr with boost function" do
|
5
|
+
session.search Post do
|
6
|
+
keywords('pizza') do
|
7
|
+
boost(function { :average_rating })
|
8
|
+
end
|
9
|
+
end
|
10
|
+
connection.should have_last_search_including(:bf, 'average_rating_ft')
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should handle boost function with constant float" do
|
14
|
+
session.search Post do
|
15
|
+
keywords('pizza') do
|
16
|
+
boost(function { 10.5 })
|
17
|
+
end
|
18
|
+
end
|
19
|
+
connection.should have_last_search_including(:bf, '10.5')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should handle boost function with time literal" do
|
23
|
+
session.search Post do
|
24
|
+
keywords('pizza') do
|
25
|
+
boost(function { Time.parse('2010-03-25 14:13:00 EDT') })
|
26
|
+
end
|
27
|
+
end
|
28
|
+
connection.should have_last_search_including(:bf, '2010-03-25T18:13:00Z')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should handle arbitrary functions in a function query block" do
|
32
|
+
session.search Post do
|
33
|
+
keywords('pizza') do
|
34
|
+
boost(function { product(:average_rating, 10) })
|
35
|
+
end
|
36
|
+
end
|
37
|
+
connection.should have_last_search_including(:bf, 'product(average_rating_ft,10)')
|
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
|
48
|
+
|
49
|
+
it "should handle nested functions in a function query block" do
|
50
|
+
session.search Post do
|
51
|
+
keywords('pizza') do
|
52
|
+
boost(function { product(:average_rating, sum(:average_rating, 20)) })
|
53
|
+
end
|
54
|
+
end
|
55
|
+
connection.should have_last_search_including(:bf, 'product(average_rating_ft,sum(average_rating_ft,20))')
|
56
|
+
end
|
57
|
+
|
58
|
+
# TODO SOLR 1.5
|
59
|
+
it "should raise ArgumentError if string literal passed" do
|
60
|
+
lambda do
|
61
|
+
session.search Post do
|
62
|
+
keywords('pizza') do
|
63
|
+
boost(function { "hello world" })
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end.should raise_error(ArgumentError)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should raise UnrecognizedFieldError if bogus field name passed" do
|
70
|
+
lambda do
|
71
|
+
session.search Post do
|
72
|
+
keywords('pizza') do
|
73
|
+
boost(function { :bogus })
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
shared_examples_for 'geohash query' do
|
4
|
+
it 'searches for nearby points with defaults' do
|
5
|
+
search do
|
6
|
+
with(:coordinates).near(40.7, -73.5)
|
7
|
+
end
|
8
|
+
connection.should have_last_search_including(:q, build_geo_query)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'searches for nearby points with non-Float arguments' do
|
12
|
+
search do
|
13
|
+
with(:coordinates).near(BigDecimal.new('40.7'), BigDecimal.new('-73.5'))
|
14
|
+
end
|
15
|
+
connection.should have_last_search_including(:q, build_geo_query)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'searches for nearby points with given precision' do
|
19
|
+
search do
|
20
|
+
with(:coordinates).near(40.7, -73.5, :precision => 10)
|
21
|
+
end
|
22
|
+
connection.should have_last_search_including(:q, build_geo_query(:precision => 10))
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'searches for nearby points with given precision factor' do
|
26
|
+
search do
|
27
|
+
with(:coordinates).near(40.7, -73.5, :precision_factor => 1.5)
|
28
|
+
end
|
29
|
+
connection.should have_last_search_including(:q, build_geo_query(:precision_factor => 1.5))
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'searches for nearby points with given boost' do
|
33
|
+
search do
|
34
|
+
with(:coordinates).near(40.7, -73.5, :boost => 2.0)
|
35
|
+
end
|
36
|
+
connection.should have_last_search_including(:q, build_geo_query(:boost => 2.0))
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'performs both dismax search and location search' do
|
40
|
+
search do
|
41
|
+
fulltext 'pizza', :fields => :title
|
42
|
+
with(:coordinates).near(40.7, -73.5)
|
43
|
+
end
|
44
|
+
expected =
|
45
|
+
"{!dismax fl='* score' qf='title_text'}pizza (#{build_geo_query})"
|
46
|
+
connection.should have_last_search_including(
|
47
|
+
:q,
|
48
|
+
%Q(_query_:"{!dismax qf='title_text'}pizza" (#{build_geo_query}))
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def build_geo_query(options = {})
|
55
|
+
precision = options[:precision] || 7
|
56
|
+
precision_factor = options[:precision_factor] || 16.0
|
57
|
+
boost = options[:boost] || 1.0
|
58
|
+
hash = 'dr5xx3nytvgs'
|
59
|
+
(precision..12).map do |i|
|
60
|
+
phrase =
|
61
|
+
if i == 12 then hash
|
62
|
+
else "#{hash[0, i]}*"
|
63
|
+
end
|
64
|
+
precision_boost = Sunspot::Util.format_float(boost*precision_factor**(i-12.0), 3)
|
65
|
+
"coordinates_s:#{phrase}^#{precision_boost}"
|
66
|
+
end.reverse.join(' OR ')
|
67
|
+
end
|
68
|
+
end
|
@@ -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
|
@@ -0,0 +1,245 @@
|
|
1
|
+
shared_examples_for "query with highlighting support" do
|
2
|
+
it 'should not send highlight parameter when highlight not requested' do
|
3
|
+
search do
|
4
|
+
keywords 'test'
|
5
|
+
end
|
6
|
+
connection.should_not have_last_search_with(:hl)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should enable highlighting when highlighting requested as keywords argument' do
|
10
|
+
search do
|
11
|
+
keywords 'test', :highlight => true
|
12
|
+
end
|
13
|
+
connection.should have_last_search_with(:hl => 'on')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should not set highlight fields parameter if highlight fields are not passed' do
|
17
|
+
search do
|
18
|
+
keywords 'test', :highlight => true, :fields => [:title]
|
19
|
+
end
|
20
|
+
connection.should_not have_last_search_with(:'hl.fl')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should enable highlighting on multiple fields when highlighting requested as array of fields via keywords argument' do
|
24
|
+
search do
|
25
|
+
keywords 'test', :highlight => [:title, :body]
|
26
|
+
end
|
27
|
+
|
28
|
+
connection.should have_last_search_with(:hl => 'on', :'hl.fl' => %w(title_text body_textsv))
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should raise UnrecognizedFieldError if try to highlight unexisting field via keywords argument' do
|
32
|
+
lambda {
|
33
|
+
search do
|
34
|
+
keywords 'test', :highlight => [:unknown_field]
|
35
|
+
end
|
36
|
+
}.should raise_error(Sunspot::UnrecognizedFieldError)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should enable highlighting on multiple fields when highlighting requested as list of fields via block call' do
|
40
|
+
search do
|
41
|
+
keywords 'test' do
|
42
|
+
highlight :title, :body
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
connection.should have_last_search_with(:hl => 'on', :'hl.fl' => %w(title_text body_textsv))
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should enable highlighting on multiple fields for multiple search types' do
|
50
|
+
session.search(Post, Namespaced::Comment) do
|
51
|
+
keywords 'test' do
|
52
|
+
highlight :body
|
53
|
+
end
|
54
|
+
end
|
55
|
+
connection.searches.last[:'hl.fl'].to_set.should == Set['body_text', 'body_textsv']
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should raise UnrecognizedFieldError if try to highlight unexisting field via block call' do
|
59
|
+
lambda {
|
60
|
+
search do
|
61
|
+
keywords 'test' do
|
62
|
+
highlight :unknown_field
|
63
|
+
end
|
64
|
+
end
|
65
|
+
}.should raise_error(Sunspot::UnrecognizedFieldError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should set internal formatting' do
|
69
|
+
search do
|
70
|
+
keywords 'test', :highlight => true
|
71
|
+
end
|
72
|
+
connection.should have_last_search_with(
|
73
|
+
:"hl.simple.pre" => '@@@hl@@@',
|
74
|
+
:"hl.simple.post" => '@@@endhl@@@'
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should set highlight fields from DSL' do
|
79
|
+
search do
|
80
|
+
keywords 'test' do
|
81
|
+
highlight :title
|
82
|
+
end
|
83
|
+
end
|
84
|
+
connection.should have_last_search_with(
|
85
|
+
:"hl.fl" => %w(title_text)
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should not set formatting params specific to fields if fields specified' do
|
90
|
+
search do
|
91
|
+
keywords 'test', :highlight => :body
|
92
|
+
end
|
93
|
+
connection.should have_last_search_with(
|
94
|
+
:"hl.simple.pre" => '@@@hl@@@',
|
95
|
+
:"hl.simple.post" => '@@@endhl@@@'
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should set maximum highlights per field' do
|
100
|
+
search do
|
101
|
+
keywords 'test' do
|
102
|
+
highlight :max_snippets => 3
|
103
|
+
end
|
104
|
+
end
|
105
|
+
connection.should have_last_search_with(
|
106
|
+
:"hl.snippets" => 3
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should set max snippets specific to highlight fields' do
|
111
|
+
search do
|
112
|
+
keywords 'test' do
|
113
|
+
highlight :title, :max_snippets => 3
|
114
|
+
end
|
115
|
+
end
|
116
|
+
connection.should have_last_search_with(
|
117
|
+
:"hl.fl" => %w(title_text),
|
118
|
+
:"f.title_text.hl.snippets" => 3
|
119
|
+
)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should set the maximum size' do
|
123
|
+
search do
|
124
|
+
keywords 'text' do
|
125
|
+
highlight :fragment_size => 200
|
126
|
+
end
|
127
|
+
end
|
128
|
+
connection.should have_last_search_with(
|
129
|
+
:"hl.fragsize" => 200
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should set the maximum size for specific fields' do
|
134
|
+
search do
|
135
|
+
keywords 'text' do
|
136
|
+
highlight :title, :fragment_size => 200
|
137
|
+
end
|
138
|
+
end
|
139
|
+
connection.should have_last_search_with(
|
140
|
+
:"f.title_text.hl.fragsize" => 200
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'enables merging of contiguous fragments' do
|
145
|
+
search do
|
146
|
+
keywords 'test' do
|
147
|
+
highlight :merge_contiguous_fragments => true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
connection.should have_last_search_with(
|
151
|
+
:"hl.mergeContiguous" => 'true'
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'enables merging of contiguous fragments for specific fields' do
|
156
|
+
search do
|
157
|
+
keywords 'test' do
|
158
|
+
highlight :title, :merge_contiguous_fragments => true
|
159
|
+
end
|
160
|
+
end
|
161
|
+
connection.should have_last_search_with(
|
162
|
+
:"f.title_text.hl.mergeContiguous" => 'true'
|
163
|
+
)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'enables use of phrase highlighter' do
|
167
|
+
search do
|
168
|
+
keywords 'test' do
|
169
|
+
highlight :phrase_highlighter => true
|
170
|
+
end
|
171
|
+
end
|
172
|
+
connection.should have_last_search_with(
|
173
|
+
:"hl.usePhraseHighlighter" => 'true'
|
174
|
+
)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'enables use of phrase highlighter for specific fields' do
|
178
|
+
search do
|
179
|
+
keywords 'test' do
|
180
|
+
highlight :title, :phrase_highlighter => true
|
181
|
+
end
|
182
|
+
end
|
183
|
+
connection.should have_last_search_with(
|
184
|
+
:"f.title_text.hl.usePhraseHighlighter" => 'true'
|
185
|
+
)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'requires field match if requested' do
|
189
|
+
search do
|
190
|
+
keywords 'test' do
|
191
|
+
highlight :phrase_highlighter => true, :require_field_match => true
|
192
|
+
end
|
193
|
+
end
|
194
|
+
connection.should have_last_search_with(
|
195
|
+
:"hl.requireFieldMatch" => 'true'
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'requires field match for specified field if requested' do
|
200
|
+
search do
|
201
|
+
keywords 'test' do
|
202
|
+
highlight :title, :phrase_highlighter => true, :require_field_match => true
|
203
|
+
end
|
204
|
+
end
|
205
|
+
connection.should have_last_search_with(
|
206
|
+
:"f.title_text.hl.requireFieldMatch" => 'true'
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'sets field specific params for different fields if different params given' do
|
211
|
+
search do
|
212
|
+
keywords 'test' do
|
213
|
+
highlight :title, :max_snippets => 2
|
214
|
+
highlight :body, :max_snippets => 1
|
215
|
+
end
|
216
|
+
end
|
217
|
+
connection.should have_last_search_with(
|
218
|
+
:"hl.fl" => %w(title_text body_textsv),
|
219
|
+
:"f.title_text.hl.snippets" => 2,
|
220
|
+
:"f.body_textsv.hl.snippets" => 1
|
221
|
+
)
|
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
|
245
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe 'more_like_this' do
|
4
|
+
before :each do
|
5
|
+
connection.expected_handler = :mlt
|
6
|
+
end
|
7
|
+
|
8
|
+
it_should_behave_like "scoped query"
|
9
|
+
it_should_behave_like "facetable query"
|
10
|
+
it_should_behave_like "query with advanced manipulation"
|
11
|
+
it_should_behave_like "query with connective scope"
|
12
|
+
it_should_behave_like "query with dynamic field support"
|
13
|
+
it_should_behave_like "sortable query"
|
14
|
+
it_should_behave_like "query with text field scoping"
|
15
|
+
|
16
|
+
it 'should query passed in object' do
|
17
|
+
p = Post.new
|
18
|
+
session.more_like_this(p)
|
19
|
+
connection.should have_last_search_with(:q => "id:Post\\ #{p.id}")
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should use more_like_this fields if no fields specified' do
|
23
|
+
session.more_like_this(Post.new)
|
24
|
+
connection.searches.last[:"mlt.fl"].split(',').sort.should == %w(body_textsv tags_textv)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should use more_like_this fields if specified' do
|
28
|
+
session.more_like_this(Post.new) do
|
29
|
+
fields :body
|
30
|
+
end
|
31
|
+
connection.should have_last_search_with(:"mlt.fl" => "body_textsv")
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'assigns boosts to fields when specified' do
|
35
|
+
session.more_like_this(Post.new) do
|
36
|
+
fields :body, :tags => 8
|
37
|
+
end
|
38
|
+
connection.searches.last[:"mlt.fl"].split(',').sort.should == %w(body_textsv tags_textv)
|
39
|
+
connection.should have_last_search_with(:qf => "tags_textv^8")
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'doesn\'t assign boosts to fields when not specified' do
|
43
|
+
session.more_like_this(Post.new) do
|
44
|
+
fields :body
|
45
|
+
end
|
46
|
+
connection.should_not have_last_search_with(:qf)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should raise ArgumentError if a field is not setup for more_like_this' do
|
50
|
+
lambda do
|
51
|
+
session.more_like_this(Post.new) do
|
52
|
+
fields :title
|
53
|
+
end
|
54
|
+
end.should raise_error(ArgumentError)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should accept options' do
|
58
|
+
session.more_like_this(Post.new) do
|
59
|
+
minimum_term_frequency 1
|
60
|
+
minimum_document_frequency 2
|
61
|
+
minimum_word_length 3
|
62
|
+
maximum_word_length 4
|
63
|
+
maximum_query_terms 5
|
64
|
+
boost_by_relevance false
|
65
|
+
end
|
66
|
+
connection.should have_last_search_with(:"mlt.mintf" => 1)
|
67
|
+
connection.should have_last_search_with(:"mlt.mindf" => 2)
|
68
|
+
connection.should have_last_search_with(:"mlt.minwl" => 3)
|
69
|
+
connection.should have_last_search_with(:"mlt.maxwl" => 4)
|
70
|
+
connection.should have_last_search_with(:"mlt.maxqt" => 5)
|
71
|
+
connection.should have_last_search_with(:"mlt.boost" => false)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should accept short options' do
|
75
|
+
session.more_like_this(Post.new) do
|
76
|
+
mintf 1
|
77
|
+
mindf 2
|
78
|
+
minwl 3
|
79
|
+
maxwl 4
|
80
|
+
maxqt 5
|
81
|
+
boost true
|
82
|
+
end
|
83
|
+
connection.should have_last_search_with(:"mlt.mintf" => 1)
|
84
|
+
connection.should have_last_search_with(:"mlt.mindf" => 2)
|
85
|
+
connection.should have_last_search_with(:"mlt.minwl" => 3)
|
86
|
+
connection.should have_last_search_with(:"mlt.maxwl" => 4)
|
87
|
+
connection.should have_last_search_with(:"mlt.maxqt" => 5)
|
88
|
+
connection.should have_last_search_with(:"mlt.boost" => true)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'paginates using default per_page when page not provided' do
|
92
|
+
session.more_like_this(Post.new)
|
93
|
+
connection.should have_last_search_with(:rows => 30)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'paginates using default per_page when page provided' do
|
97
|
+
session.more_like_this(Post.new) do
|
98
|
+
paginate :page => 2
|
99
|
+
end
|
100
|
+
connection.should have_last_search_with(:rows => 30, :start => 30)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'paginates using provided per_page' do
|
104
|
+
session.more_like_this(Post.new) do
|
105
|
+
paginate :page => 4, :per_page => 15
|
106
|
+
end
|
107
|
+
connection.should have_last_search_with(:rows => 15, :start => 45)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'defaults to page 1 if no :page argument given' do
|
111
|
+
session.more_like_this(Post.new) do
|
112
|
+
paginate :per_page => 15
|
113
|
+
end
|
114
|
+
connection.should have_last_search_with(:rows => 15, :start => 0)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'paginates from string argument' do
|
118
|
+
session.more_like_this(Post.new) do
|
119
|
+
paginate :page => '3', :per_page => '15'
|
120
|
+
end
|
121
|
+
connection.should have_last_search_with(:rows => 15, :start => 30)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should send query to solr with adjusted parameters (keyword example)" do
|
125
|
+
session.more_like_this(Post.new) do
|
126
|
+
adjust_solr_params do |params|
|
127
|
+
params[:q] = 'new search'
|
128
|
+
params[:some] = 'param'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
connection.should have_last_search_with(:q => 'new search')
|
132
|
+
connection.should have_last_search_with(:some => 'param')
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def search(*args, &block)
|
138
|
+
session.more_like_this(Post.new, *args, &block)
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
shared_examples_for 'sortable query' do
|
2
|
+
it 'paginates using default per_page when page not provided' do
|
3
|
+
search
|
4
|
+
connection.should have_last_search_with(:rows => 30)
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'paginates using default per_page when page provided' do
|
8
|
+
search do
|
9
|
+
paginate :page => 2
|
10
|
+
end
|
11
|
+
connection.should have_last_search_with(:rows => 30, :start => 30)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'paginates using provided per_page' do
|
15
|
+
search do
|
16
|
+
paginate :page => 4, :per_page => 15
|
17
|
+
end
|
18
|
+
connection.should have_last_search_with(:rows => 15, :start => 45)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'defaults to page 1 if no :page argument given' do
|
22
|
+
search do
|
23
|
+
paginate :per_page => 15
|
24
|
+
end
|
25
|
+
connection.should have_last_search_with(:rows => 15, :start => 0)
|
26
|
+
end
|
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
|
+
|
42
|
+
it 'paginates from string argument' do
|
43
|
+
search do
|
44
|
+
paginate :page => '3', :per_page => '15'
|
45
|
+
end
|
46
|
+
connection.should have_last_search_with(:rows => 15, :start => 30)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'orders by a single field' do
|
50
|
+
search do
|
51
|
+
order_by :average_rating, :desc
|
52
|
+
end
|
53
|
+
connection.should have_last_search_with(:sort => 'average_rating_ft desc')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'orders by multiple fields' do
|
57
|
+
search do
|
58
|
+
order_by :average_rating, :desc
|
59
|
+
order_by :sort_title, :asc
|
60
|
+
end
|
61
|
+
connection.should have_last_search_with(:sort => 'average_rating_ft desc, sort_title_s asc')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'orders by random' do
|
65
|
+
search do
|
66
|
+
order_by :random
|
67
|
+
end
|
68
|
+
connection.searches.last[:sort].should =~ /^random_\d+ asc$/
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'orders by score' do
|
72
|
+
search do
|
73
|
+
order_by :score, :desc
|
74
|
+
end
|
75
|
+
connection.should have_last_search_with(:sort => 'score desc')
|
76
|
+
end
|
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
|
+
|
85
|
+
it 'throws an ArgumentError if a bogus order direction is given' do
|
86
|
+
lambda do
|
87
|
+
search do
|
88
|
+
order_by :sort_title, :sideways
|
89
|
+
end
|
90
|
+
end.should raise_error(ArgumentError)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'throws an UnrecognizedFieldError if :distance is given for sort' do
|
94
|
+
lambda do
|
95
|
+
search do
|
96
|
+
order_by :distance, :asc
|
97
|
+
end
|
98
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'does not allow ordering by multiple-value fields' do
|
102
|
+
lambda do
|
103
|
+
search do
|
104
|
+
order_by :category_ids
|
105
|
+
end
|
106
|
+
end.should raise_error(ArgumentError)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'raises ArgumentError if bogus argument given to paginate' do
|
110
|
+
lambda do
|
111
|
+
search do
|
112
|
+
paginate :page => 4, :ugly => :puppy
|
113
|
+
end
|
114
|
+
end.should raise_error(ArgumentError)
|
115
|
+
end
|
116
|
+
end
|