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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 179de5f5261bdb69d21038a0b2e36fbd2812e1fc71ef4c1efd77979a03e58179
4
+ data.tar.gz: 1f7f40d9737400cf61c23515c61ebde70140b1c1bf9df800d7e19ce27c3cbd0d
5
+ SHA512:
6
+ metadata.gz: ad59d5868f3461648d29c77b6368d7c5145ef6247ecca38878bf4f03bb3d2ab73fea2decf629936d58282b8067345198f6bff82be1347bb0cc92cb4537722d28
7
+ data.tar.gz: 3c4fd67940331fbdacffd665ca624119038bf12da2aa2b041adbd8260aef3921660b83803a912cf81384c7269f6b46d3b7fad1c883c34e1a1ba2ccbade2fd6dc
data/.gitignore CHANGED
@@ -11,3 +11,4 @@ pkg
11
11
  README.rdoc
12
12
  .bundle
13
13
  Gemfile.lock
14
+ gemfiles/*.gemfile*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Appraisals ADDED
@@ -0,0 +1,7 @@
1
+ appraise 'rsolr-1.x' do
2
+ gem 'rsolr', '>= 1', '< 2'
3
+ end
4
+
5
+ appraise 'rsolr-2.x' do
6
+ gem 'rsolr', '>= 2', '< 3'
7
+ end
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'sunspot_solr', :path => File.expand_path('../../sunspot_solr', __FILE__)
4
-
5
3
  gemspec
data/History.txt CHANGED
@@ -1,3 +1,13 @@
1
+ == 2.1.0
2
+ * Dropped support for rails 2.x. Added support for Rails 4.
3
+ * Bundled Solr installation (`sunspot_solr`) is version 4.2.0
4
+ * Upgrade to Jetty 8 and changed solr config directory structure.
5
+ * Removed interactive warning prompt from sunspot:reindex rake task.
6
+ * Support Rails 4 custom primary keys i.e. UUID
7
+ * Switch to EDismax query parser from dismax.
8
+ * Extend Sunspot.remove! to accept a block, and enable .remove_by_id! to accept multiple ids.
9
+ * add 'order_by_function' method to field queries. Allowing for Solr FunctionQuery, nesting, and literal constants.
10
+
1
11
  == 2.0.0
2
12
  * Adds support for field grouping (Andy Lindeman)
3
13
  * Adds support for native geospatial searches and ordering (Eric Tang, Bruno Miranda, Andy Lindeman)
data/lib/sunspot.rb CHANGED
@@ -196,23 +196,61 @@ module Sunspot
196
196
  session.index!(*objects)
197
197
  end
198
198
 
199
- # Commits the singleton session
199
+ # Atomic update object properties on the singleton session.
200
+ #
201
+ # ==== Parameters
202
+ #
203
+ # clazz<Class>:: the class of the objects to be updated
204
+ # updates<Hash>:: hash of updates where keys are model ids
205
+ # and values are hash with property name/values to be updated
206
+ #
207
+ # ==== Example
208
+ #
209
+ # post1, post2 = new Array(2) { Post.create }
210
+ # Sunspot.atomic_update(Post, post1.id => {title: 'New Title'}, post2.id => {description: 'new description'})
211
+ #
212
+ # Note that indexed objects won't be reflected in search until a commit is
213
+ # sent - see Sunspot.index! and Sunspot.commit
214
+ #
215
+ def atomic_update(clazz, updates = {})
216
+ session.atomic_update(clazz, updates)
217
+ end
218
+
219
+ # Atomic update object properties on the singleton session.
220
+ #
221
+ # See: Sunspot.atomic_update and Sunspot.commit
222
+ #
223
+ # ==== Parameters
224
+ #
225
+ # clazz<Class>:: the class of the objects to be updated
226
+ # updates<Hash>:: hash of updates where keys are model ids
227
+ # and values are hash with property name/values to be updated
228
+ #
229
+ def atomic_update!(clazz, updates = {})
230
+ session.atomic_update!(clazz, updates)
231
+ end
232
+
233
+ # Commits (soft or hard) the singleton session
200
234
  #
201
235
  # When documents are added to or removed from Solr, the changes are
202
236
  # initially stored in memory, and are not reflected in Solr's existing
203
- # searcher instance. When a commit message is sent, the changes are written
237
+ # searcher instance. When a hard commit message is sent, the changes are written
204
238
  # to disk, and a new searcher is spawned. Commits are thus fairly
205
239
  # expensive, so if your application needs to index several documents as part
206
240
  # of a single operation, it is advisable to index them all and then call
207
241
  # commit at the end of the operation.
242
+ # Solr 4 introduced the concept of a soft commit which is much faster
243
+ # since it only makes index changes visible while not writing changes to disk.
244
+ # If Solr crashes or there is a loss of power, changes that occurred after
245
+ # the last hard commit will be lost.
208
246
  #
209
247
  # Note that Solr can also be configured to automatically perform a commit
210
248
  # after either a specified interval after the last change, or after a
211
249
  # specified number of documents are added. See
212
250
  # http://wiki.apache.org/solr/SolrConfigXml
213
251
  #
214
- def commit
215
- session.commit
252
+ def commit(soft_commit = false)
253
+ session.commit soft_commit
216
254
  end
217
255
 
218
256
  # Optimizes the index on the singletion session.
@@ -417,8 +455,8 @@ module Sunspot
417
455
  #
418
456
  # objects...<Object>:: Objects to remove from the index
419
457
  #
420
- def remove!(*objects)
421
- session.remove!(*objects)
458
+ def remove!(*objects, &block)
459
+ session.remove!(*objects, &block)
422
460
  end
423
461
 
424
462
  #
@@ -433,16 +471,16 @@ module Sunspot
433
471
  # Primary key of the object. This should be the same id that would be
434
472
  # returned by the class's instance adapter.
435
473
  #
436
- def remove_by_id(clazz, id)
437
- session.remove_by_id(clazz, id)
474
+ def remove_by_id(clazz, *ids)
475
+ session.remove_by_id(clazz, ids)
438
476
  end
439
477
 
440
478
  #
441
479
  # Remove an object by class name and primary key, and immediately commit.
442
480
  # See #remove_by_id and #commit
443
481
  #
444
- def remove_by_id!(clazz, id)
445
- session.remove_by_id!(clazz, id)
482
+ def remove_by_id!(clazz, *ids)
483
+ session.remove_by_id!(clazz, ids)
446
484
  end
447
485
 
448
486
  # Remove all objects of the given classes from the index. There isn't much
@@ -486,9 +524,9 @@ module Sunspot
486
524
  #
487
525
  # Sunspot.batch do
488
526
  # post = Post.new
489
- # Sunspot.add(post)
527
+ # Sunspot.index(post)
490
528
  # comment = Comment.new
491
- # Sunspot.add(comment)
529
+ # Sunspot.index(comment)
492
530
  # end
493
531
  #
494
532
  # Sunspot will send both the post and the comment in a single request.
@@ -510,10 +548,10 @@ module Sunspot
510
548
  end
511
549
 
512
550
  #
513
- # Sends a commit if the session is dirty (see #dirty?).
551
+ # Sends a commit (soft or hard) if the session is dirty (see #dirty?).
514
552
  #
515
- def commit_if_dirty
516
- session.commit_if_dirty
553
+ def commit_if_dirty(soft_commit = false)
554
+ session.commit_if_dirty soft_commit
517
555
  end
518
556
 
519
557
  #
@@ -530,8 +568,8 @@ module Sunspot
530
568
  #
531
569
  # Sends a commit if the session has deletes since the last commit (see #delete_dirty?).
532
570
  #
533
- def commit_if_delete_dirty
534
- session.commit_if_delete_dirty
571
+ def commit_if_delete_dirty(soft_commit = false)
572
+ session.commit_if_delete_dirty soft_commit
535
573
  end
536
574
 
537
575
  # Returns the configuration associated with the singleton session. See
@@ -1,3 +1,5 @@
1
+ require 'forwardable'
2
+
1
3
  module Sunspot
2
4
  #
3
5
  # Sunspot works by saving references to the primary key (or natural ID) of
@@ -46,7 +48,7 @@ module Sunspot
46
48
  # end
47
49
  #
48
50
  # # then in your initializer
49
- # Sunspot::Adapters::InstanceAdapter.register(MyAdapter, File)
51
+ # Sunspot::Adapters::InstanceAdapter.register(FileAdapter, File)
50
52
  #
51
53
  class InstanceAdapter
52
54
  def initialize(instance) #:nodoc:
@@ -61,7 +63,10 @@ module Sunspot
61
63
  # String:: ID for use in Solr
62
64
  #
63
65
  def index_id #:nodoc:
64
- InstanceAdapter.index_id_for(@instance.class.name, id)
66
+ setup = Sunspot::Setup.for(@instance.class)
67
+ id_prefix = setup ? setup.id_prefix_for(@instance) : nil
68
+
69
+ InstanceAdapter.index_id_for("#{id_prefix}#{@instance.class.name}", id)
65
70
  end
66
71
 
67
72
  class <<self
@@ -119,16 +124,28 @@ module Sunspot
119
124
  #
120
125
  # Sunspot::NoAdapterError:: If no adapter is registered for this class
121
126
  #
122
- def for(clazz) #:nodoc:
123
- original_class_name = clazz.name
124
- clazz.ancestors.each do |ancestor_class|
125
- next if ancestor_class.name.nil? || ancestor_class.name.empty?
126
- class_name = ancestor_class.name.to_sym
127
- return instance_adapters[class_name] if instance_adapters[class_name]
128
- end
129
-
127
+ def for(clazz)
128
+ adapter = registered_adapter_for(clazz) || registered_adapter_for_ancestors_of(clazz)
129
+ return adapter if adapter
130
130
  raise(Sunspot::NoAdapterError,
131
- "No adapter is configured for #{original_class_name} or its superclasses. See the documentation for Sunspot::Adapters")
131
+ "No adapter is configured for #{clazz.name} or its superclasses. See the documentation for Sunspot::Adapters")
132
+ end
133
+
134
+ # Returns the directly-registered adapter for the specified class,
135
+ # if one exists, without searching the class's ancestors.
136
+ #
137
+ # === Parameters
138
+ #
139
+ # clazz<Class>:: The model class to be checked for the registered
140
+ # adapter
141
+ #
142
+ # === Returns
143
+ #
144
+ # Class:: Subclass of InstanceAdapter, or nil if none found
145
+ #
146
+ def registered_adapter_for(clazz)
147
+ return nil if clazz.name.nil? || clazz.name.empty?
148
+ instance_adapters[clazz.name.to_sym]
132
149
  end
133
150
 
134
151
  def index_id_for(class_name, id) #:nodoc:
@@ -146,6 +163,16 @@ module Sunspot
146
163
  def instance_adapters #:nodoc:
147
164
  @instance_adapters ||= {}
148
165
  end
166
+
167
+ def registered_adapter_for_ancestors_of(clazz) # :nodoc:
168
+ clazz.ancestors.each do |ancestor_class|
169
+ if adapter = registered_adapter_for(ancestor_class)
170
+ register(adapter, clazz)
171
+ return adapter
172
+ end
173
+ end
174
+ nil
175
+ end
149
176
  end
150
177
  end
151
178
 
@@ -247,14 +274,27 @@ module Sunspot
247
274
  # Sunspot::NoAdapterError:: If no data accessor exists for the given class
248
275
  #
249
276
  def for(clazz) #:nodoc:
250
- original_class_name = clazz.name
251
- clazz.ancestors.each do |ancestor_class|
252
- next if ancestor_class.name.nil? || ancestor_class.name.empty?
253
- class_name = ancestor_class.name.to_sym
254
- return data_accessors[class_name] if data_accessors[class_name]
255
- end
277
+ accessor = registered_accessor_for(clazz) || registered_accessor_for_ancestors_of(clazz)
278
+ return accessor if accessor
256
279
  raise(Sunspot::NoAdapterError,
257
- "No data accessor is configured for #{original_class_name} or its superclasses. See the documentation for Sunspot::Adapters")
280
+ "No data accessor is configured for #{clazz.name} or its superclasses. See the documentation for Sunspot::Adapters")
281
+ end
282
+
283
+ # Returns the directly-registered accessor for the specified class, if
284
+ # one exists, without searching the class's ancestors.
285
+ #
286
+ # === Parameters
287
+ #
288
+ # clazz<Class>:: The model class to be checked for the registered
289
+ # data accessor
290
+ #
291
+ # === Returns
292
+ #
293
+ # Class:: Subclass of DataAccessor, or nil if none found
294
+ #
295
+ def registered_accessor_for(clazz)
296
+ return nil if clazz.name.nil? || clazz.name.empty?
297
+ data_accessors[clazz.name.to_sym]
258
298
  end
259
299
 
260
300
  protected
@@ -268,6 +308,16 @@ module Sunspot
268
308
  def data_accessors #:nodoc:
269
309
  @adapters ||= {}
270
310
  end
311
+
312
+ def registered_accessor_for_ancestors_of(clazz) # :nodoc:
313
+ clazz.ancestors.each do |ancestor_class|
314
+ if accessor = registered_accessor_for(ancestor_class)
315
+ register(accessor, clazz)
316
+ return accessor
317
+ end
318
+ end
319
+ nil
320
+ end
271
321
  end
272
322
  end
273
323
 
@@ -12,7 +12,7 @@ module Sunspot
12
12
  # end
13
13
  #
14
14
  # it is the Batcher's job to keep track of these nestings. The inner will
15
- # be sent of to be indexed first.
15
+ # be sent off to be indexed first.
16
16
  #
17
17
  class Batcher
18
18
  include Enumerable
@@ -22,9 +22,11 @@ module Sunspot
22
22
  def build #:nodoc:
23
23
  LightConfig.build do
24
24
  solr do
25
- url 'http://127.0.0.1:8983/solr'
25
+ url 'http://127.0.0.1:8983/solr/default'
26
26
  read_timeout nil
27
27
  open_timeout nil
28
+ proxy nil
29
+ update_format :xml
28
30
  end
29
31
  master_solr do
30
32
  url nil
@@ -37,7 +39,7 @@ module Sunspot
37
39
  end
38
40
  end
39
41
  end
40
-
42
+
41
43
  # Location for the default solr configuration files,
42
44
  # required for bootstrapping a new solr installation
43
45
  #
@@ -5,16 +5,46 @@ module Sunspot
5
5
  # method, which takes an object and returns the value extracted from it.
6
6
  #
7
7
  module DataExtractor #:nodoc: all
8
+ #
9
+ # Abstract extractor to perform common actions on extracted values
10
+ #
11
+ class AbstractExtractor
12
+ BLACKLIST_REGEXP = /[\x0-\x8\xB\xC\xE-\x1F\x7f]/
13
+
14
+ def value_for(object)
15
+ extract_value_from(object)
16
+ end
17
+
18
+ private
19
+
20
+ def extract_value_from(object)
21
+ case object
22
+ when String
23
+ remove_blacklisted_chars(object)
24
+ when Array
25
+ object.map { |o| extract_value_from(o) }
26
+ when Hash
27
+ object.inject({}) { |h, (k, v)| h.merge(extract_value_from(k) => extract_value_from(v)) }
28
+ else
29
+ object
30
+ end
31
+ end
32
+
33
+ def remove_blacklisted_chars(object)
34
+ object.gsub(BLACKLIST_REGEXP, '')
35
+ end
36
+ end
37
+
8
38
  #
9
39
  # AttributeExtractors extract data by simply calling a method on the block.
10
40
  #
11
- class AttributeExtractor
41
+ class AttributeExtractor < AbstractExtractor
12
42
  def initialize(attribute_name)
13
43
  @attribute_name = attribute_name
14
44
  end
15
45
 
16
46
  def value_for(object)
17
- object.send(@attribute_name)
47
+ super object.send(@attribute_name)
18
48
  end
19
49
  end
20
50
 
@@ -24,26 +54,26 @@ module Sunspot
24
54
  # as the argument to the block. Either way, the return value of the block is
25
55
  # the value returned by the extractor.
26
56
  #
27
- class BlockExtractor
57
+ class BlockExtractor < AbstractExtractor
28
58
  def initialize(&block)
29
59
  @block = block
30
60
  end
31
61
 
32
62
  def value_for(object)
33
- Util.instance_eval_or_call(object, &@block)
63
+ super Util.instance_eval_or_call(object, &@block)
34
64
  end
35
65
  end
36
66
 
37
67
  #
38
68
  # Constant data extractors simply return the same value for every object.
39
69
  #
40
- class Constant
70
+ class Constant < AbstractExtractor
41
71
  def initialize(value)
42
72
  @value = value
43
73
  end
44
74
 
45
75
  def value_for(object)
46
- @value
76
+ super @value
47
77
  end
48
78
  end
49
79
  end
data/lib/sunspot/dsl.rb CHANGED
@@ -1,5 +1,6 @@
1
- %w(fields scope paginatable adjustable field_query standard_query query_facet
2
- functional fulltext restriction restriction_with_near search
3
- more_like_this_query function field_group).each do |file|
1
+ %w(spellcheckable fields scope paginatable adjustable field_query
2
+ standard_query query_facet functional fulltext restriction
3
+ restriction_with_near search more_like_this_query function
4
+ group field_stats).each do |file|
4
5
  require File.join(File.dirname(__FILE__), 'dsl', file)
5
6
  end
@@ -26,9 +26,9 @@ module Sunspot
26
26
  # params["mlt.match.include"] = true
27
27
  # end
28
28
  # end
29
- #
29
+ #
30
30
  def adjust_solr_params( &block )
31
- @query.solr_parameter_adjustment = block
31
+ @query.add_parameter_adjustment(block)
32
32
  end
33
33
 
34
34
  #