sunspot 2.0.0 → 2.5.0
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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Appraisals +7 -0
- data/Gemfile +0 -2
- data/History.txt +10 -0
- data/lib/sunspot.rb +55 -17
- data/lib/sunspot/adapters.rb +68 -18
- data/lib/sunspot/batcher.rb +1 -1
- data/lib/sunspot/configuration.rb +4 -2
- data/lib/sunspot/data_extractor.rb +36 -6
- data/lib/sunspot/dsl.rb +4 -3
- data/lib/sunspot/dsl/adjustable.rb +2 -2
- data/lib/sunspot/dsl/field_query.rb +69 -16
- data/lib/sunspot/dsl/field_stats.rb +25 -0
- data/lib/sunspot/dsl/fields.rb +28 -8
- data/lib/sunspot/dsl/fulltext.rb +9 -1
- data/lib/sunspot/dsl/group.rb +118 -0
- data/lib/sunspot/dsl/paginatable.rb +4 -1
- data/lib/sunspot/dsl/scope.rb +19 -10
- data/lib/sunspot/dsl/search.rb +1 -1
- data/lib/sunspot/dsl/spellcheckable.rb +14 -0
- data/lib/sunspot/dsl/standard_query.rb +63 -35
- data/lib/sunspot/field.rb +76 -4
- data/lib/sunspot/field_factory.rb +60 -11
- data/lib/sunspot/indexer.rb +70 -18
- data/lib/sunspot/query.rb +5 -4
- data/lib/sunspot/query/abstract_field_facet.rb +0 -2
- data/lib/sunspot/query/abstract_fulltext.rb +76 -0
- data/lib/sunspot/query/abstract_json_field_facet.rb +70 -0
- data/lib/sunspot/query/bbox.rb +5 -1
- data/lib/sunspot/query/common_query.rb +31 -6
- data/lib/sunspot/query/composite_fulltext.rb +58 -8
- data/lib/sunspot/query/date_field_json_facet.rb +25 -0
- data/lib/sunspot/query/dismax.rb +25 -71
- data/lib/sunspot/query/field_json_facet.rb +19 -0
- data/lib/sunspot/query/field_list.rb +15 -0
- data/lib/sunspot/query/field_stats.rb +61 -0
- data/lib/sunspot/query/function_query.rb +1 -2
- data/lib/sunspot/query/geo.rb +1 -1
- data/lib/sunspot/query/geofilt.rb +8 -3
- data/lib/sunspot/query/group.rb +46 -0
- data/lib/sunspot/query/group_query.rb +17 -0
- data/lib/sunspot/query/join.rb +88 -0
- data/lib/sunspot/query/more_like_this.rb +1 -1
- data/lib/sunspot/query/pagination.rb +12 -4
- data/lib/sunspot/query/range_json_facet.rb +28 -0
- data/lib/sunspot/query/restriction.rb +99 -13
- data/lib/sunspot/query/sort.rb +41 -0
- data/lib/sunspot/query/sort_composite.rb +7 -0
- data/lib/sunspot/query/spellcheck.rb +19 -0
- data/lib/sunspot/query/standard_query.rb +24 -2
- data/lib/sunspot/query/text_field_boost.rb +1 -3
- data/lib/sunspot/schema.rb +12 -3
- data/lib/sunspot/search.rb +4 -2
- data/lib/sunspot/search/abstract_search.rb +93 -43
- data/lib/sunspot/search/cursor_paginated_collection.rb +32 -0
- data/lib/sunspot/search/field_facet.rb +4 -4
- data/lib/sunspot/search/field_json_facet.rb +33 -0
- data/lib/sunspot/search/field_stats.rb +21 -0
- data/lib/sunspot/search/hit.rb +6 -1
- data/lib/sunspot/search/hit_enumerable.rb +4 -1
- data/lib/sunspot/search/json_facet_row.rb +40 -0
- data/lib/sunspot/search/json_facet_stats.rb +23 -0
- data/lib/sunspot/search/paginated_collection.rb +1 -0
- data/lib/sunspot/search/query_group.rb +74 -0
- data/lib/sunspot/search/standard_search.rb +70 -3
- data/lib/sunspot/search/stats_facet.rb +25 -0
- data/lib/sunspot/search/stats_json_row.rb +82 -0
- data/lib/sunspot/search/stats_row.rb +68 -0
- data/lib/sunspot/session.rb +62 -37
- data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +6 -4
- data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +16 -8
- data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +2 -2
- data/lib/sunspot/session_proxy/retry_5xx_session_proxy.rb +1 -1
- data/lib/sunspot/session_proxy/sharding_session_proxy.rb +4 -2
- data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +1 -1
- data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +6 -4
- data/lib/sunspot/setup.rb +42 -0
- data/lib/sunspot/type.rb +20 -0
- data/lib/sunspot/util.rb +78 -14
- data/lib/sunspot/version.rb +1 -1
- data/spec/api/adapters_spec.rb +40 -15
- data/spec/api/batcher_spec.rb +15 -15
- data/spec/api/binding_spec.rb +3 -3
- data/spec/api/class_set_spec.rb +6 -6
- data/spec/api/data_extractor_spec.rb +39 -0
- data/spec/api/hit_enumerable_spec.rb +32 -9
- data/spec/api/indexer/attributes_spec.rb +35 -30
- data/spec/api/indexer/batch_spec.rb +8 -7
- data/spec/api/indexer/dynamic_fields_spec.rb +8 -8
- data/spec/api/indexer/fixed_fields_spec.rb +16 -11
- data/spec/api/indexer/fulltext_spec.rb +8 -8
- data/spec/api/indexer/removal_spec.rb +24 -14
- data/spec/api/indexer_spec.rb +2 -2
- data/spec/api/query/advanced_manipulation_examples.rb +3 -3
- data/spec/api/query/connectives_examples.rb +26 -14
- data/spec/api/query/dsl_spec.rb +24 -6
- data/spec/api/query/dynamic_fields_examples.rb +18 -18
- data/spec/api/query/faceting_examples.rb +80 -61
- data/spec/api/query/fulltext_examples.rb +194 -40
- data/spec/api/query/function_spec.rb +116 -13
- data/spec/api/query/geo_examples.rb +8 -12
- data/spec/api/query/group_spec.rb +27 -5
- data/spec/api/query/highlighting_examples.rb +26 -26
- data/spec/api/query/join_spec.rb +19 -0
- data/spec/api/query/more_like_this_spec.rb +40 -27
- data/spec/api/query/ordering_pagination_examples.rb +37 -23
- data/spec/api/query/scope_examples.rb +39 -39
- data/spec/api/query/spatial_examples.rb +3 -3
- data/spec/api/query/spellcheck_examples.rb +20 -0
- data/spec/api/query/standard_spec.rb +3 -1
- data/spec/api/query/stats_examples.rb +66 -0
- data/spec/api/query/text_field_scoping_examples.rb +5 -5
- data/spec/api/query/types_spec.rb +4 -4
- data/spec/api/search/cursor_paginated_collection_spec.rb +35 -0
- data/spec/api/search/dynamic_fields_spec.rb +4 -4
- data/spec/api/search/faceting_spec.rb +55 -52
- data/spec/api/search/highlighting_spec.rb +7 -7
- data/spec/api/search/hits_spec.rb +43 -29
- data/spec/api/search/paginated_collection_spec.rb +19 -18
- data/spec/api/search/results_spec.rb +13 -13
- data/spec/api/search/search_spec.rb +3 -3
- data/spec/api/search/stats_spec.rb +94 -0
- data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +23 -16
- data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +16 -4
- data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +10 -6
- data/spec/api/session_proxy/retry_5xx_session_proxy_spec.rb +11 -11
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +15 -14
- data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +3 -3
- data/spec/api/session_proxy/spec_helper.rb +1 -1
- data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +40 -26
- data/spec/api/session_spec.rb +78 -38
- data/spec/api/sunspot_spec.rb +7 -4
- data/spec/helpers/integration_helper.rb +11 -1
- data/spec/helpers/query_helper.rb +1 -1
- data/spec/helpers/search_helper.rb +30 -0
- data/spec/integration/atomic_updates_spec.rb +58 -0
- data/spec/integration/dynamic_fields_spec.rb +31 -20
- data/spec/integration/faceting_spec.rb +252 -39
- data/spec/integration/field_grouping_spec.rb +47 -15
- data/spec/integration/field_lists_spec.rb +57 -0
- data/spec/integration/geospatial_spec.rb +34 -8
- data/spec/integration/highlighting_spec.rb +8 -8
- data/spec/integration/indexing_spec.rb +7 -6
- data/spec/integration/join_spec.rb +45 -0
- data/spec/integration/keyword_search_spec.rb +68 -38
- data/spec/integration/local_search_spec.rb +4 -4
- data/spec/integration/more_like_this_spec.rb +7 -7
- data/spec/integration/scoped_search_spec.rb +193 -74
- data/spec/integration/spellcheck_spec.rb +119 -0
- data/spec/integration/stats_spec.rb +88 -0
- data/spec/integration/stored_fields_spec.rb +1 -1
- data/spec/integration/test_pagination.rb +4 -4
- data/spec/integration/unicode_spec.rb +1 -1
- data/spec/mocks/adapters.rb +36 -0
- data/spec/mocks/connection.rb +5 -3
- data/spec/mocks/photo.rb +32 -1
- data/spec/mocks/post.rb +18 -3
- data/spec/spec_helper.rb +13 -8
- data/sunspot.gemspec +6 -4
- data/tasks/rdoc.rake +22 -14
- metadata +101 -44
- data/lib/sunspot/dsl/field_group.rb +0 -57
- data/lib/sunspot/query/field_group.rb +0 -37
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'join' do
|
|
4
|
+
it 'should search by join' do
|
|
5
|
+
session.search PhotoContainer do
|
|
6
|
+
with(:caption, 'blah')
|
|
7
|
+
end
|
|
8
|
+
expect(connection).to have_last_search_including(
|
|
9
|
+
:fq, "{!join from=photo_container_id_i to=id_i}caption_s:blah")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should greater_than search by join' do
|
|
13
|
+
session.search PhotoContainer do
|
|
14
|
+
with(:photo_rating).greater_than(3)
|
|
15
|
+
end
|
|
16
|
+
expect(connection).to have_last_search_including(
|
|
17
|
+
:fq, "{!join from=photo_container_id_i to=id_i}average_rating_ft:{3\\.0 TO *}")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -16,42 +16,42 @@ describe 'more_like_this' do
|
|
|
16
16
|
it 'should query passed in object' do
|
|
17
17
|
p = Post.new
|
|
18
18
|
session.more_like_this(p)
|
|
19
|
-
connection.
|
|
19
|
+
expect(connection).to have_last_search_with(:q => "id:Post\\ #{p.id}")
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it 'should use more_like_this fields if no fields specified' do
|
|
23
23
|
session.more_like_this(Post.new)
|
|
24
|
-
connection.searches.last[:"mlt.fl"].split(',').sort.
|
|
24
|
+
expect(connection.searches.last[:"mlt.fl"].split(',').sort).to eq(%w(body_textsv tags_textv))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it 'should use more_like_this fields if specified' do
|
|
28
28
|
session.more_like_this(Post.new) do
|
|
29
29
|
fields :body
|
|
30
30
|
end
|
|
31
|
-
connection.
|
|
31
|
+
expect(connection).to have_last_search_with(:"mlt.fl" => "body_textsv")
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
it 'assigns boosts to fields when specified' do
|
|
35
35
|
session.more_like_this(Post.new) do
|
|
36
36
|
fields :body, :tags => 8
|
|
37
37
|
end
|
|
38
|
-
connection.searches.last[:"mlt.fl"].split(',').sort.
|
|
39
|
-
connection.
|
|
38
|
+
expect(connection.searches.last[:"mlt.fl"].split(',').sort).to eq(%w(body_textsv tags_textv))
|
|
39
|
+
expect(connection).to have_last_search_with(:"mlt.qf" => "tags_textv^8")
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it 'doesn\'t assign boosts to fields when not specified' do
|
|
43
43
|
session.more_like_this(Post.new) do
|
|
44
44
|
fields :body
|
|
45
45
|
end
|
|
46
|
-
connection.
|
|
46
|
+
expect(connection).not_to have_last_search_with(:qf)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it 'should raise ArgumentError if a field is not setup for more_like_this' do
|
|
50
|
-
|
|
50
|
+
expect do
|
|
51
51
|
session.more_like_this(Post.new) do
|
|
52
52
|
fields :title
|
|
53
53
|
end
|
|
54
|
-
end.
|
|
54
|
+
end.to raise_error(ArgumentError)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
it 'should accept options' do
|
|
@@ -63,12 +63,12 @@ describe 'more_like_this' do
|
|
|
63
63
|
maximum_query_terms 5
|
|
64
64
|
boost_by_relevance false
|
|
65
65
|
end
|
|
66
|
-
connection.
|
|
67
|
-
connection.
|
|
68
|
-
connection.
|
|
69
|
-
connection.
|
|
70
|
-
connection.
|
|
71
|
-
connection.
|
|
66
|
+
expect(connection).to have_last_search_with(:"mlt.mintf" => 1)
|
|
67
|
+
expect(connection).to have_last_search_with(:"mlt.mindf" => 2)
|
|
68
|
+
expect(connection).to have_last_search_with(:"mlt.minwl" => 3)
|
|
69
|
+
expect(connection).to have_last_search_with(:"mlt.maxwl" => 4)
|
|
70
|
+
expect(connection).to have_last_search_with(:"mlt.maxqt" => 5)
|
|
71
|
+
expect(connection).to have_last_search_with(:"mlt.boost" => false)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
it 'should accept short options' do
|
|
@@ -80,45 +80,45 @@ describe 'more_like_this' do
|
|
|
80
80
|
maxqt 5
|
|
81
81
|
boost true
|
|
82
82
|
end
|
|
83
|
-
connection.
|
|
84
|
-
connection.
|
|
85
|
-
connection.
|
|
86
|
-
connection.
|
|
87
|
-
connection.
|
|
88
|
-
connection.
|
|
83
|
+
expect(connection).to have_last_search_with(:"mlt.mintf" => 1)
|
|
84
|
+
expect(connection).to have_last_search_with(:"mlt.mindf" => 2)
|
|
85
|
+
expect(connection).to have_last_search_with(:"mlt.minwl" => 3)
|
|
86
|
+
expect(connection).to have_last_search_with(:"mlt.maxwl" => 4)
|
|
87
|
+
expect(connection).to have_last_search_with(:"mlt.maxqt" => 5)
|
|
88
|
+
expect(connection).to have_last_search_with(:"mlt.boost" => true)
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
it 'paginates using default per_page when page not provided' do
|
|
92
92
|
session.more_like_this(Post.new)
|
|
93
|
-
connection.
|
|
93
|
+
expect(connection).to have_last_search_with(:rows => 30)
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
it 'paginates using default per_page when page provided' do
|
|
97
97
|
session.more_like_this(Post.new) do
|
|
98
98
|
paginate :page => 2
|
|
99
99
|
end
|
|
100
|
-
connection.
|
|
100
|
+
expect(connection).to have_last_search_with(:rows => 30, :start => 30)
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
it 'paginates using provided per_page' do
|
|
104
104
|
session.more_like_this(Post.new) do
|
|
105
105
|
paginate :page => 4, :per_page => 15
|
|
106
106
|
end
|
|
107
|
-
connection.
|
|
107
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 45)
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
it 'defaults to page 1 if no :page argument given' do
|
|
111
111
|
session.more_like_this(Post.new) do
|
|
112
112
|
paginate :per_page => 15
|
|
113
113
|
end
|
|
114
|
-
connection.
|
|
114
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 0)
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
it 'paginates from string argument' do
|
|
118
118
|
session.more_like_this(Post.new) do
|
|
119
119
|
paginate :page => '3', :per_page => '15'
|
|
120
120
|
end
|
|
121
|
-
connection.
|
|
121
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 30)
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
it "should send query to solr with adjusted parameters (keyword example)" do
|
|
@@ -128,8 +128,21 @@ describe 'more_like_this' do
|
|
|
128
128
|
params[:some] = 'param'
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
|
-
connection.
|
|
132
|
-
connection.
|
|
131
|
+
expect(connection).to have_last_search_with(:q => 'new search')
|
|
132
|
+
expect(connection).to have_last_search_with(:some => 'param')
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "should send query to solr with adjusted parameters in multiple blocks" do
|
|
136
|
+
session.more_like_this(Post.new) do
|
|
137
|
+
adjust_solr_params do |params|
|
|
138
|
+
params[:q] = 'new search'
|
|
139
|
+
end
|
|
140
|
+
adjust_solr_params do |params|
|
|
141
|
+
params[:some] = 'param'
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
expect(connection).to have_last_search_with(:q => 'new search')
|
|
145
|
+
expect(connection).to have_last_search_with(:some => 'param')
|
|
133
146
|
end
|
|
134
147
|
|
|
135
148
|
private
|
|
@@ -1,56 +1,70 @@
|
|
|
1
1
|
shared_examples_for 'sortable query' do
|
|
2
2
|
it 'paginates using default per_page when page not provided' do
|
|
3
3
|
search
|
|
4
|
-
connection.
|
|
4
|
+
expect(connection).to have_last_search_with(:rows => 30)
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
it 'paginates using default per_page when page provided' do
|
|
8
8
|
search do
|
|
9
9
|
paginate :page => 2
|
|
10
10
|
end
|
|
11
|
-
connection.
|
|
11
|
+
expect(connection).to have_last_search_with(:rows => 30, :start => 30)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it 'paginates using provided per_page' do
|
|
15
15
|
search do
|
|
16
16
|
paginate :page => 4, :per_page => 15
|
|
17
17
|
end
|
|
18
|
-
connection.
|
|
18
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 45)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it 'defaults to page 1 if no :page argument given' do
|
|
22
22
|
search do
|
|
23
23
|
paginate :per_page => 15
|
|
24
24
|
end
|
|
25
|
-
connection.
|
|
25
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 0)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it 'paginates with an offset' do
|
|
29
29
|
search do
|
|
30
30
|
paginate :per_page => 15, :offset => 3
|
|
31
31
|
end
|
|
32
|
-
connection.
|
|
32
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 3)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it 'paginates with an offset as a string' do
|
|
36
36
|
search do
|
|
37
37
|
paginate :per_page => 15, :offset => '3'
|
|
38
38
|
end
|
|
39
|
-
connection.
|
|
39
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 3)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it 'paginates from string argument' do
|
|
43
43
|
search do
|
|
44
44
|
paginate :page => '3', :per_page => '15'
|
|
45
45
|
end
|
|
46
|
-
connection.
|
|
46
|
+
expect(connection).to have_last_search_with(:rows => 15, :start => 30)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'paginates with initial cursor' do
|
|
50
|
+
search do
|
|
51
|
+
paginate :cursor => '*', :per_page => 15
|
|
52
|
+
end
|
|
53
|
+
expect(connection).to have_last_search_with(:rows => 15, :cursorMark => '*')
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'paginates with given cursor' do
|
|
57
|
+
search do
|
|
58
|
+
paginate :cursor => 'AoIIP4AAACxQcm9maWxlIDEwMTk='
|
|
59
|
+
end
|
|
60
|
+
expect(connection).to have_last_search_with(:cursorMark => 'AoIIP4AAACxQcm9maWxlIDEwMTk=')
|
|
47
61
|
end
|
|
48
62
|
|
|
49
63
|
it 'orders by a single field' do
|
|
50
64
|
search do
|
|
51
65
|
order_by :average_rating, :desc
|
|
52
66
|
end
|
|
53
|
-
connection.
|
|
67
|
+
expect(connection).to have_last_search_with(:sort => 'average_rating_ft desc')
|
|
54
68
|
end
|
|
55
69
|
|
|
56
70
|
it 'orders by multiple fields' do
|
|
@@ -58,80 +72,80 @@ shared_examples_for 'sortable query' do
|
|
|
58
72
|
order_by :average_rating, :desc
|
|
59
73
|
order_by :sort_title, :asc
|
|
60
74
|
end
|
|
61
|
-
connection.
|
|
75
|
+
expect(connection).to have_last_search_with(:sort => 'average_rating_ft desc, sort_title_s asc')
|
|
62
76
|
end
|
|
63
77
|
|
|
64
78
|
it 'orders by random' do
|
|
65
79
|
search do
|
|
66
80
|
order_by :random
|
|
67
81
|
end
|
|
68
|
-
connection.searches.last[:sort].
|
|
82
|
+
expect(connection.searches.last[:sort]).to match(/^random_\d+ asc$/)
|
|
69
83
|
end
|
|
70
84
|
|
|
71
85
|
it 'orders by random with declared direction' do
|
|
72
86
|
search do
|
|
73
87
|
order_by :random, :desc
|
|
74
88
|
end
|
|
75
|
-
connection.searches.last[:sort].
|
|
89
|
+
expect(connection.searches.last[:sort]).to match(/^random_\d+ desc$/)
|
|
76
90
|
end
|
|
77
91
|
|
|
78
92
|
it 'orders by random with provided seed value' do
|
|
79
93
|
search do
|
|
80
94
|
order_by :random, :seed => 9001
|
|
81
95
|
end
|
|
82
|
-
connection.searches.last[:sort].
|
|
96
|
+
expect(connection.searches.last[:sort]).to match(/^random_9001 asc$/)
|
|
83
97
|
end
|
|
84
98
|
|
|
85
99
|
it 'orders by random with provided seed value and direction' do
|
|
86
100
|
search do
|
|
87
101
|
order_by :random, :seed => 12345, :direction => :desc
|
|
88
102
|
end
|
|
89
|
-
connection.searches.last[:sort].
|
|
103
|
+
expect(connection.searches.last[:sort]).to match(/^random_12345 desc$/)
|
|
90
104
|
end
|
|
91
105
|
|
|
92
106
|
it 'orders by score' do
|
|
93
107
|
search do
|
|
94
108
|
order_by :score, :desc
|
|
95
109
|
end
|
|
96
|
-
connection.
|
|
110
|
+
expect(connection).to have_last_search_with(:sort => 'score desc')
|
|
97
111
|
end
|
|
98
112
|
|
|
99
113
|
it 'orders by geodist' do
|
|
100
114
|
search do
|
|
101
115
|
order_by_geodist :coordinates_new, 32, -68, :desc
|
|
102
116
|
end
|
|
103
|
-
connection.
|
|
117
|
+
expect(connection).to have_last_search_with(:sort => 'geodist(coordinates_new_ll,32,-68) desc')
|
|
104
118
|
end
|
|
105
119
|
|
|
106
120
|
it 'throws an ArgumentError if a bogus order direction is given' do
|
|
107
|
-
|
|
121
|
+
expect do
|
|
108
122
|
search do
|
|
109
123
|
order_by :sort_title, :sideways
|
|
110
124
|
end
|
|
111
|
-
end.
|
|
125
|
+
end.to raise_error(ArgumentError)
|
|
112
126
|
end
|
|
113
127
|
|
|
114
128
|
it 'throws an UnrecognizedFieldError if :distance is given for sort' do
|
|
115
|
-
|
|
129
|
+
expect do
|
|
116
130
|
search do
|
|
117
131
|
order_by :distance, :asc
|
|
118
132
|
end
|
|
119
|
-
end.
|
|
133
|
+
end.to raise_error(Sunspot::UnrecognizedFieldError)
|
|
120
134
|
end
|
|
121
135
|
|
|
122
136
|
it 'does not allow ordering by multiple-value fields' do
|
|
123
|
-
|
|
137
|
+
expect do
|
|
124
138
|
search do
|
|
125
139
|
order_by :category_ids
|
|
126
140
|
end
|
|
127
|
-
end.
|
|
141
|
+
end.to raise_error(ArgumentError)
|
|
128
142
|
end
|
|
129
143
|
|
|
130
144
|
it 'raises ArgumentError if bogus argument given to paginate' do
|
|
131
|
-
|
|
145
|
+
expect do
|
|
132
146
|
search do
|
|
133
147
|
paginate :page => 4, :ugly => :puppy
|
|
134
148
|
end
|
|
135
|
-
end.
|
|
149
|
+
end.to raise_error(ArgumentError)
|
|
136
150
|
end
|
|
137
151
|
end
|
|
@@ -3,14 +3,14 @@ shared_examples_for "scoped query" do
|
|
|
3
3
|
search do
|
|
4
4
|
with :title, 'My Pet Post'
|
|
5
5
|
end
|
|
6
|
-
connection.
|
|
6
|
+
expect(connection).to have_last_search_including(:fq, 'title_ss:My\ Pet\ Post')
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
it 'scopes by exact match with a special string' do
|
|
10
10
|
search do
|
|
11
11
|
with :title, 'OR'
|
|
12
12
|
end
|
|
13
|
-
connection.
|
|
13
|
+
expect(connection).to have_last_search_including(:fq, 'title_ss:"OR"')
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it 'scopes by exact match with time' do
|
|
@@ -18,7 +18,7 @@ shared_examples_for "scoped query" do
|
|
|
18
18
|
search do
|
|
19
19
|
with :published_at, time
|
|
20
20
|
end
|
|
21
|
-
connection.
|
|
21
|
+
expect(connection).to have_last_search_including(
|
|
22
22
|
:fq,
|
|
23
23
|
'published_at_dt:1983\-07\-08T09\:00\:00Z'
|
|
24
24
|
)
|
|
@@ -29,7 +29,7 @@ shared_examples_for "scoped query" do
|
|
|
29
29
|
search do
|
|
30
30
|
with :expire_date, date
|
|
31
31
|
end
|
|
32
|
-
connection.
|
|
32
|
+
expect(connection).to have_last_search_including(
|
|
33
33
|
:fq,
|
|
34
34
|
'expire_date_d:1983\-07\-08T00\:00\:00Z'
|
|
35
35
|
)
|
|
@@ -39,133 +39,133 @@ shared_examples_for "scoped query" do
|
|
|
39
39
|
search do
|
|
40
40
|
with :featured, false
|
|
41
41
|
end
|
|
42
|
-
connection.
|
|
42
|
+
expect(connection).to have_last_search_including(:fq, 'featured_bs:false')
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
it 'scopes by less than match with float' do
|
|
46
46
|
search do
|
|
47
47
|
with(:average_rating).less_than 3.0
|
|
48
48
|
end
|
|
49
|
-
connection.
|
|
49
|
+
expect(connection).to have_last_search_including(:fq, 'average_rating_ft:{* TO 3\.0}')
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it 'should quote string with space in a less than match' do
|
|
53
53
|
search do
|
|
54
54
|
with(:title).less_than('test value')
|
|
55
55
|
end
|
|
56
|
-
connection.
|
|
56
|
+
expect(connection).to have_last_search_including(:fq, 'title_ss:{* TO "test\ value"}')
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
it 'scopes by greater than match with float' do
|
|
60
60
|
search do
|
|
61
61
|
with(:average_rating).greater_than 3.0
|
|
62
62
|
end
|
|
63
|
-
connection.
|
|
63
|
+
expect(connection).to have_last_search_including(:fq, 'average_rating_ft:{3\.0 TO *}')
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it 'scopes by short-form between match with integers' do
|
|
67
67
|
search do
|
|
68
68
|
with :blog_id, 2..4
|
|
69
69
|
end
|
|
70
|
-
connection.
|
|
70
|
+
expect(connection).to have_last_search_including(:fq, 'blog_id_i:[2 TO 4]')
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
it 'scopes by between match with float' do
|
|
74
74
|
search do
|
|
75
75
|
with(:average_rating).between 2.0..4.0
|
|
76
76
|
end
|
|
77
|
-
connection.
|
|
77
|
+
expect(connection).to have_last_search_including(:fq, 'average_rating_ft:[2\.0 TO 4\.0]')
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
it 'scopes by any match with integer' do
|
|
81
81
|
search do
|
|
82
82
|
with(:category_ids).any_of [2, 7, 12]
|
|
83
83
|
end
|
|
84
|
-
connection.
|
|
84
|
+
expect(connection).to have_last_search_including(:fq, 'category_ids_im:(2 OR 7 OR 12)')
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it 'scopes by short-form any-of match with integers' do
|
|
88
88
|
search do
|
|
89
89
|
with :category_ids, [2, 7, 12]
|
|
90
90
|
end
|
|
91
|
-
connection.
|
|
91
|
+
expect(connection).to have_last_search_including(:fq, 'category_ids_im:(2 OR 7 OR 12)')
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
it 'scopes by all match with integer' do
|
|
95
95
|
search do
|
|
96
96
|
with(:category_ids).all_of [2, 7, 12]
|
|
97
97
|
end
|
|
98
|
-
connection.
|
|
98
|
+
expect(connection).to have_last_search_including(:fq, 'category_ids_im:(2 AND 7 AND 12)')
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
it 'scopes by prefix match with string' do
|
|
102
102
|
search do
|
|
103
103
|
with(:title).starting_with('tes')
|
|
104
104
|
end
|
|
105
|
-
connection.
|
|
105
|
+
expect(connection).to have_last_search_including(:fq, 'title_ss:tes*')
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
it 'scopes by not equal match with string' do
|
|
109
109
|
search do
|
|
110
110
|
without :title, 'Bad Post'
|
|
111
111
|
end
|
|
112
|
-
connection.
|
|
112
|
+
expect(connection).to have_last_search_including(:fq, '-title_ss:Bad\ Post')
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
it 'scopes by not less than match with float' do
|
|
116
116
|
search do
|
|
117
117
|
without(:average_rating).less_than 3.0
|
|
118
118
|
end
|
|
119
|
-
connection.
|
|
119
|
+
expect(connection).to have_last_search_including(:fq, '-average_rating_ft:{* TO 3\.0}')
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
it 'scopes by not greater than match with float' do
|
|
123
123
|
search do
|
|
124
124
|
without(:average_rating).greater_than 3.0
|
|
125
125
|
end
|
|
126
|
-
connection.
|
|
126
|
+
expect(connection).to have_last_search_including(:fq, '-average_rating_ft:{3\.0 TO *}')
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
it 'scopes by not between match with shorthand' do
|
|
130
130
|
search do
|
|
131
131
|
without(:blog_id, 2..4)
|
|
132
132
|
end
|
|
133
|
-
connection.
|
|
133
|
+
expect(connection).to have_last_search_including(:fq, '-blog_id_i:[2 TO 4]')
|
|
134
134
|
end
|
|
135
135
|
|
|
136
136
|
it 'scopes by not between match with float' do
|
|
137
137
|
search do
|
|
138
138
|
without(:average_rating).between 2.0..4.0
|
|
139
139
|
end
|
|
140
|
-
connection.
|
|
140
|
+
expect(connection).to have_last_search_including(:fq, '-average_rating_ft:[2\.0 TO 4\.0]')
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it 'scopes by not any match with integer' do
|
|
144
144
|
search do
|
|
145
145
|
without(:category_ids).any_of [2, 7, 12]
|
|
146
146
|
end
|
|
147
|
-
connection.
|
|
147
|
+
expect(connection).to have_last_search_including(:fq, '-category_ids_im:(2 OR 7 OR 12)')
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
it 'scopes by not all match with integer' do
|
|
151
151
|
search do
|
|
152
152
|
without(:category_ids).all_of [2, 7, 12]
|
|
153
153
|
end
|
|
154
|
-
connection.
|
|
154
|
+
expect(connection).to have_last_search_including(:fq, '-category_ids_im:(2 AND 7 AND 12)')
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
it 'scopes by empty field' do
|
|
158
158
|
search do
|
|
159
159
|
with :average_rating, nil
|
|
160
160
|
end
|
|
161
|
-
connection.
|
|
161
|
+
expect(connection).to have_last_search_including(:fq, '-average_rating_ft:[* TO *]')
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
it 'scopes by non-empty field' do
|
|
165
165
|
search do
|
|
166
166
|
without :average_rating, nil
|
|
167
167
|
end
|
|
168
|
-
connection.
|
|
168
|
+
expect(connection).to have_last_search_including(:fq, 'average_rating_ft:[* TO *]')
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
it 'includes by object identity' do
|
|
@@ -173,7 +173,7 @@ shared_examples_for "scoped query" do
|
|
|
173
173
|
search do
|
|
174
174
|
with post
|
|
175
175
|
end
|
|
176
|
-
connection.
|
|
176
|
+
expect(connection).to have_last_search_including(:fq, "id:(Post\\ #{post.id})")
|
|
177
177
|
end
|
|
178
178
|
|
|
179
179
|
it 'includes multiple objects passed as varargs by object identity' do
|
|
@@ -181,7 +181,7 @@ shared_examples_for "scoped query" do
|
|
|
181
181
|
search do
|
|
182
182
|
with post1, post2
|
|
183
183
|
end
|
|
184
|
-
connection.
|
|
184
|
+
expect(connection).to have_last_search_including(
|
|
185
185
|
:fq, "id:(Post\\ #{post1.id} OR Post\\ #{post2.id})"
|
|
186
186
|
)
|
|
187
187
|
end
|
|
@@ -191,7 +191,7 @@ shared_examples_for "scoped query" do
|
|
|
191
191
|
search do
|
|
192
192
|
with posts
|
|
193
193
|
end
|
|
194
|
-
connection.
|
|
194
|
+
expect(connection).to have_last_search_including(
|
|
195
195
|
:fq, "id:(Post\\ #{posts.first.id} OR Post\\ #{posts.last.id})"
|
|
196
196
|
)
|
|
197
197
|
end
|
|
@@ -201,7 +201,7 @@ shared_examples_for "scoped query" do
|
|
|
201
201
|
search do
|
|
202
202
|
without post
|
|
203
203
|
end
|
|
204
|
-
connection.
|
|
204
|
+
expect(connection).to have_last_search_including(:fq, "-id:(Post\\ #{post.id})")
|
|
205
205
|
end
|
|
206
206
|
|
|
207
207
|
it 'excludes multiple objects passed as varargs by object identity' do
|
|
@@ -209,7 +209,7 @@ shared_examples_for "scoped query" do
|
|
|
209
209
|
search do
|
|
210
210
|
without post1, post2
|
|
211
211
|
end
|
|
212
|
-
connection.
|
|
212
|
+
expect(connection).to have_last_search_including(
|
|
213
213
|
:fq,
|
|
214
214
|
"-id:(Post\\ #{post1.id} OR Post\\ #{post2.id})"
|
|
215
215
|
)
|
|
@@ -220,7 +220,7 @@ shared_examples_for "scoped query" do
|
|
|
220
220
|
search do
|
|
221
221
|
without posts
|
|
222
222
|
end
|
|
223
|
-
connection.
|
|
223
|
+
expect(connection).to have_last_search_including(
|
|
224
224
|
:fq,
|
|
225
225
|
"-id:(Post\\ #{posts.first.id} OR Post\\ #{posts.last.id})"
|
|
226
226
|
)
|
|
@@ -231,45 +231,45 @@ shared_examples_for "scoped query" do
|
|
|
231
231
|
search Post, Namespaced::Comment do
|
|
232
232
|
with :published_at, time
|
|
233
233
|
end
|
|
234
|
-
connection.
|
|
234
|
+
expect(connection).to have_last_search_including(:fq, 'published_at_dt:1983\-07\-08T09\:00\:00Z')
|
|
235
235
|
end
|
|
236
236
|
|
|
237
237
|
it 'allows scoping on field not common to all types' do
|
|
238
238
|
search Post, Namespaced::Comment do
|
|
239
239
|
with :blog_id, 1
|
|
240
240
|
end
|
|
241
|
-
connection.
|
|
241
|
+
expect(connection).to have_last_search_including(:fq, 'blog_id_i:1')
|
|
242
242
|
end
|
|
243
243
|
|
|
244
244
|
it 'raises Sunspot::UnrecognizedFieldError if search scoped to field configured differently between types' do
|
|
245
|
-
|
|
245
|
+
expect do
|
|
246
246
|
search Post, Namespaced::Comment do
|
|
247
247
|
with :average_rating, 2.2 # this is a float in Post but an integer in Comment
|
|
248
248
|
end
|
|
249
|
-
end.
|
|
249
|
+
end.to raise_error(Sunspot::UnrecognizedFieldError)
|
|
250
250
|
end
|
|
251
251
|
|
|
252
252
|
it 'raises Sunspot::UnrecognizedFieldError for nonexistant fields in block scope' do
|
|
253
|
-
|
|
253
|
+
expect do
|
|
254
254
|
search do
|
|
255
255
|
with :bogus, 'Field'
|
|
256
256
|
end
|
|
257
|
-
end.
|
|
257
|
+
end.to raise_error(Sunspot::UnrecognizedFieldError)
|
|
258
258
|
end
|
|
259
259
|
|
|
260
260
|
it 'raises NoMethodError if bogus operator referenced' do
|
|
261
|
-
|
|
261
|
+
expect do
|
|
262
262
|
search do
|
|
263
263
|
with(:category_ids).resembling :bogus_condition
|
|
264
264
|
end
|
|
265
|
-
end.
|
|
265
|
+
end.to raise_error(NoMethodError)
|
|
266
266
|
end
|
|
267
267
|
|
|
268
268
|
it 'should raise ArgumentError if more than two arguments passed to scope method' do
|
|
269
|
-
|
|
269
|
+
expect do
|
|
270
270
|
search do
|
|
271
271
|
with(:category_ids, 4, 5)
|
|
272
272
|
end
|
|
273
|
-
end.
|
|
273
|
+
end.to raise_error(ArgumentError)
|
|
274
274
|
end
|
|
275
275
|
end
|