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
|
@@ -25,13 +25,13 @@ describe 'local search' do
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it 'should return results in geo order' do
|
|
28
|
-
@search.results.
|
|
28
|
+
expect(@search.results).to eq(@posts)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it 'should asssign higher score to closer locations' do
|
|
32
32
|
hits = @search.hits
|
|
33
33
|
hits[1..-1].each_with_index do |hit, i|
|
|
34
|
-
hit.score.
|
|
34
|
+
expect(hit.score).to be < hits[i].score
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -51,13 +51,13 @@ describe 'local search' do
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it 'should take both fulltext and distance into account in ordering' do
|
|
54
|
-
@search.results.
|
|
54
|
+
expect(@search.results).to eq(@posts)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
it 'should take both fulltext and distance into account in scoring' do
|
|
58
58
|
hits = @search.hits
|
|
59
59
|
hits[1..-1].each_with_index do |hit, i|
|
|
60
|
-
hit.score.
|
|
60
|
+
expect(hit.score).to be < hits[i].score
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
end
|
|
@@ -14,30 +14,30 @@ describe 'more_like_this' do
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it 'should return results for all MLT fields' do
|
|
17
|
-
Sunspot.more_like_this(@posts.first).results.to_set.
|
|
17
|
+
expect(Sunspot.more_like_this(@posts.first).results.to_set).to eq(@posts[1..3].to_set)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it 'should return results for specified text field' do
|
|
21
|
-
Sunspot.more_like_this(@posts.first) do
|
|
21
|
+
expect(Sunspot.more_like_this(@posts.first) do
|
|
22
22
|
fields :body
|
|
23
|
-
end.results.to_set.
|
|
23
|
+
end.results.to_set).to eq(@posts[2..3].to_set)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it 'should return empty result set if no results' do
|
|
27
|
-
Sunspot.more_like_this(@posts.last) do
|
|
27
|
+
expect(Sunspot.more_like_this(@posts.last) do
|
|
28
28
|
with(:title, 'bogus')
|
|
29
|
-
end.results.
|
|
29
|
+
end.results).to eq([])
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
describe 'when non-indexed object searched' do
|
|
33
33
|
before(:each) { @mlt = Sunspot.more_like_this(Post.new) }
|
|
34
34
|
|
|
35
35
|
it 'should return empty result set' do
|
|
36
|
-
@mlt.results.
|
|
36
|
+
expect(@mlt.results).to eq([])
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it 'shoult return a total of 0' do
|
|
40
|
-
@mlt.total.
|
|
40
|
+
expect(@mlt.total).to eq(0)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -22,95 +22,95 @@ describe 'scoped_search' do
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it 'should filter by exact match' do
|
|
25
|
-
Sunspot.search(clazz) { with(field, values[2]) }.results.
|
|
25
|
+
expect(Sunspot.search(clazz) { with(field, values[2]) }.results).to eq([@objects[2]])
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it 'should reject by inexact match' do
|
|
29
29
|
results = Sunspot.search(clazz) { without(field, values[2]) }.results
|
|
30
|
-
[0, 1, 3, 4].each { |i| results.
|
|
31
|
-
results.
|
|
30
|
+
[0, 1, 3, 4].each { |i| expect(results).to include(@objects[i]) }
|
|
31
|
+
expect(results).not_to include(@objects[2])
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
it 'should filter by less than' do
|
|
35
35
|
results = Sunspot.search(clazz) { with(field).less_than values[2] }.results
|
|
36
|
-
(0..1).each { |i| results.
|
|
37
|
-
(2..4).each { |i| results.
|
|
36
|
+
(0..1).each { |i| expect(results).to include(@objects[i]) }
|
|
37
|
+
(2..4).each { |i| expect(results).not_to include(@objects[i]) }
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it 'should reject by less than' do
|
|
41
41
|
results = Sunspot.search(clazz) { without(field).less_than values[2] }.results
|
|
42
|
-
(0..1).each { |i| results.
|
|
43
|
-
(2..4).each { |i| results.
|
|
42
|
+
(0..1).each { |i| expect(results).not_to include(@objects[i]) }
|
|
43
|
+
(2..4).each { |i| expect(results).to include(@objects[i]) }
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it 'should filter by less than or equal to' do
|
|
47
47
|
results = Sunspot.search(clazz) { with(field).less_than_or_equal_to values[2] }.results
|
|
48
|
-
(0..2).each { |i| results.
|
|
49
|
-
(3..4).each { |i| results.
|
|
48
|
+
(0..2).each { |i| expect(results).to include(@objects[i]) }
|
|
49
|
+
(3..4).each { |i| expect(results).not_to include(@objects[i]) }
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it 'should reject by less than or equal to' do
|
|
53
53
|
results = Sunspot.search(clazz) { without(field).less_than_or_equal_to values[2] }.results
|
|
54
|
-
(0..2).each { |i| results.
|
|
55
|
-
(3..4).each { |i| results.
|
|
54
|
+
(0..2).each { |i| expect(results).not_to include(@objects[i]) }
|
|
55
|
+
(3..4).each { |i| expect(results).to include(@objects[i]) }
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it 'should filter by greater than' do
|
|
59
59
|
results = Sunspot.search(clazz) { with(field).greater_than values[2] }.results
|
|
60
|
-
(3..4).each { |i| results.
|
|
61
|
-
(0..2).each { |i| results.
|
|
60
|
+
(3..4).each { |i| expect(results).to include(@objects[i]) }
|
|
61
|
+
(0..2).each { |i| expect(results).not_to include(@objects[i]) }
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
it 'should reject by greater than' do
|
|
65
65
|
results = Sunspot.search(clazz) { without(field).greater_than values[2] }.results
|
|
66
|
-
(3..4).each { |i| results.
|
|
67
|
-
(0..2).each { |i| results.
|
|
66
|
+
(3..4).each { |i| expect(results).not_to include(@objects[i]) }
|
|
67
|
+
(0..2).each { |i| expect(results).to include(@objects[i]) }
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
it 'should filter by greater than or equal to' do
|
|
71
71
|
results = Sunspot.search(clazz) { with(field).greater_than_or_equal_to values[2] }.results
|
|
72
|
-
(2..4).each { |i| results.
|
|
73
|
-
(0..1).each { |i| results.
|
|
72
|
+
(2..4).each { |i| expect(results).to include(@objects[i]) }
|
|
73
|
+
(0..1).each { |i| expect(results).not_to include(@objects[i]) }
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
it 'should reject by greater than' do
|
|
77
77
|
results = Sunspot.search(clazz) { without(field).greater_than_or_equal_to values[2] }.results
|
|
78
|
-
(2..4).each { |i| results.
|
|
79
|
-
(0..1).each { |i| results.
|
|
78
|
+
(2..4).each { |i| expect(results).not_to include(@objects[i]) }
|
|
79
|
+
(0..1).each { |i| expect(results).to include(@objects[i]) }
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it 'should filter by between' do
|
|
83
83
|
results = Sunspot.search(clazz) { with(field).between(values[1]..values[3]) }.results
|
|
84
|
-
(1..3).each { |i| results.
|
|
85
|
-
[0, 4].each { |i| results.
|
|
84
|
+
(1..3).each { |i| expect(results).to include(@objects[i]) }
|
|
85
|
+
[0, 4].each { |i| expect(results).not_to include(@objects[i]) }
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
it 'should reject by between' do
|
|
89
89
|
results = Sunspot.search(clazz) { without(field).between(values[1]..values[3]) }.results
|
|
90
|
-
(1..3).each { |i| results.
|
|
91
|
-
[0, 4].each { |i| results.
|
|
90
|
+
(1..3).each { |i| expect(results).not_to include(@objects[i]) }
|
|
91
|
+
[0, 4].each { |i| expect(results).to include(@objects[i]) }
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
it 'should filter by any of' do
|
|
95
95
|
results = Sunspot.search(clazz) { with(field).any_of(values.values_at(1, 3)) }.results
|
|
96
|
-
[1, 3].each { |i| results.
|
|
97
|
-
[0, 2, 4].each { |i| results.
|
|
96
|
+
[1, 3].each { |i| expect(results).to include(@objects[i]) }
|
|
97
|
+
[0, 2, 4].each { |i| expect(results).not_to include(@objects[i]) }
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it 'should reject by any of' do
|
|
101
101
|
results = Sunspot.search(clazz) { without(field).any_of(values.values_at(1, 3)) }.results
|
|
102
|
-
[1, 3].each { |i| results.
|
|
103
|
-
[0, 2, 4].each { |i| results.
|
|
102
|
+
[1, 3].each { |i| expect(results).not_to include(@objects[i]) }
|
|
103
|
+
[0, 2, 4].each { |i| expect(results).to include(@objects[i]) }
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
it 'should order by field ascending' do
|
|
107
107
|
results = Sunspot.search(clazz) { order_by field, :asc }.results
|
|
108
|
-
results.
|
|
108
|
+
expect(results).to eq(@objects)
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
it 'should order by field descending' do
|
|
112
112
|
results = Sunspot.search(clazz) { order_by field, :desc }.results
|
|
113
|
-
results.
|
|
113
|
+
expect(results).to eq(@objects.reverse)
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
116
|
end
|
|
@@ -126,6 +126,56 @@ describe 'scoped_search' do
|
|
|
126
126
|
test_field_type 'Trie Float', :average_rating, :average_rating, Photo, -2.5, 0.0, 3.2, 3.5, 16.0
|
|
127
127
|
test_field_type 'Trie Time', :created_at, :created_at, Photo, *(['1970-01-01 00:00:00 UTC', '1983-07-08 04:00:00 UTC', '1983-07-08 02:00:00 -0500',
|
|
128
128
|
'2005-11-05 10:00:00 UTC', Time.now.to_s].map { |t| Time.parse(t) })
|
|
129
|
+
describe 'Date range field type' do
|
|
130
|
+
let(:date_ranges) do
|
|
131
|
+
{
|
|
132
|
+
'December and January' => Date.new(2014,12,25)..Date.new(2015,1,10),
|
|
133
|
+
'January only' => Date.new(2015,1,5)..Date.new(2015,1,20),
|
|
134
|
+
'January and February' => Date.new(2015,1,25)..Date.new(2015,2,10),
|
|
135
|
+
'February only' => Date.new(2015,2,5)..Date.new(2015,2,20),
|
|
136
|
+
'December to February' => Date.new(2014,12,25)..Date.new(2015,2,10),
|
|
137
|
+
'January to March' => Date.new(2015,1,25)..Date.new(2015,3,10),
|
|
138
|
+
'December to March' => Date.new(2014,12,25)..Date.new(2015,3,20)
|
|
139
|
+
}
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
before :all do
|
|
143
|
+
january = Date.new(2015,1,1)..Date.new(2015,1,31)
|
|
144
|
+
february = Date.new(2015,2,1)..Date.new(2015,2,28)
|
|
145
|
+
Sunspot.remove_all
|
|
146
|
+
@posts = [Post.new(featured_for: january), Post.new(featured_for: february), Post.new]
|
|
147
|
+
Sunspot.index!(@posts)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it 'should filter by Contains' do
|
|
151
|
+
expect(featured_for_posts(:containing, Date.new(2015,1,15) )).to eq([@posts[0]])
|
|
152
|
+
expect(featured_for_posts(:containing, 'December and January')).to be_empty
|
|
153
|
+
expect(featured_for_posts(:containing, 'January only')).to eq([@posts[0]])
|
|
154
|
+
expect(featured_for_posts(:containing, 'January only', negated = true)).to eq(@posts[1..-1])
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'should filter by Intersects' do
|
|
158
|
+
expect(featured_for_posts(:intersecting, Date.new(2015,1,15) )).to eq([@posts[0]])
|
|
159
|
+
expect(featured_for_posts(:intersecting, 'January only')).to eq([@posts[0]])
|
|
160
|
+
expect(featured_for_posts(:intersecting, 'January and February')).to eq(@posts[0..1])
|
|
161
|
+
expect(featured_for_posts(:intersecting, 'January and February', negated = true)).to eq([@posts[2]])
|
|
162
|
+
expect(featured_for_posts(:intersecting, 'February only')).to eq([@posts[1]])
|
|
163
|
+
expect(featured_for_posts(:intersecting, 'February only', negated = true)).to eq([@posts[0], @posts[2]])
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it 'should filter by Within' do
|
|
167
|
+
expect(featured_for_posts(:within, Date.new(2015,1,15) )).to be_empty
|
|
168
|
+
(date_ranges.keys - date_ranges.keys.grep(/ to /)).each do |key|
|
|
169
|
+
expect(featured_for_posts(:within, key)).to be_empty
|
|
170
|
+
end
|
|
171
|
+
expect(featured_for_posts(:within, 'December to February')).to eq([@posts[0]])
|
|
172
|
+
expect(featured_for_posts(:within, 'December to February', negated = true)).to eq(@posts[1..-1])
|
|
173
|
+
expect(featured_for_posts(:within, 'January to March')).to eq([@posts[1]])
|
|
174
|
+
expect(featured_for_posts(:within, 'January to March', negated = true)).to eq([@posts[0], @posts[2]])
|
|
175
|
+
expect(featured_for_posts(:within, 'December to March')).to eq(@posts[0..1])
|
|
176
|
+
expect(featured_for_posts(:within, 'December to March', negated = true)).to eq([@posts[2]])
|
|
177
|
+
end
|
|
178
|
+
end
|
|
129
179
|
|
|
130
180
|
describe 'Boolean field type' do
|
|
131
181
|
before :all do
|
|
@@ -135,11 +185,11 @@ describe 'scoped_search' do
|
|
|
135
185
|
end
|
|
136
186
|
|
|
137
187
|
it 'should filter by exact match for true' do
|
|
138
|
-
Sunspot.search(Post) { with(:featured, true) }.results.
|
|
188
|
+
expect(Sunspot.search(Post) { with(:featured, true) }.results).to eq([@posts[0]])
|
|
139
189
|
end
|
|
140
190
|
|
|
141
191
|
it 'should filter for exact match for false' do
|
|
142
|
-
Sunspot.search(Post) { with(:featured, false) }.results.
|
|
192
|
+
expect(Sunspot.search(Post) { with(:featured, false) }.results).to eq([@posts[1]])
|
|
143
193
|
end
|
|
144
194
|
end
|
|
145
195
|
|
|
@@ -147,7 +197,7 @@ describe 'scoped_search' do
|
|
|
147
197
|
it "allows for using symbols in defining static field names" do
|
|
148
198
|
Sunspot.remove_all
|
|
149
199
|
Sunspot.index!(legacy = Post.new(:title => "foo"))
|
|
150
|
-
Sunspot.search(Post) { with(:legacy, "legacy foo") }.results.
|
|
200
|
+
expect(Sunspot.search(Post) { with(:legacy, "legacy foo") }.results).to eq([legacy])
|
|
151
201
|
end
|
|
152
202
|
end
|
|
153
203
|
|
|
@@ -155,7 +205,7 @@ describe 'scoped_search' do
|
|
|
155
205
|
%w(AND OR NOT TO).each do |word|
|
|
156
206
|
it "should successfully search for #{word.inspect}" do
|
|
157
207
|
Sunspot.index!(post = Post.new(:title => word))
|
|
158
|
-
Sunspot.search(Post) { with(:title, word) }.results.
|
|
208
|
+
expect(Sunspot.search(Post) { with(:title, word) }.results).to eq([post])
|
|
159
209
|
end
|
|
160
210
|
end
|
|
161
211
|
end
|
|
@@ -168,11 +218,11 @@ describe 'scoped_search' do
|
|
|
168
218
|
end
|
|
169
219
|
|
|
170
220
|
it 'should filter results without value for field' do
|
|
171
|
-
Sunspot.search(Post) { with(:title, nil) }.results.
|
|
221
|
+
expect(Sunspot.search(Post) { with(:title, nil) }.results).to eq([@posts[1]])
|
|
172
222
|
end
|
|
173
223
|
|
|
174
224
|
it 'should exclude results without value for field' do
|
|
175
|
-
Sunspot.search(Post) { without(:title, nil) }.results.
|
|
225
|
+
expect(Sunspot.search(Post) { without(:title, nil) }.results).to eq([@posts[0]])
|
|
176
226
|
end
|
|
177
227
|
end
|
|
178
228
|
|
|
@@ -186,12 +236,13 @@ describe 'scoped_search' do
|
|
|
186
236
|
end
|
|
187
237
|
|
|
188
238
|
it 'should return results whose prefix matches' do
|
|
189
|
-
Sunspot.search(Post) { with(:title).starting_with('test') }.results.
|
|
239
|
+
expect(Sunspot.search(Post) { with(:title).starting_with('test') }.results).to eq(@posts[0..1])
|
|
190
240
|
end
|
|
191
241
|
end
|
|
192
242
|
|
|
193
243
|
describe 'inclusion by identity' do
|
|
194
244
|
before do
|
|
245
|
+
Sunspot.remove_all
|
|
195
246
|
@posts = (1..5).map do |i|
|
|
196
247
|
post = Post.new
|
|
197
248
|
Sunspot.index(post)
|
|
@@ -202,26 +253,27 @@ describe 'scoped_search' do
|
|
|
202
253
|
|
|
203
254
|
it 'should only return included object' do
|
|
204
255
|
included_post = @posts.shift
|
|
205
|
-
Sunspot.search(Post) { with(included_post) }.results.
|
|
256
|
+
expect(Sunspot.search(Post) { with(included_post) }.results).to include(included_post)
|
|
206
257
|
end
|
|
207
258
|
|
|
208
259
|
it 'should not return objects not included' do
|
|
209
260
|
included_post = @posts.shift
|
|
210
261
|
for excluded_post in @posts
|
|
211
|
-
Sunspot.search(Post) { with(included_post) }.results.
|
|
262
|
+
expect(Sunspot.search(Post) { with(included_post) }.results).not_to include(excluded_post)
|
|
212
263
|
end
|
|
213
264
|
end
|
|
214
265
|
|
|
215
266
|
it 'should return included objects' do
|
|
216
267
|
included_posts = [@posts.shift, @posts.shift]
|
|
217
268
|
for included_post in included_posts
|
|
218
|
-
Sunspot.search(Post) { with(included_posts) }.results.
|
|
269
|
+
expect(Sunspot.search(Post) { with(included_posts) }.results).to include(included_post)
|
|
219
270
|
end
|
|
220
271
|
end
|
|
221
272
|
end
|
|
222
273
|
|
|
223
274
|
describe 'exclusion by identity' do
|
|
224
275
|
before do
|
|
276
|
+
Sunspot.remove_all
|
|
225
277
|
@posts = (1..5).map do |i|
|
|
226
278
|
post = Post.new
|
|
227
279
|
Sunspot.index(post)
|
|
@@ -232,20 +284,20 @@ describe 'scoped_search' do
|
|
|
232
284
|
|
|
233
285
|
it 'should not return excluded object' do
|
|
234
286
|
excluded_post = @posts.shift
|
|
235
|
-
Sunspot.search(Post) { without(excluded_post) }.results.
|
|
287
|
+
expect(Sunspot.search(Post) { without(excluded_post) }.results).not_to include(excluded_post)
|
|
236
288
|
end
|
|
237
289
|
|
|
238
290
|
it 'should return objects not excluded' do
|
|
239
291
|
excluded_post = @posts.shift
|
|
240
292
|
for included_post in @posts
|
|
241
|
-
Sunspot.search(Post) { without(excluded_post) }.results.
|
|
293
|
+
expect(Sunspot.search(Post) { without(excluded_post) }.results).to include(included_post)
|
|
242
294
|
end
|
|
243
295
|
end
|
|
244
296
|
|
|
245
297
|
it 'should not return excluded objects' do
|
|
246
298
|
excluded_posts = [@posts.shift, @posts.shift]
|
|
247
299
|
for excluded_post in excluded_posts
|
|
248
|
-
Sunspot.search(Post) { without(excluded_posts) }.results.
|
|
300
|
+
expect(Sunspot.search(Post) { without(excluded_posts) }.results).not_to include(excluded_post)
|
|
249
301
|
end
|
|
250
302
|
end
|
|
251
303
|
end
|
|
@@ -258,12 +310,50 @@ describe 'scoped_search' do
|
|
|
258
310
|
it 'should return results that match any restriction in a disjunction' do
|
|
259
311
|
posts = (1..3).map { |i| Post.new(:blog_id => i)}
|
|
260
312
|
Sunspot.index!(posts)
|
|
261
|
-
Sunspot.search(Post) do
|
|
313
|
+
expect(Sunspot.search(Post) do
|
|
262
314
|
any_of do
|
|
263
315
|
with(:blog_id, 1)
|
|
264
316
|
with(:blog_id, 2)
|
|
265
317
|
end
|
|
266
|
-
end.results.
|
|
318
|
+
end.results).to eq(posts[0..1])
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it 'should return results, ignoring any restriction in a disjunction that has been passed an empty array' do
|
|
322
|
+
posts = (1..3).map { |i| Post.new(:blog_id => i)}
|
|
323
|
+
Sunspot.index!(posts)
|
|
324
|
+
expect(Sunspot.search(Post) do
|
|
325
|
+
with(:blog_id, [])
|
|
326
|
+
end.results).to eq(posts)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it 'should return results, ignoring any restriction in a negative disjunction that has been passed an empty array' do
|
|
330
|
+
posts = (1..3).map { |i| Post.new(:blog_id => i)}
|
|
331
|
+
Sunspot.index!(posts)
|
|
332
|
+
expect(Sunspot.search(Post) do
|
|
333
|
+
without(:blog_id, [])
|
|
334
|
+
end.results).to eq(posts)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
it 'should return results, ignoring any restriction in a conjunction that has been passed an empty array' do
|
|
338
|
+
posts = (1..3).map { |i| Post.new(:blog_id => i)}
|
|
339
|
+
Sunspot.index!(posts)
|
|
340
|
+
expect(Sunspot.search(Post) do
|
|
341
|
+
all_of do
|
|
342
|
+
with(:blog_id, 1)
|
|
343
|
+
with(:blog_id, [])
|
|
344
|
+
end
|
|
345
|
+
end.results).to eq(posts[0..0])
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
it 'should return results, ignoring any restriction in a negative conjunction that has been passed an empty array' do
|
|
349
|
+
posts = (1..3).map { |i| Post.new(:blog_id => i)}
|
|
350
|
+
Sunspot.index!(posts)
|
|
351
|
+
expect(Sunspot.search(Post) do
|
|
352
|
+
all_of do
|
|
353
|
+
with(:blog_id, 1)
|
|
354
|
+
without(:blog_id, [])
|
|
355
|
+
end
|
|
356
|
+
end.results).to eq(posts[0..0])
|
|
267
357
|
end
|
|
268
358
|
|
|
269
359
|
it 'should return results that match a nested conjunction in a disjunction' do
|
|
@@ -274,7 +364,7 @@ describe 'scoped_search' do
|
|
|
274
364
|
Post.new(:title => 'No', :blog_id => 2)
|
|
275
365
|
]
|
|
276
366
|
Sunspot.index!(posts)
|
|
277
|
-
Sunspot.search(Post) do
|
|
367
|
+
expect(Sunspot.search(Post) do
|
|
278
368
|
any_of do
|
|
279
369
|
with(:blog_id, 1)
|
|
280
370
|
all_of do
|
|
@@ -282,7 +372,7 @@ describe 'scoped_search' do
|
|
|
282
372
|
with(:title, 'Yes')
|
|
283
373
|
end
|
|
284
374
|
end
|
|
285
|
-
end.results.
|
|
375
|
+
end.results).to eq(posts[0..1])
|
|
286
376
|
end
|
|
287
377
|
|
|
288
378
|
it 'should return results that match a conjunction with a negated restriction' do
|
|
@@ -298,7 +388,7 @@ describe 'scoped_search' do
|
|
|
298
388
|
without(:title, 'No')
|
|
299
389
|
end
|
|
300
390
|
end
|
|
301
|
-
search.results.
|
|
391
|
+
expect(search.results).to eq(posts[0..1])
|
|
302
392
|
end
|
|
303
393
|
|
|
304
394
|
it 'should return results that match a conjunction with a disjunction with a conjunction with a negated restriction' do
|
|
@@ -322,7 +412,7 @@ describe 'scoped_search' do
|
|
|
322
412
|
end
|
|
323
413
|
end
|
|
324
414
|
end
|
|
325
|
-
search.results.
|
|
415
|
+
expect(search.results).to eq(posts[0..2])
|
|
326
416
|
end
|
|
327
417
|
|
|
328
418
|
it 'should return results that match a disjunction with a negated restriction and a nested disjunction in a conjunction with a negated restriction' do
|
|
@@ -347,7 +437,7 @@ describe 'scoped_search' do
|
|
|
347
437
|
end
|
|
348
438
|
end
|
|
349
439
|
end
|
|
350
|
-
search.results.
|
|
440
|
+
expect(search.results).to eq(posts[0..2])
|
|
351
441
|
end
|
|
352
442
|
end
|
|
353
443
|
|
|
@@ -367,7 +457,7 @@ describe 'scoped_search' do
|
|
|
367
457
|
order_by :average_rating, :desc
|
|
368
458
|
order_by :sort_title, :asc
|
|
369
459
|
end
|
|
370
|
-
search.results.
|
|
460
|
+
expect(search.results).to eq(@posts)
|
|
371
461
|
end
|
|
372
462
|
end
|
|
373
463
|
|
|
@@ -377,46 +467,75 @@ describe 'scoped_search' do
|
|
|
377
467
|
Sunspot.index!(Array.new(100) { Post.new })
|
|
378
468
|
end
|
|
379
469
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
end
|
|
470
|
+
def search_ordered_by_random(direction = nil)
|
|
471
|
+
Sunspot.search(Post) do
|
|
472
|
+
order_by(:random, direction)
|
|
473
|
+
paginate(:page => 1, :per_page => 100)
|
|
385
474
|
end
|
|
386
|
-
result_sets[0].should_not == result_sets[1]
|
|
387
475
|
end
|
|
388
476
|
|
|
389
|
-
|
|
477
|
+
it 'should order randomly' do
|
|
478
|
+
result_sets = Array.new(5) do
|
|
479
|
+
search_ordered_by_random.results.map { |result| result.id }
|
|
480
|
+
end
|
|
481
|
+
expect(result_sets.uniq.size).to be > 1
|
|
482
|
+
end
|
|
483
|
+
|
|
390
484
|
it 'should order randomly using the order_by function and passing a direction' do
|
|
391
|
-
result_sets = Array.new(
|
|
392
|
-
|
|
393
|
-
result.id
|
|
394
|
-
end
|
|
485
|
+
result_sets = Array.new(5) do
|
|
486
|
+
search_ordered_by_random(:desc).results.map { |result| result.id }
|
|
395
487
|
end
|
|
396
|
-
result_sets
|
|
488
|
+
expect(result_sets.uniq.size).to be > 1
|
|
397
489
|
end
|
|
398
490
|
|
|
399
491
|
context 'when providing a custom seed value' do
|
|
400
492
|
before do
|
|
401
|
-
@first_results =
|
|
402
|
-
order_by(:random, :seed => 12345)
|
|
403
|
-
end.results.map { |result| result.id }
|
|
493
|
+
@first_results = search_ordered_by_random(:seed => 12345).results.map { |result| result.id }
|
|
404
494
|
end
|
|
405
495
|
|
|
406
|
-
# This could fail if the random set returned just happens to be the same as the last random set (the nature of randomness)
|
|
407
496
|
it 'should return different results when passing a different seed value' do
|
|
408
|
-
next_results =
|
|
409
|
-
|
|
410
|
-
end.results.map { |result| result.id }
|
|
411
|
-
next_results.should_not == @first_results
|
|
497
|
+
next_results = search_ordered_by_random(:seed => 54321).results.map { |result| result.id }
|
|
498
|
+
expect(next_results).not_to eq(@first_results)
|
|
412
499
|
end
|
|
413
500
|
|
|
414
501
|
it 'should return the same results when passing the same seed value' do
|
|
415
|
-
next_results =
|
|
416
|
-
|
|
417
|
-
end.results.map { |result| result.id }
|
|
418
|
-
next_results.should == @first_results
|
|
502
|
+
next_results = search_ordered_by_random(:seed => 12345).results.map { |result| result.id }
|
|
503
|
+
expect(next_results).to eq(@first_results)
|
|
419
504
|
end
|
|
420
505
|
end
|
|
421
506
|
end
|
|
507
|
+
|
|
508
|
+
describe 'ordering by function' do
|
|
509
|
+
before :all do
|
|
510
|
+
Sunspot.remove_all
|
|
511
|
+
@p1 = Post.new(:blog_id => 1, :category_ids => [3])
|
|
512
|
+
@p2 = Post.new(:blog_id => 2, :category_ids => [1])
|
|
513
|
+
Sunspot.index([@p1,@p2])
|
|
514
|
+
Sunspot.commit
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
it 'should order by sum' do
|
|
518
|
+
# 1+3 > 2+1
|
|
519
|
+
search = Sunspot.search(Post) {order_by_function :sum, :blog_id, :primary_category_id, :desc}
|
|
520
|
+
expect(search.results.first).to eq(@p1)
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it 'should order by product and sum' do
|
|
524
|
+
# 1 * (1+3) < 2 * (2+1)
|
|
525
|
+
search = Sunspot.search(Post) { order_by_function :product, :blog_id, [:sum,:blog_id,:primary_category_id], :desc}
|
|
526
|
+
expect(search.results.first).to eq(@p2)
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
it 'should accept string literals' do
|
|
530
|
+
# (1 * -2) > (2 * -2)
|
|
531
|
+
search = Sunspot.search(Post) {order_by_function :product, :blog_id, '-2', :desc}
|
|
532
|
+
expect(search.results.first).to eq(@p1)
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
it 'should accept non-string literals' do
|
|
536
|
+
# (1 * -2) > (2 * -2)
|
|
537
|
+
search = Sunspot.search(Post) {order_by_function :product, :blog_id, -2, :desc}
|
|
538
|
+
expect(search.results.first).to eq(@p1)
|
|
539
|
+
end
|
|
540
|
+
end
|
|
422
541
|
end
|