sunspot 2.5.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sunspot/adapters.rb +14 -3
  3. data/lib/sunspot/data_extractor.rb +1 -1
  4. data/lib/sunspot/dsl/fulltext.rb +1 -1
  5. data/lib/sunspot/dsl/standard_query.rb +29 -1
  6. data/lib/sunspot/dsl.rb +2 -2
  7. data/lib/sunspot/field.rb +21 -4
  8. data/lib/sunspot/indexer.rb +37 -8
  9. data/lib/sunspot/query/abstract_fulltext.rb +7 -3
  10. data/lib/sunspot/query/abstract_json_field_facet.rb +3 -0
  11. data/lib/sunspot/query/composite_fulltext.rb +21 -2
  12. data/lib/sunspot/query/date_field_json_facet.rb +2 -16
  13. data/lib/sunspot/query/dismax.rb +10 -4
  14. data/lib/sunspot/query/function_query.rb +25 -1
  15. data/lib/sunspot/query/join.rb +1 -1
  16. data/lib/sunspot/query/range_json_facet.rb +5 -2
  17. data/lib/sunspot/query/restriction.rb +16 -10
  18. data/lib/sunspot/query/standard_query.rb +12 -0
  19. data/lib/sunspot/search/field_json_facet.rb +14 -3
  20. data/lib/sunspot/session.rb +7 -5
  21. data/lib/sunspot/setup.rb +38 -0
  22. data/lib/sunspot/util.rb +24 -21
  23. data/lib/sunspot/version.rb +1 -1
  24. data/lib/sunspot.rb +9 -1
  25. data/spec/api/binding_spec.rb +15 -0
  26. data/spec/api/indexer/attributes_spec.rb +1 -1
  27. data/spec/api/indexer/removal_spec.rb +87 -0
  28. data/spec/api/query/connective_boost_examples.rb +85 -0
  29. data/spec/api/query/geo_examples.rb +1 -1
  30. data/spec/api/query/join_spec.rb +2 -2
  31. data/spec/api/query/standard_spec.rb +10 -0
  32. data/spec/api/query/types_spec.rb +2 -2
  33. data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +1 -1
  34. data/spec/api/session_proxy/retry_5xx_session_proxy_spec.rb +9 -5
  35. data/spec/api/session_spec.rb +1 -1
  36. data/spec/api/setup_spec.rb +99 -0
  37. data/spec/helpers/indexer_helper.rb +22 -0
  38. data/spec/integration/atomic_updates_spec.rb +169 -5
  39. data/spec/integration/faceting_spec.rb +68 -34
  40. data/spec/integration/join_spec.rb +22 -3
  41. data/spec/integration/scoped_search_spec.rb +78 -0
  42. data/spec/mocks/comment.rb +1 -1
  43. data/spec/mocks/connection.rb +6 -0
  44. data/spec/mocks/photo.rb +11 -7
  45. data/spec/mocks/post.rb +35 -1
  46. data/sunspot.gemspec +4 -6
  47. metadata +33 -15
@@ -1,6 +1,79 @@
1
1
  require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
2
 
3
- describe 'atomic updates' do
3
+ shared_examples 'atomic update with instance as key' do
4
+ it 'updates record' do
5
+ post = clazz.new(title: 'A Title', featured: true)
6
+ Sunspot.index!(post)
7
+
8
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
9
+
10
+ Sunspot.atomic_update!(clazz, post => { title: 'A New Title' })
11
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: 'A New Title', featured: true)
12
+
13
+ Sunspot.atomic_update!(clazz, post => { featured: false })
14
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: 'A New Title', featured: false)
15
+ end
16
+
17
+ it 'does not print warning' do
18
+ post = clazz.new(title: 'A Title', featured: true)
19
+ Sunspot.index!(post)
20
+
21
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
22
+
23
+ expect do
24
+ Sunspot.atomic_update!(clazz, post => { title: 'A New Title' })
25
+ end.to_not output(Sunspot::AtomicUpdateRequireInstanceForCompositeIdMessage.call(clazz)).to_stderr
26
+ end
27
+
28
+ it 'does not create duplicate document' do
29
+ post = clazz.new(title: 'A Title', featured: true)
30
+ Sunspot.index!(post)
31
+
32
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
33
+
34
+ Sunspot.atomic_update!(clazz, post => { title: 'A New Title' })
35
+ hit = find_indexed_post_with_prefix_id(post, nil)
36
+ expect(hit).to be_nil
37
+ end
38
+ end
39
+
40
+ shared_examples 'atomic update with id as key' do
41
+ it 'does not update record' do
42
+ post = clazz.new(title: 'A Title', featured: true)
43
+ Sunspot.index!(post)
44
+
45
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
46
+
47
+ Sunspot.atomic_update!(clazz, post.id => { title: 'A New Title' })
48
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: 'A Title', featured: true)
49
+
50
+ Sunspot.atomic_update!(clazz, post.id => { featured: false })
51
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: 'A Title', featured: true)
52
+ end
53
+
54
+ it 'prints warning' do
55
+ post = clazz.new(title: 'A Title', featured: true)
56
+ Sunspot.index!(post)
57
+
58
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
59
+
60
+ expect do
61
+ Sunspot.atomic_update!(clazz, post.id => { title: 'A New Title' })
62
+ end.to output(Sunspot::AtomicUpdateRequireInstanceForCompositeIdMessage.call(clazz) + "\n").to_stderr
63
+ end
64
+
65
+ it 'creates duplicate document that have only fields provided for update' do
66
+ post = clazz.new(title: 'A Title', featured: true)
67
+ Sunspot.index!(post)
68
+
69
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
70
+
71
+ Sunspot.atomic_update!(clazz, post.id => { title: 'A New Title' })
72
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, nil), title: 'A New Title', featured: nil)
73
+ end
74
+ end
75
+
76
+ describe 'Atomic Update feature' do
4
77
  before :all do
5
78
  Sunspot.remove_all
6
79
  end
@@ -18,10 +91,27 @@ describe 'atomic updates' do
18
91
  hit
19
92
  end
20
93
 
21
- it 'should update single record fields one by one' do
94
+ def find_and_validate_indexed_post_with_prefix_id(post, id_prefix)
95
+ hit = find_indexed_post_with_prefix_id(post, id_prefix_value(post, id_prefix))
96
+ expect(hit).not_to be_nil
97
+ hit
98
+ end
99
+
100
+ def find_indexed_post_with_prefix_id(post, id_prefix)
101
+ Sunspot.search(post.class).hits.find { |h| h.primary_key.to_i == post.id && h.id_prefix == id_prefix }
102
+ end
103
+
104
+ def id_prefix_value(post, id_prefix)
105
+ return unless id_prefix
106
+ return id_prefix if id_prefix.is_a?(String)
107
+
108
+ id_prefix.call(post)
109
+ end
110
+
111
+ it 'updates single record fields one by one' do
22
112
  post = Post.new(title: 'A Title', featured: true)
23
113
  Sunspot.index!(post)
24
-
114
+
25
115
  validate_hit(find_indexed_post(post.id), title: post.title, featured: post.featured)
26
116
 
27
117
  Sunspot.atomic_update!(Post, post.id => {title: 'A New Title'})
@@ -31,7 +121,7 @@ describe 'atomic updates' do
31
121
  validate_hit(find_indexed_post(post.id), title: 'A New Title', featured: false)
32
122
  end
33
123
 
34
- it 'should update fields for multiple records' do
124
+ it 'updates fields for multiple records' do
35
125
  post1 = Post.new(title: 'A First Title', featured: true)
36
126
  post2 = Post.new(title: 'A Second Title', featured: false)
37
127
  Sunspot.index!(post1, post2)
@@ -44,7 +134,7 @@ describe 'atomic updates' do
44
134
  validate_hit(find_indexed_post(post2.id), title: 'A Second Title', featured: true)
45
135
  end
46
136
 
47
- it 'should clear field value properly' do
137
+ it 'clears field value properly' do
48
138
  post = Post.new(title: 'A Title', tags: %w(tag1 tag2), featured: true)
49
139
  Sunspot.index!(post)
50
140
  validate_hit(find_indexed_post(post.id), title: post.title, tag_list: post.tags, featured: true)
@@ -55,4 +145,78 @@ describe 'atomic updates' do
55
145
  Sunspot.atomic_update!(Post, post.id => {featured: nil})
56
146
  validate_hit(find_indexed_post(post.id), title: post.title, tag_list: nil, featured: nil)
57
147
  end
148
+
149
+ context 'when `id_prefix` is defined on model' do
150
+ context 'as Proc' do
151
+ let(:clazz) { PostWithProcPrefixId }
152
+ let(:id_prefix) { lambda { |post| "USERDATA-#{post.id}!" } }
153
+
154
+ context 'and instance passed as key' do
155
+ include_examples 'atomic update with instance as key'
156
+ end
157
+
158
+ context 'and id passed as key' do
159
+ include_examples 'atomic update with id as key'
160
+ end
161
+ end
162
+
163
+ context 'as Symbol' do
164
+ let(:clazz) { PostWithSymbolPrefixId }
165
+ let(:id_prefix) { lambda { |post| "#{post.title}!" } }
166
+
167
+ context 'and instance passed as key' do
168
+ include_examples 'atomic update with instance as key'
169
+ end
170
+
171
+ context 'and id passed as key' do
172
+ include_examples 'atomic update with id as key'
173
+ end
174
+ end
175
+
176
+ context 'as String' do
177
+ let(:clazz) { PostWithStringPrefixId }
178
+ let(:id_prefix) { 'USERDATA!' }
179
+
180
+ context 'and instance passed as key' do
181
+ include_examples 'atomic update with instance as key'
182
+ end
183
+
184
+ context 'and id passed as key' do
185
+ it 'updates record' do
186
+ post = clazz.new(title: 'A Title', featured: true)
187
+ Sunspot.index!(post)
188
+
189
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
190
+
191
+ Sunspot.atomic_update!(clazz, post.id => { title: 'A New Title' })
192
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: 'A New Title', featured: true)
193
+
194
+ Sunspot.atomic_update!(clazz, post.id => { featured: false })
195
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: 'A New Title', featured: false)
196
+ end
197
+
198
+ it 'does not print warning' do
199
+ post = clazz.new(title: 'A Title', featured: true)
200
+ Sunspot.index!(post)
201
+
202
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
203
+
204
+ expect do
205
+ Sunspot.atomic_update!(clazz, post.id => { title: 'A New Title' })
206
+ end.to_not output(Sunspot::AtomicUpdateRequireInstanceForCompositeIdMessage.call(clazz) + "\n").to_stderr
207
+ end
208
+
209
+ it 'does not create duplicate document' do
210
+ post = clazz.new(title: 'A Title', featured: true)
211
+ Sunspot.index!(post)
212
+
213
+ validate_hit(find_and_validate_indexed_post_with_prefix_id(post, id_prefix), title: post.title, featured: post.featured)
214
+
215
+ Sunspot.atomic_update!(clazz, post.id => { title: 'A New Title' })
216
+ hit = find_indexed_post_with_prefix_id(post, nil)
217
+ expect(hit).to be_nil
218
+ end
219
+ end
220
+ end
221
+ end
58
222
  end
@@ -84,7 +84,7 @@ describe 'search faceting' do
84
84
  end
85
85
  expect(search.facet(:title).rows.map { |row| row.value }).to include('zero')
86
86
  end
87
-
87
+
88
88
  it 'should return facet rows from an offset' do
89
89
  search = Sunspot.search(Post) do
90
90
  facet :title, :offset => 3
@@ -214,6 +214,15 @@ describe 'search faceting' do
214
214
  expect(search.facet(:title).rows.map { |row| row.value }).to eq(%w(four three two one))
215
215
  end
216
216
 
217
+ it 'should include allBuckets and missing' do
218
+ search = Sunspot.search(Post) do
219
+ with :blog_id, 1
220
+ json_facet :title, all_buckets: true, missing: true
221
+ end
222
+ expect(search.facet(:title).other_count('allBuckets')).to eq(10)
223
+ expect(search.facet(:title).other_count('missing')).to eq(1)
224
+ end
225
+
217
226
  it 'should limit facet values by prefix' do
218
227
  search = Sunspot.search(Post) do
219
228
  with :blog_id, 1
@@ -221,7 +230,64 @@ describe 'search faceting' do
221
230
  end
222
231
  expect(search.facet(:title).rows.map { |row| row.value }.sort).to eq(%w(three two))
223
232
  end
233
+ end
224
234
 
235
+ context 'date or time json facet' do
236
+ before :all do
237
+ Sunspot.remove_all
238
+ posts = [
239
+ Post.new(title: 'dt test', blog_id: 1, published_at: Time.new(2020, 8, 20)),
240
+ Post.new(title: 'dt test', blog_id: 1, published_at: Time.new(2020, 7, 20)),
241
+ Post.new(title: 'dt test', blog_id: 1, published_at: Time.new(2020, 6, 20)),
242
+ Post.new(title: 'dt test', blog_id: 1, published_at: Time.new(2020, 6, 15)),
243
+ Post.new(title: 'dt test', blog_id: 1, published_at: Time.new(2020, 5, 20)),
244
+ Post.new(title: 'dt test', blog_id: 1, published_at: Time.new(2020, 4, 20)),
245
+ Post.new(title: 'dt test', blog_id: 1, published_at: Time.new(2020, 3, 20))
246
+ ]
247
+ posts.each { |p| Sunspot.index(p) }
248
+ Sunspot.commit
249
+ end
250
+
251
+ it 'facets properly with the range specified as time_range' do
252
+ time_range = [Time.new(2020, 4, 1), Time.new(2020, 7, 31)]
253
+ search = Sunspot.search(Post) do
254
+ with :blog_id, 1
255
+ json_facet :published_at, time_range: time_range, gap: 1, gap_unit: 'MONTHS'
256
+ end
257
+ expected_rows = [
258
+ { count: 1, value: Time.new(2020, 4, 1).utc.iso8601 },
259
+ { count: 1, value: Time.new(2020, 5, 1).utc.iso8601 },
260
+ { count: 2, value: Time.new(2020, 6, 1).utc.iso8601 },
261
+ { count: 1, value: Time.new(2020, 7, 1).utc.iso8601 }
262
+ ]
263
+ expect(search.facet(:published_at).rows.map { |row| { count: row.count, value: row.value } }).to eq(expected_rows)
264
+ end
265
+
266
+ it 'should use custom gap parameters if provided' do
267
+ time_range = [Time.new(2020, 4, 1), Time.new(2020, 7, 31)]
268
+ search = Sunspot.search(Post) do
269
+ with :blog_id, 1
270
+ json_facet :published_at, range: time_range, gap: 1, gap_unit: 'MONTHS'
271
+ end
272
+ expected_rows = [
273
+ { count: 1, value: Time.new(2020, 4, 1).utc.iso8601 },
274
+ { count: 1, value: Time.new(2020, 5, 1).utc.iso8601 },
275
+ { count: 2, value: Time.new(2020, 6, 1).utc.iso8601 },
276
+ { count: 1, value: Time.new(2020, 7, 1).utc.iso8601 }
277
+ ]
278
+ expect(search.facet(:published_at).rows.map { |row| { count: row.count, value: row.value } }).to eq(expected_rows)
279
+ end
280
+
281
+ it 'should support computing other statistics' do
282
+ time_range = [Time.new(2020, 5, 1), Time.new(2020, 7, 1)]
283
+ search = Sunspot.search(Post) do
284
+ with :blog_id, 1
285
+ json_facet :published_at, range: time_range, gap: 1, gap_unit: 'MONTHS', other: 'all'
286
+ end
287
+ expect(search.facet(:published_at).other_count('before')).to eq(2)
288
+ expect(search.facet(:published_at).other_count('after')).to eq(2)
289
+ expect(search.facet(:published_at).other_count('between')).to eq(3)
290
+ end
225
291
  end
226
292
 
227
293
  context 'nested json facet' do
@@ -237,7 +303,7 @@ describe 'search faceting' do
237
303
  end
238
304
 
239
305
  0.upto(9) { |i| Sunspot.index(Post.new(:title => 'zero', :author_name => "another#{i}", :blog_id => 1)) }
240
-
306
+
241
307
  Sunspot.commit
242
308
  end
243
309
 
@@ -459,38 +525,6 @@ describe 'search faceting' do
459
525
  expect(search.facet(:published_at).rows.last.value).to eq((time + 60*60*24)..(time + 60*60*24*2))
460
526
  expect(search.facet(:published_at).rows.last.count).to eq(1)
461
527
  end
462
-
463
- it 'json facet should return time ranges' do
464
- days_diff = 15
465
- time_from = Time.utc(2009, 7, 8)
466
- time_to = Time.utc(2009, 7, 8 + days_diff)
467
- search = Sunspot.search(Post) do
468
- json_facet(
469
- :published_at,
470
- :time_range => time_from..time_to
471
- )
472
- end
473
-
474
- expect(search.facet(:published_at).rows.size).to eq(days_diff)
475
- expect(search.facet(:published_at).rows[0].count).to eq(2)
476
- expect(search.facet(:published_at).rows[1].count).to eq(1)
477
- end
478
-
479
- it 'json facet should return time ranges with custom gap' do
480
- days_diff = 10
481
- time_from = Time.utc(2009, 7, 8)
482
- time_to = Time.utc(2009, 7, 8 + days_diff)
483
- search = Sunspot.search(Post) do
484
- json_facet(
485
- :published_at,
486
- :time_range => time_from..time_to,
487
- gap: 60*60*24*2
488
- )
489
- end
490
- expect(search.facet(:published_at).rows.size).to eq(days_diff / 2)
491
- expect(search.facet(:published_at).rows[0].count).to eq(3)
492
- end
493
-
494
528
  end
495
529
 
496
530
  context 'class facets' do
@@ -8,9 +8,9 @@ describe "searching by joined fields" do
8
8
  @container2 = PhotoContainer.new(:id => 2).tap { |c| allow(c).to receive(:id).and_return(2) }
9
9
  @container3 = PhotoContainer.new(:id => 3).tap { |c| allow(c).to receive(:id).and_return(3) }
10
10
 
11
- @picture = Picture.new(:photo_container_id => @container1.id, :description => "one")
12
- @photo1 = Photo.new(:photo_container_id => @container1.id, :description => "two")
13
- @photo2 = Photo.new(:photo_container_id => @container2.id, :description => "three")
11
+ @picture = Picture.new(:photo_container_id => @container1.id, :description => "one", :published => true)
12
+ @photo1 = Photo.new(:photo_container_id => @container1.id, :description => "two", :published => true)
13
+ @photo2 = Photo.new(:photo_container_id => @container2.id, :description => "three", :published => false)
14
14
 
15
15
  Sunspot.index!(@container1, @container2, @photo1, @photo2, @picture)
16
16
  end
@@ -42,4 +42,23 @@ describe "searching by joined fields" do
42
42
  expect(results).to eq res
43
43
  end
44
44
  end
45
+
46
+ it "matches by joined fields when using filter queries" do
47
+ {
48
+ :photo_published => [
49
+ [true, [@container1]],
50
+ [false, [@container2]]
51
+ ],
52
+ :picture_published => [
53
+ [true, [@container1]],
54
+ [false, []]
55
+ ]
56
+ }.each do |key, data|
57
+ data.each do |(value, res)|
58
+ results = Sunspot.search(PhotoContainer) { with(key, value) }.results
59
+
60
+ expect(results).to eq res
61
+ end
62
+ end
63
+ end
45
64
  end
@@ -538,4 +538,82 @@ describe 'scoped_search' do
538
538
  expect(search.results.first).to eq(@p1)
539
539
  end
540
540
  end
541
+
542
+ describe 'boosting' do
543
+ before :all do
544
+ Sunspot.remove_all
545
+ @p1 = Post.new(:title => 'Post', :body => 'Lorem', :blog_id => 1, :category_ids => [3], :ratings_average => 30)
546
+ @p2 = Post.new(:title => 'Post', :body => 'Ipsum', :blog_id => 2, :category_ids => [2], :ratings_average => 60)
547
+ @p3 = Post.new(:title => 'Post', :body => 'Dolor', :blog_id => 3, :category_ids => [1], :ratings_average => 90)
548
+ Sunspot.index([@p1, @p2, @p3])
549
+ Sunspot.commit
550
+ end
551
+
552
+ it 'without boost should returns post in default order' do
553
+ search = Sunspot.search(Post) {}
554
+
555
+ expect(search.results[0]).to eq(@p1)
556
+ expect(search.results[1]).to eq(@p2)
557
+ expect(search.results[2]).to eq(@p3)
558
+ end
559
+
560
+ it 'should apply boost function' do
561
+ search = Sunspot.search(Post) do
562
+ boost(function() { field(:average_rating) })
563
+ end
564
+
565
+ expect(search.results[0]).to eq(@p3)
566
+ expect(search.results[1]).to eq(@p2)
567
+ expect(search.results[2]).to eq(@p1)
568
+ end
569
+
570
+ it 'should apply multilicative boost function' do
571
+ search = Sunspot.search(Post) do
572
+ boost_multiplicative(function() { field(:average_rating) })
573
+ end
574
+
575
+ expect(search.results[0]).to eq(@p3)
576
+ expect(search.results[1]).to eq(@p2)
577
+ expect(search.results[2]).to eq(@p1)
578
+ end
579
+
580
+ it 'should apply boost query' do
581
+ search = Sunspot.search(Post) do
582
+ boost(5) do
583
+ with(:blog_id, 1)
584
+ end
585
+
586
+ boost(10) do
587
+ with(:blog_id, 3)
588
+ end
589
+ end
590
+
591
+ expect(search.results[0]).to eq(@p3)
592
+ expect(search.results[1]).to eq(@p1)
593
+ expect(search.results[2]).to eq(@p2)
594
+ end
595
+
596
+ it 'should work properly when combined with fulltext' do
597
+ search = Sunspot.search(Post) do
598
+ fulltext('Post Ipsum') do
599
+ boost_fields :body => 0.2
600
+ minimum_match 1
601
+ end
602
+
603
+ boost(0.9) do
604
+ with(:blog_id, 1)
605
+ end
606
+
607
+ boost(function() { div(field(:average_rating), 100) })
608
+
609
+ fulltext('Post') do
610
+ minimum_match 1
611
+ end
612
+ end
613
+
614
+ expect(search.results[0]).to eq(@p2)
615
+ expect(search.results[1]).to eq(@p3)
616
+ expect(search.results[2]).to eq(@p1)
617
+ end
618
+ end
541
619
  end
@@ -17,5 +17,5 @@ Sunspot.setup(Namespaced::Comment) do
17
17
  long :hash
18
18
  double :average_rating
19
19
  dynamic_float :custom_float, :multiple => true
20
- boost :boost
20
+ boost(:boost)
21
21
  end
@@ -92,6 +92,12 @@ module Mock
92
92
  end
93
93
  end
94
94
 
95
+ def has_no_delete?(*ids)
96
+ @deletes.none? do |delete|
97
+ delete & ids == ids
98
+ end
99
+ end
100
+
95
101
  def has_delete_by_query?(query)
96
102
  @deletes_by_query.include?(query)
97
103
  end
data/spec/mocks/photo.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Photo < MockRecord
2
- attr_accessor :caption, :description, :lat, :lng, :size, :average_rating, :created_at, :post_id, :photo_container_id
2
+ attr_accessor :caption, :description, :lat, :lng, :size, :average_rating, :created_at, :post_id, :photo_container_id, :published
3
3
  end
4
4
 
5
5
  Sunspot.setup(Photo) do
@@ -7,6 +7,7 @@ Sunspot.setup(Photo) do
7
7
  text :description
8
8
  string :caption
9
9
  integer :photo_container_id
10
+ boolean :published
10
11
  boost 0.75
11
12
  integer :size, :trie => true
12
13
  float :average_rating, :trie => true
@@ -14,12 +15,13 @@ Sunspot.setup(Photo) do
14
15
  end
15
16
 
16
17
  class Picture < MockRecord
17
- attr_accessor :description, :photo_container_id
18
+ attr_accessor :description, :photo_container_id, :published
18
19
  end
19
20
 
20
21
  Sunspot.setup(Picture) do
21
22
  text :description
22
23
  integer :photo_container_id
24
+ boolean :published
23
25
  end
24
26
 
25
27
  class PhotoContainer < MockRecord
@@ -34,9 +36,11 @@ Sunspot.setup(PhotoContainer) do
34
36
  integer :id
35
37
  text :description, :default_boost => 1.2
36
38
 
37
- join(:caption, :target => Photo, :type => :string, :join => { :from => :photo_container_id, :to => :id })
38
- join(:photo_rating, :target => Photo, :type => :trie_float, :join => { :from => :photo_container_id, :to => :id }, :as => 'average_rating_ft')
39
- join(:caption, :target => Photo, :type => :text, :join => { :from => :photo_container_id, :to => :id })
40
- join(:description, :target => Photo, :type => :text, :join => { :from => :photo_container_id, :to => :id }, :prefix => "photo")
41
- join(:description, :target => Picture, :type => :text, :join => { :from => :photo_container_id, :to => :id }, :prefix => "picture")
39
+ join(:caption, :target => 'Photo', :type => :string, :join => { :from => :photo_container_id, :to => :id })
40
+ join(:photo_rating, :target => 'Photo', :type => :trie_float, :join => { :from => :photo_container_id, :to => :id }, :as => 'average_rating_ft')
41
+ join(:caption, :target => 'Photo', :type => :text, :join => { :from => :photo_container_id, :to => :id })
42
+ join(:description, :target => 'Photo', :type => :text, :join => { :from => :photo_container_id, :to => :id }, :prefix => "photo")
43
+ join(:published, :target => 'Photo', :type => :boolean, :join => { :from => :photo_container_id, :to => :id }, :prefix => "photo")
44
+ join(:description, :target => 'Picture', :type => :text, :join => { :from => :photo_container_id, :to => :id }, :prefix => "picture")
45
+ join(:published, :target => 'Picture', :type => :boolean, :join => { :from => :photo_container_id, :to => :id }, :prefix => "picture")
42
46
  end
data/spec/mocks/post.rb CHANGED
@@ -37,7 +37,7 @@ end
37
37
 
38
38
  Sunspot.setup(Post) do
39
39
  text :title, :boost => 2
40
- text :text_array, :boost => 3 do
40
+ text :text_array do
41
41
  [title, title]
42
42
  end
43
43
  text :body, :stored => true, :more_like_this => true
@@ -99,3 +99,37 @@ end
99
99
  class PhotoPost < Post
100
100
  end
101
101
 
102
+ class PostWithProcPrefixId < Post
103
+ end
104
+
105
+ Sunspot.setup(PostWithProcPrefixId) do
106
+ id_prefix { "USERDATA-#{id}!" }
107
+ string :title, :stored => true
108
+ boolean :featured, :using => :featured?, :stored => true
109
+ end
110
+
111
+ class PostWithSymbolPrefixId < Post
112
+ end
113
+
114
+ Sunspot.setup(PostWithSymbolPrefixId) do
115
+ id_prefix :title
116
+ string :title, :stored => true
117
+ boolean :featured, :using => :featured?, :stored => true
118
+ end
119
+
120
+ class PostWithStringPrefixId < Post
121
+ end
122
+
123
+ Sunspot.setup(PostWithStringPrefixId) do
124
+ id_prefix 'USERDATA!'
125
+ string :title, :stored => true
126
+ boolean :featured, :using => :featured?, :stored => true
127
+ end
128
+
129
+ class PostWithoutPrefixId < Post
130
+ end
131
+
132
+ Sunspot.setup(PostWithoutPrefixId) do
133
+ string :title, :stored => true
134
+ boolean :featured, :using => :featured?, :stored => true
135
+ end
data/sunspot.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  'Dylan Vaughn', 'Brian Durand', 'Sam Granieri', 'Nick Zadrozny', 'Jason Ronallo', 'Ryan Wallace', 'Nicholas Jakobsen',
12
12
  'Bragadeesh J', 'Ethiraj Srinivasan']
13
13
  s.email = ["mat@patch.com"]
14
- s.homepage = "http://outoftime.github.com/sunspot"
14
+ s.homepage = "https://sunspot.github.io"
15
15
  s.summary = 'Library for expressive, powerful interaction with the Solr search engine'
16
16
  s.license = 'MIT'
17
17
  s.description = <<-TEXT
@@ -20,8 +20,6 @@ Gem::Specification.new do |s|
20
20
  can be performed without hand-writing any boolean queries or building Solr parameters by hand.
21
21
  TEXT
22
22
 
23
- s.rubyforge_project = "sunspot"
24
-
25
23
  s.files = `git ls-files`.split("\n")
26
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
25
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -29,10 +27,10 @@ Gem::Specification.new do |s|
29
27
 
30
28
  s.add_dependency 'rsolr', '>= 1.1.1', '< 3'
31
29
  s.add_dependency 'pr_geohash', '~>1.0'
32
-
33
- s.add_development_dependency 'rake', '< 12.3'
30
+ s.add_dependency 'bigdecimal'
31
+ s.add_development_dependency 'rake', '~> 13.2'
34
32
  s.add_development_dependency 'rspec', '~> 3.7'
35
- s.add_development_dependency 'appraisal', '2.2.0'
33
+ s.add_development_dependency 'appraisal', '~> 2.5'
36
34
 
37
35
  s.rdoc_options << '--webcvs=http://github.com/outoftime/sunspot/tree/master/%s' <<
38
36
  '--title' << 'Sunspot - Solr-powered search for Ruby objects - API Documentation' <<