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.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -0
  4. data/Appraisals +7 -0
  5. data/Gemfile +0 -2
  6. data/History.txt +10 -0
  7. data/lib/sunspot.rb +55 -17
  8. data/lib/sunspot/adapters.rb +68 -18
  9. data/lib/sunspot/batcher.rb +1 -1
  10. data/lib/sunspot/configuration.rb +4 -2
  11. data/lib/sunspot/data_extractor.rb +36 -6
  12. data/lib/sunspot/dsl.rb +4 -3
  13. data/lib/sunspot/dsl/adjustable.rb +2 -2
  14. data/lib/sunspot/dsl/field_query.rb +69 -16
  15. data/lib/sunspot/dsl/field_stats.rb +25 -0
  16. data/lib/sunspot/dsl/fields.rb +28 -8
  17. data/lib/sunspot/dsl/fulltext.rb +9 -1
  18. data/lib/sunspot/dsl/group.rb +118 -0
  19. data/lib/sunspot/dsl/paginatable.rb +4 -1
  20. data/lib/sunspot/dsl/scope.rb +19 -10
  21. data/lib/sunspot/dsl/search.rb +1 -1
  22. data/lib/sunspot/dsl/spellcheckable.rb +14 -0
  23. data/lib/sunspot/dsl/standard_query.rb +63 -35
  24. data/lib/sunspot/field.rb +76 -4
  25. data/lib/sunspot/field_factory.rb +60 -11
  26. data/lib/sunspot/indexer.rb +70 -18
  27. data/lib/sunspot/query.rb +5 -4
  28. data/lib/sunspot/query/abstract_field_facet.rb +0 -2
  29. data/lib/sunspot/query/abstract_fulltext.rb +76 -0
  30. data/lib/sunspot/query/abstract_json_field_facet.rb +70 -0
  31. data/lib/sunspot/query/bbox.rb +5 -1
  32. data/lib/sunspot/query/common_query.rb +31 -6
  33. data/lib/sunspot/query/composite_fulltext.rb +58 -8
  34. data/lib/sunspot/query/date_field_json_facet.rb +25 -0
  35. data/lib/sunspot/query/dismax.rb +25 -71
  36. data/lib/sunspot/query/field_json_facet.rb +19 -0
  37. data/lib/sunspot/query/field_list.rb +15 -0
  38. data/lib/sunspot/query/field_stats.rb +61 -0
  39. data/lib/sunspot/query/function_query.rb +1 -2
  40. data/lib/sunspot/query/geo.rb +1 -1
  41. data/lib/sunspot/query/geofilt.rb +8 -3
  42. data/lib/sunspot/query/group.rb +46 -0
  43. data/lib/sunspot/query/group_query.rb +17 -0
  44. data/lib/sunspot/query/join.rb +88 -0
  45. data/lib/sunspot/query/more_like_this.rb +1 -1
  46. data/lib/sunspot/query/pagination.rb +12 -4
  47. data/lib/sunspot/query/range_json_facet.rb +28 -0
  48. data/lib/sunspot/query/restriction.rb +99 -13
  49. data/lib/sunspot/query/sort.rb +41 -0
  50. data/lib/sunspot/query/sort_composite.rb +7 -0
  51. data/lib/sunspot/query/spellcheck.rb +19 -0
  52. data/lib/sunspot/query/standard_query.rb +24 -2
  53. data/lib/sunspot/query/text_field_boost.rb +1 -3
  54. data/lib/sunspot/schema.rb +12 -3
  55. data/lib/sunspot/search.rb +4 -2
  56. data/lib/sunspot/search/abstract_search.rb +93 -43
  57. data/lib/sunspot/search/cursor_paginated_collection.rb +32 -0
  58. data/lib/sunspot/search/field_facet.rb +4 -4
  59. data/lib/sunspot/search/field_json_facet.rb +33 -0
  60. data/lib/sunspot/search/field_stats.rb +21 -0
  61. data/lib/sunspot/search/hit.rb +6 -1
  62. data/lib/sunspot/search/hit_enumerable.rb +4 -1
  63. data/lib/sunspot/search/json_facet_row.rb +40 -0
  64. data/lib/sunspot/search/json_facet_stats.rb +23 -0
  65. data/lib/sunspot/search/paginated_collection.rb +1 -0
  66. data/lib/sunspot/search/query_group.rb +74 -0
  67. data/lib/sunspot/search/standard_search.rb +70 -3
  68. data/lib/sunspot/search/stats_facet.rb +25 -0
  69. data/lib/sunspot/search/stats_json_row.rb +82 -0
  70. data/lib/sunspot/search/stats_row.rb +68 -0
  71. data/lib/sunspot/session.rb +62 -37
  72. data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +6 -4
  73. data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +16 -8
  74. data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +2 -2
  75. data/lib/sunspot/session_proxy/retry_5xx_session_proxy.rb +1 -1
  76. data/lib/sunspot/session_proxy/sharding_session_proxy.rb +4 -2
  77. data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +1 -1
  78. data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +6 -4
  79. data/lib/sunspot/setup.rb +42 -0
  80. data/lib/sunspot/type.rb +20 -0
  81. data/lib/sunspot/util.rb +78 -14
  82. data/lib/sunspot/version.rb +1 -1
  83. data/spec/api/adapters_spec.rb +40 -15
  84. data/spec/api/batcher_spec.rb +15 -15
  85. data/spec/api/binding_spec.rb +3 -3
  86. data/spec/api/class_set_spec.rb +6 -6
  87. data/spec/api/data_extractor_spec.rb +39 -0
  88. data/spec/api/hit_enumerable_spec.rb +32 -9
  89. data/spec/api/indexer/attributes_spec.rb +35 -30
  90. data/spec/api/indexer/batch_spec.rb +8 -7
  91. data/spec/api/indexer/dynamic_fields_spec.rb +8 -8
  92. data/spec/api/indexer/fixed_fields_spec.rb +16 -11
  93. data/spec/api/indexer/fulltext_spec.rb +8 -8
  94. data/spec/api/indexer/removal_spec.rb +24 -14
  95. data/spec/api/indexer_spec.rb +2 -2
  96. data/spec/api/query/advanced_manipulation_examples.rb +3 -3
  97. data/spec/api/query/connectives_examples.rb +26 -14
  98. data/spec/api/query/dsl_spec.rb +24 -6
  99. data/spec/api/query/dynamic_fields_examples.rb +18 -18
  100. data/spec/api/query/faceting_examples.rb +80 -61
  101. data/spec/api/query/fulltext_examples.rb +194 -40
  102. data/spec/api/query/function_spec.rb +116 -13
  103. data/spec/api/query/geo_examples.rb +8 -12
  104. data/spec/api/query/group_spec.rb +27 -5
  105. data/spec/api/query/highlighting_examples.rb +26 -26
  106. data/spec/api/query/join_spec.rb +19 -0
  107. data/spec/api/query/more_like_this_spec.rb +40 -27
  108. data/spec/api/query/ordering_pagination_examples.rb +37 -23
  109. data/spec/api/query/scope_examples.rb +39 -39
  110. data/spec/api/query/spatial_examples.rb +3 -3
  111. data/spec/api/query/spellcheck_examples.rb +20 -0
  112. data/spec/api/query/standard_spec.rb +3 -1
  113. data/spec/api/query/stats_examples.rb +66 -0
  114. data/spec/api/query/text_field_scoping_examples.rb +5 -5
  115. data/spec/api/query/types_spec.rb +4 -4
  116. data/spec/api/search/cursor_paginated_collection_spec.rb +35 -0
  117. data/spec/api/search/dynamic_fields_spec.rb +4 -4
  118. data/spec/api/search/faceting_spec.rb +55 -52
  119. data/spec/api/search/highlighting_spec.rb +7 -7
  120. data/spec/api/search/hits_spec.rb +43 -29
  121. data/spec/api/search/paginated_collection_spec.rb +19 -18
  122. data/spec/api/search/results_spec.rb +13 -13
  123. data/spec/api/search/search_spec.rb +3 -3
  124. data/spec/api/search/stats_spec.rb +94 -0
  125. data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +23 -16
  126. data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +16 -4
  127. data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +10 -6
  128. data/spec/api/session_proxy/retry_5xx_session_proxy_spec.rb +11 -11
  129. data/spec/api/session_proxy/sharding_session_proxy_spec.rb +15 -14
  130. data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +3 -3
  131. data/spec/api/session_proxy/spec_helper.rb +1 -1
  132. data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +40 -26
  133. data/spec/api/session_spec.rb +78 -38
  134. data/spec/api/sunspot_spec.rb +7 -4
  135. data/spec/helpers/integration_helper.rb +11 -1
  136. data/spec/helpers/query_helper.rb +1 -1
  137. data/spec/helpers/search_helper.rb +30 -0
  138. data/spec/integration/atomic_updates_spec.rb +58 -0
  139. data/spec/integration/dynamic_fields_spec.rb +31 -20
  140. data/spec/integration/faceting_spec.rb +252 -39
  141. data/spec/integration/field_grouping_spec.rb +47 -15
  142. data/spec/integration/field_lists_spec.rb +57 -0
  143. data/spec/integration/geospatial_spec.rb +34 -8
  144. data/spec/integration/highlighting_spec.rb +8 -8
  145. data/spec/integration/indexing_spec.rb +7 -6
  146. data/spec/integration/join_spec.rb +45 -0
  147. data/spec/integration/keyword_search_spec.rb +68 -38
  148. data/spec/integration/local_search_spec.rb +4 -4
  149. data/spec/integration/more_like_this_spec.rb +7 -7
  150. data/spec/integration/scoped_search_spec.rb +193 -74
  151. data/spec/integration/spellcheck_spec.rb +119 -0
  152. data/spec/integration/stats_spec.rb +88 -0
  153. data/spec/integration/stored_fields_spec.rb +1 -1
  154. data/spec/integration/test_pagination.rb +4 -4
  155. data/spec/integration/unicode_spec.rb +1 -1
  156. data/spec/mocks/adapters.rb +36 -0
  157. data/spec/mocks/connection.rb +5 -3
  158. data/spec/mocks/photo.rb +32 -1
  159. data/spec/mocks/post.rb +18 -3
  160. data/spec/spec_helper.rb +13 -8
  161. data/sunspot.gemspec +6 -4
  162. data/tasks/rdoc.rake +22 -14
  163. metadata +101 -44
  164. data/lib/sunspot/dsl/field_group.rb +0 -57
  165. data/lib/sunspot/query/field_group.rb +0 -37
@@ -0,0 +1,68 @@
1
+ module Sunspot
2
+ module Search
3
+ class StatsRow
4
+ attr_reader :data, :value
5
+ attr_writer :instance #:nodoc:
6
+
7
+ def initialize(data, facet = nil, value = nil) #:nodoc:
8
+ @data, @facet, @value = data, facet, value
9
+ @facet_fields = []
10
+ end
11
+
12
+ def min
13
+ data['min']
14
+ end
15
+
16
+ def max
17
+ data['max']
18
+ end
19
+
20
+ def count
21
+ data['count']
22
+ end
23
+
24
+ def sum
25
+ data['sum']
26
+ end
27
+
28
+ def missing
29
+ data['missing']
30
+ end
31
+
32
+ def sum_of_squares
33
+ data['sumOfSquares']
34
+ end
35
+
36
+ def mean
37
+ data['mean']
38
+ end
39
+
40
+ def standard_deviation
41
+ data['stddev']
42
+ end
43
+
44
+ def facet name
45
+ facets.find { |facet| facet.field.name == name.to_sym }
46
+ end
47
+
48
+ def facets
49
+ @facets ||= @facet_fields.map do |field|
50
+ StatsFacet.new(field, data['facets'][field.indexed_name])
51
+ end
52
+ end
53
+
54
+ def instance
55
+ if !defined?(@instance)
56
+ @facet.populate_instances
57
+ end
58
+ @instance
59
+ end
60
+
61
+ def inspect
62
+ "<Sunspot::Search::StatsRow:#{value.inspect} min=#{min} max=#{max}"\
63
+ " count=#{self.count} sum=#{sum} missing=#{missing} sum_of_squares=#{sum_of_squares}"\
64
+ " mean=#{mean} standard_deviation=#{standard_deviation}>"
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,5 +1,5 @@
1
1
  module Sunspot
2
- #
2
+ #
3
3
  # A Sunspot session encapsulates a connection to Solr and a set of
4
4
  # configuration choices. Though users of Sunspot may manually instantiate
5
5
  # Session objects, in the general case it's easier to use the singleton
@@ -10,8 +10,8 @@ module Sunspot
10
10
  class Session
11
11
  class <<self
12
12
  attr_writer :connection_class #:nodoc:
13
-
14
- #
13
+
14
+ #
15
15
  # For testing purposes
16
16
  #
17
17
  def connection_class #:nodoc:
@@ -19,12 +19,12 @@ module Sunspot
19
19
  end
20
20
  end
21
21
 
22
- #
22
+ #
23
23
  # Sunspot::Configuration object for this session
24
24
  #
25
25
  attr_reader :config
26
26
 
27
- #
27
+ #
28
28
  # Sessions are initialized with a Sunspot configuration and a Solr
29
29
  # connection. Usually you will want to stick with the default arguments
30
30
  # when instantiating your own sessions.
@@ -36,7 +36,7 @@ module Sunspot
36
36
  @deletes = @adds = 0
37
37
  end
38
38
 
39
- #
39
+ #
40
40
  # See Sunspot.new_search
41
41
  #
42
42
  def new_search(*types, &block)
@@ -59,7 +59,7 @@ module Sunspot
59
59
  search.execute
60
60
  end
61
61
 
62
- #
62
+ #
63
63
  # See Sunspot.new_more_like_this
64
64
  #
65
65
  def new_more_like_this(object, *types, &block)
@@ -91,7 +91,7 @@ module Sunspot
91
91
  indexer.add(objects)
92
92
  end
93
93
 
94
- #
94
+ #
95
95
  # See Sunspot.index!
96
96
  #
97
97
  def index!(*objects)
@@ -99,12 +99,28 @@ module Sunspot
99
99
  commit
100
100
  end
101
101
 
102
+ #
103
+ # See Sunspot.atomic_update
104
+ #
105
+ def atomic_update(clazz, updates = {})
106
+ @adds += updates.keys.length
107
+ indexer.add_atomic_update(clazz, updates)
108
+ end
109
+
110
+ #
111
+ # See Sunspot.atomic_update!
112
+ #
113
+ def atomic_update!(clazz, updates = {})
114
+ atomic_update(clazz, updates)
115
+ commit
116
+ end
117
+
102
118
  #
103
119
  # See Sunspot.commit
104
120
  #
105
- def commit
121
+ def commit(soft_commit = false)
106
122
  @adds = @deletes = 0
107
- connection.commit
123
+ connection.commit :commit_attributes => {:softCommit => soft_commit}
108
124
  end
109
125
 
110
126
  #
@@ -115,7 +131,7 @@ module Sunspot
115
131
  connection.optimize
116
132
  end
117
133
 
118
- #
134
+ #
119
135
  # See Sunspot.remove
120
136
  #
121
137
  def remove(*objects, &block)
@@ -139,32 +155,32 @@ module Sunspot
139
155
  end
140
156
  end
141
157
 
142
- #
158
+ #
143
159
  # See Sunspot.remove!
144
160
  #
145
- def remove!(*objects)
146
- remove(*objects)
161
+ def remove!(*objects, &block)
162
+ remove(*objects, &block)
147
163
  commit
148
164
  end
149
165
 
150
- #
166
+ #
151
167
  # See Sunspot.remove_by_id
152
168
  #
153
- def remove_by_id(clazz, id)
169
+ def remove_by_id(clazz, *ids)
154
170
  class_name =
155
171
  if clazz.is_a?(Class)
156
172
  clazz.name
157
173
  else
158
174
  clazz.to_s
159
175
  end
160
- indexer.remove_by_id(class_name, id)
176
+ indexer.remove_by_id(class_name, ids)
161
177
  end
162
178
 
163
- #
179
+ #
164
180
  # See Sunspot.remove_by_id!
165
181
  #
166
- def remove_by_id!(clazz, id)
167
- remove_by_id(clazz, id)
182
+ def remove_by_id!(clazz, *ids)
183
+ remove_by_id(clazz, ids)
168
184
  commit
169
185
  end
170
186
 
@@ -182,7 +198,7 @@ module Sunspot
182
198
  end
183
199
  end
184
200
 
185
- #
201
+ #
186
202
  # See Sunspot.remove_all!
187
203
  #
188
204
  def remove_all!(*classes)
@@ -190,35 +206,35 @@ module Sunspot
190
206
  commit
191
207
  end
192
208
 
193
- #
209
+ #
194
210
  # See Sunspot.dirty?
195
211
  #
196
212
  def dirty?
197
213
  (@deletes + @adds) > 0
198
214
  end
199
215
 
200
- #
216
+ #
201
217
  # See Sunspot.commit_if_dirty
202
218
  #
203
- def commit_if_dirty
204
- commit if dirty?
219
+ def commit_if_dirty(soft_commit = false)
220
+ commit soft_commit if dirty?
205
221
  end
206
-
207
- #
222
+
223
+ #
208
224
  # See Sunspot.delete_dirty?
209
225
  #
210
226
  def delete_dirty?
211
227
  @deletes > 0
212
228
  end
213
229
 
214
- #
230
+ #
215
231
  # See Sunspot.commit_if_delete_dirty
216
232
  #
217
- def commit_if_delete_dirty
218
- commit if delete_dirty?
233
+ def commit_if_delete_dirty(soft_commit = false)
234
+ commit soft_commit if delete_dirty?
219
235
  end
220
-
221
- #
236
+
237
+ #
222
238
  # See Sunspot.batch
223
239
  #
224
240
  def batch
@@ -229,7 +245,7 @@ module Sunspot
229
245
 
230
246
  private
231
247
 
232
- #
248
+ #
233
249
  # Retrieve the Solr connection for this session, creating one if it does not
234
250
  # already exist.
235
251
  #
@@ -238,10 +254,13 @@ module Sunspot
238
254
  # RSolr::Connection::Base:: The connection for this session
239
255
  #
240
256
  def connection
241
- @connection ||=
242
- self.class.connection_class.connect(:url => config.solr.url,
243
- :read_timeout => config.solr.read_timeout,
244
- :open_timeout => config.solr.open_timeout)
257
+ @connection ||= self.class.connection_class.connect(
258
+ url: config.solr.url,
259
+ read_timeout: config.solr.read_timeout,
260
+ open_timeout: config.solr.open_timeout,
261
+ proxy: config.solr.proxy,
262
+ update_format: update_format_generator
263
+ )
245
264
  end
246
265
 
247
266
  def indexer
@@ -258,5 +277,11 @@ module Sunspot
258
277
  CompositeSetup.for(types)
259
278
  end
260
279
  end
280
+
281
+ def update_format_generator
282
+ if config.solr.update_format && RSolr.version.to_i > 1
283
+ config.solr.update_format.downcase.to_sym == :json ? RSolr::JSON::Generator : RSolr::Xml::Generator
284
+ end
285
+ end
261
286
  end
262
287
  end
@@ -23,15 +23,17 @@ module Sunspot
23
23
  #
24
24
  # See Sunspot.remove_by_id
25
25
  #
26
- def remove_by_id(clazz, id)
27
- session_for_class(clazz).remove_by_id(clazz, id)
26
+ def remove_by_id(clazz, *ids)
27
+ ids.flatten!
28
+ session_for_class(clazz).remove_by_id(clazz, ids)
28
29
  end
29
30
 
30
31
  #
31
32
  # See Sunspot.remove_by_id!
32
33
  #
33
- def remove_by_id!(clazz, id)
34
- session_for_class(clazz).remove_by_id!(clazz, id)
34
+ def remove_by_id!(clazz, *ids)
35
+ ids.flatten!
36
+ session_for_class(clazz).remove_by_id!(clazz, ids)
35
37
  end
36
38
 
37
39
  #
@@ -45,23 +45,31 @@ module Sunspot
45
45
  #
46
46
  # See Sunspot.remove_by_id
47
47
  #
48
- def remove_by_id(clazz, id)
49
- session_for_index_id(
50
- Adapters::InstanceAdapter.index_id_for(clazz, id)
51
- ).remove_by_id(clazz, id)
48
+ def remove_by_id(clazz, *ids)
49
+ ids.flatten!
50
+ ids_by_session(clazz, ids).each do |session, ids|
51
+ session.remove_by_id(clazz, ids)
52
+ end
52
53
  end
53
54
 
54
55
  #
55
56
  # See Sunspot.remove_by_id!
56
57
  #
57
- def remove_by_id!(clazz, id)
58
- session_for_index_id(
59
- Adapters::InstanceAdapter.index_id_for(clazz, id)
60
- ).remove_by_id!(clazz, id)
58
+ def remove_by_id!(clazz, *ids)
59
+ ids.flatten!
60
+ ids_by_session(clazz, ids).each do |session, ids|
61
+ session.remove_by_id!(clazz, ids)
62
+ end
61
63
  end
62
64
 
63
65
  private
64
66
 
67
+ def ids_by_session(clazz, ids)
68
+ ids.group_by do |id|
69
+ session_for_index_id(Adapters::InstanceAdapter.index_id_for(clazz, id))
70
+ end
71
+ end
72
+
65
73
  def session_for_index_id(index_id)
66
74
  @sessions[id_hash(index_id) % @sessions.length]
67
75
  end
@@ -19,8 +19,8 @@ module Sunspot
19
19
 
20
20
  delegate :batch, :commit, :commit_if_delete_dirty, :commit_if_dirty,
21
21
  :config, :delete_dirty?, :dirty?, :index, :index!, :optimize, :remove,
22
- :remove!, :remove_all, :remove_all!, :remove_by_id,
23
- :remove_by_id!, :to => :master_session
22
+ :remove!, :remove_all, :remove_all!, :remove_by_id, :remove_by_id!,
23
+ :atomic_update, :atomic_update!, :to => :master_session
24
24
  delegate :new_search, :search, :new_more_like_this, :more_like_this, :to => :slave_session
25
25
 
26
26
  def initialize(master_session, slave_session)
@@ -59,7 +59,7 @@ module Sunspot
59
59
 
60
60
  delegate :batch, :commit, :commit_if_dirty, :commit_if_delete_dirty,
61
61
  :dirty?, :index!, :index, :optimize, :remove!, :remove, :remove_all!,
62
- :remove_all, :remove_by_id!, :remove_by_id,
62
+ :remove_all, :remove_by_id!, :remove_by_id, :atomic_update, :atomic_update!,
63
63
  :to => :retry_handler
64
64
 
65
65
  end
@@ -27,9 +27,11 @@ module Sunspot
27
27
  # * remove_by_id!
28
28
  # * remove_all with an argument
29
29
  # * remove_all! with an argument
30
+ # * atomic_update with arguments
31
+ # * atomic_update! with arguments
30
32
  #
31
33
  class ShardingSessionProxy < AbstractSessionProxy
32
- not_supported :batch, :config, :remove_by_id, :remove_by_id!
34
+ not_supported :batch, :config, :remove_by_id, :remove_by_id!, :atomic_update, :atomic_update!
33
35
 
34
36
  #
35
37
  # +search_session+ is the session that should be used for searching.
@@ -70,7 +72,7 @@ module Sunspot
70
72
  using_sharded_session(objects) { |session, group| session.index!(group) }
71
73
  end
72
74
 
73
- #
75
+ #
74
76
  # See Sunspot.remove
75
77
  #
76
78
  def remove(*objects)
@@ -22,7 +22,7 @@ module Sunspot
22
22
  SUPPORTED_METHODS = [
23
23
  :batch, :commit, :commit_if_dirty, :commit_if_delete_dirty, :dirty?,
24
24
  :index!, :index, :optimize, :remove!, :remove, :remove_all!, :remove_all,
25
- :remove_by_id!, :remove_by_id
25
+ :remove_by_id!, :remove_by_id, :atomic_update, :atomic_update!
26
26
  ]
27
27
 
28
28
  SUPPORTED_METHODS.each do |method|
@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), 'abstract_session_proxy')
3
3
 
4
4
  module Sunspot
5
5
  module SessionProxy
6
- #
6
+ #
7
7
  # This class implements a session proxy that creates a different Session
8
8
  # object for each thread. Any multithreaded application should use this
9
9
  # proxy.
@@ -17,14 +17,16 @@ module Sunspot
17
17
  attr_reader :config
18
18
  @@next_id = 0
19
19
 
20
- delegate :batch, :commit, :commit_if_delete_dirty, :commit_if_dirty, :delete_dirty?, :dirty?, :index, :index!, :new_search, :optimize, :remove, :remove!, :remove_all, :remove_all!, :remove_by_id, :remove_by_id!, :search, :more_like_this, :new_more_like_this, :to => :session
20
+ delegate :batch, :commit, :commit_if_delete_dirty, :commit_if_dirty, :delete_dirty?, :dirty?, :index, :index!,
21
+ :new_search, :optimize, :remove, :remove!, :remove_all, :remove_all!, :remove_by_id, :remove_by_id!,
22
+ :search, :more_like_this, :new_more_like_this, :atomic_update, :atomic_update!, :to => :session
21
23
 
22
- #
24
+ #
23
25
  # Optionally pass an existing Sunspot::Configuration object. If none is
24
26
  # passed, a default configuration is used; it can then be modified using
25
27
  # the #config attribute.
26
28
  #
27
- def initialize(config = Sunspot::Configuration.new)
29
+ def initialize(config = Sunspot::Configuration.build)
28
30
  @config = config
29
31
  ObjectSpace.define_finalizer(self, FINALIZER)
30
32
  end
data/lib/sunspot/setup.rb CHANGED
@@ -15,6 +15,7 @@ module Sunspot
15
15
  @more_like_this_field_factories_cache = Hash.new { |h, k| h[k] = [] }
16
16
  @dsl = DSL::Fields.new(self)
17
17
  @document_boost_extractor = nil
18
+ @id_prefix_extractor = nil
18
19
  add_field_factory(:class, Type::ClassType.instance)
19
20
  end
20
21
 
@@ -38,6 +39,17 @@ module Sunspot
38
39
  end
39
40
  end
40
41
 
42
+ def add_join_field_factory(name, type, options = {}, &block)
43
+ field_factory = FieldFactory::Join.new(name, type, options, &block)
44
+ @field_factories[field_factory.signature] = field_factory
45
+
46
+ if type.is_a?(Type::TextType)
47
+ @text_field_factories_cache[field_factory.name] = field_factory
48
+ else
49
+ @field_factories_cache[field_factory.name] = field_factory
50
+ end
51
+ end
52
+
41
53
  #
42
54
  # Add field_factories for fulltext search
43
55
  #
@@ -50,6 +62,7 @@ module Sunspot
50
62
  field_factory = FieldFactory::Static.new(name, Type::TextType.instance, options, &block)
51
63
  @text_field_factories[name] = field_factory
52
64
  @text_field_factories_cache[field_factory.name] = field_factory
65
+ @field_factories_cache[field_factory.name] = field_factory
53
66
  if stored
54
67
  @stored_field_factories_cache[field_factory.name] << field_factory
55
68
  end
@@ -70,6 +83,7 @@ module Sunspot
70
83
  field_factory = FieldFactory::Dynamic.new(name, type, options, &block)
71
84
  @dynamic_field_factories[field_factory.signature] = field_factory
72
85
  @dynamic_field_factories_cache[field_factory.name] = field_factory
86
+ @field_factories_cache[field_factory.name] = field_factory
73
87
  if stored
74
88
  @stored_field_factories_cache[field_factory.name] << field_factory
75
89
  end
@@ -96,6 +110,24 @@ module Sunspot
96
110
  end
97
111
  end
98
112
 
113
+ #
114
+ # Add id prefix for compositeId router
115
+ #
116
+ def add_id_prefix(attr_name, &block)
117
+ @id_prefix_extractor =
118
+ case attr_name
119
+ when Symbol
120
+ DataExtractor::AttributeExtractor.new(attr_name)
121
+ when String
122
+ DataExtractor::Constant.new(attr_name)
123
+ when nil
124
+ DataExtractor::BlockExtractor.new(&block) if block_given?
125
+ else
126
+ raise ArgumentError,
127
+ "The ID prefix has to be either a Symbol, a String or a Proc"
128
+ end
129
+ end
130
+
99
131
  #
100
132
  # Builder method for evaluating the setup DSL
101
133
  #
@@ -260,6 +292,16 @@ module Sunspot
260
292
  end
261
293
  end
262
294
 
295
+ def id_prefix_for(model)
296
+ if @id_prefix_extractor
297
+ value = @id_prefix_extractor.value_for(model)
298
+
299
+ if value.is_a?(String) and value.size > 0
300
+ value[-1] == "!" ? value : "#{value}!"
301
+ end
302
+ end
303
+ end
304
+
263
305
  protected
264
306
 
265
307
  #