sunspot_rails 2.0.0.pre.120720 → 2.0.0.pre.120924

Sign up to get free protection for your applications and to get access to all the features.
Files changed (293) hide show
  1. data/.gitignore +10 -6
  2. data/.travis.yml +35 -0
  3. data/README.md +863 -0
  4. data/Rakefile +32 -12
  5. data/ci/travis.sh +67 -0
  6. data/sunspot/.gitignore +13 -0
  7. data/sunspot/Gemfile +5 -0
  8. data/sunspot/History.txt +258 -0
  9. data/{LICENSE → sunspot/LICENSE} +0 -0
  10. data/sunspot/Rakefile +13 -0
  11. data/sunspot/TODO +13 -0
  12. data/sunspot/lib/light_config.rb +40 -0
  13. data/sunspot/lib/sunspot.rb +579 -0
  14. data/sunspot/lib/sunspot/adapters.rb +349 -0
  15. data/sunspot/lib/sunspot/batcher.rb +62 -0
  16. data/sunspot/lib/sunspot/class_set.rb +23 -0
  17. data/sunspot/lib/sunspot/composite_setup.rb +202 -0
  18. data/sunspot/lib/sunspot/configuration.rb +53 -0
  19. data/sunspot/lib/sunspot/data_extractor.rb +50 -0
  20. data/sunspot/lib/sunspot/dsl.rb +5 -0
  21. data/sunspot/lib/sunspot/dsl/adjustable.rb +47 -0
  22. data/sunspot/lib/sunspot/dsl/field_group.rb +57 -0
  23. data/sunspot/lib/sunspot/dsl/field_query.rb +345 -0
  24. data/sunspot/lib/sunspot/dsl/fields.rb +103 -0
  25. data/sunspot/lib/sunspot/dsl/fulltext.rb +243 -0
  26. data/sunspot/lib/sunspot/dsl/function.rb +27 -0
  27. data/sunspot/lib/sunspot/dsl/functional.rb +44 -0
  28. data/sunspot/lib/sunspot/dsl/more_like_this_query.rb +56 -0
  29. data/sunspot/lib/sunspot/dsl/paginatable.rb +32 -0
  30. data/sunspot/lib/sunspot/dsl/query_facet.rb +36 -0
  31. data/sunspot/lib/sunspot/dsl/restriction.rb +25 -0
  32. data/sunspot/lib/sunspot/dsl/restriction_with_near.rb +160 -0
  33. data/sunspot/lib/sunspot/dsl/scope.rb +214 -0
  34. data/sunspot/lib/sunspot/dsl/search.rb +30 -0
  35. data/sunspot/lib/sunspot/dsl/standard_query.rb +122 -0
  36. data/sunspot/lib/sunspot/field.rb +193 -0
  37. data/sunspot/lib/sunspot/field_factory.rb +129 -0
  38. data/sunspot/lib/sunspot/indexer.rb +136 -0
  39. data/sunspot/lib/sunspot/query.rb +11 -0
  40. data/sunspot/lib/sunspot/query/abstract_field_facet.rb +55 -0
  41. data/sunspot/lib/sunspot/query/bbox.rb +15 -0
  42. data/sunspot/lib/sunspot/query/boost_query.rb +24 -0
  43. data/sunspot/lib/sunspot/query/common_query.rb +96 -0
  44. data/sunspot/lib/sunspot/query/composite_fulltext.rb +36 -0
  45. data/sunspot/lib/sunspot/query/connective.rb +206 -0
  46. data/sunspot/lib/sunspot/query/date_field_facet.rb +14 -0
  47. data/sunspot/lib/sunspot/query/dismax.rb +132 -0
  48. data/sunspot/lib/sunspot/query/field_facet.rb +41 -0
  49. data/sunspot/lib/sunspot/query/field_group.rb +37 -0
  50. data/sunspot/lib/sunspot/query/filter.rb +38 -0
  51. data/sunspot/lib/sunspot/query/function_query.rb +52 -0
  52. data/sunspot/lib/sunspot/query/geo.rb +53 -0
  53. data/sunspot/lib/sunspot/query/geofilt.rb +16 -0
  54. data/sunspot/lib/sunspot/query/highlighting.rb +62 -0
  55. data/sunspot/lib/sunspot/query/more_like_this.rb +61 -0
  56. data/sunspot/lib/sunspot/query/more_like_this_query.rb +12 -0
  57. data/sunspot/lib/sunspot/query/pagination.rb +42 -0
  58. data/sunspot/lib/sunspot/query/query_facet.rb +53 -0
  59. data/sunspot/lib/sunspot/query/range_facet.rb +15 -0
  60. data/sunspot/lib/sunspot/query/restriction.rb +308 -0
  61. data/sunspot/lib/sunspot/query/scope.rb +9 -0
  62. data/sunspot/lib/sunspot/query/sort.rb +109 -0
  63. data/sunspot/lib/sunspot/query/sort_composite.rb +34 -0
  64. data/sunspot/lib/sunspot/query/standard_query.rb +16 -0
  65. data/sunspot/lib/sunspot/query/text_field_boost.rb +17 -0
  66. data/sunspot/lib/sunspot/schema.rb +151 -0
  67. data/sunspot/lib/sunspot/search.rb +9 -0
  68. data/sunspot/lib/sunspot/search/abstract_search.rb +286 -0
  69. data/sunspot/lib/sunspot/search/date_facet.rb +35 -0
  70. data/sunspot/lib/sunspot/search/facet_row.rb +27 -0
  71. data/sunspot/lib/sunspot/search/field_facet.rb +88 -0
  72. data/sunspot/lib/sunspot/search/field_group.rb +70 -0
  73. data/sunspot/lib/sunspot/search/group.rb +54 -0
  74. data/sunspot/lib/sunspot/search/highlight.rb +38 -0
  75. data/sunspot/lib/sunspot/search/hit.rb +150 -0
  76. data/sunspot/lib/sunspot/search/hit_enumerable.rb +68 -0
  77. data/sunspot/lib/sunspot/search/more_like_this_search.rb +31 -0
  78. data/sunspot/lib/sunspot/search/paginated_collection.rb +57 -0
  79. data/sunspot/lib/sunspot/search/query_facet.rb +67 -0
  80. data/sunspot/lib/sunspot/search/range_facet.rb +37 -0
  81. data/sunspot/lib/sunspot/search/standard_search.rb +21 -0
  82. data/sunspot/lib/sunspot/session.rb +262 -0
  83. data/sunspot/lib/sunspot/session_proxy.rb +95 -0
  84. data/sunspot/lib/sunspot/session_proxy/abstract_session_proxy.rb +29 -0
  85. data/sunspot/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +66 -0
  86. data/sunspot/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +89 -0
  87. data/sunspot/lib/sunspot/session_proxy/master_slave_session_proxy.rb +43 -0
  88. data/sunspot/lib/sunspot/session_proxy/retry_5xx_session_proxy.rb +67 -0
  89. data/sunspot/lib/sunspot/session_proxy/sharding_session_proxy.rb +222 -0
  90. data/sunspot/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
  91. data/sunspot/lib/sunspot/session_proxy/thread_local_session_proxy.rb +37 -0
  92. data/sunspot/lib/sunspot/setup.rb +350 -0
  93. data/sunspot/lib/sunspot/text_field_setup.rb +29 -0
  94. data/sunspot/lib/sunspot/type.rb +393 -0
  95. data/sunspot/lib/sunspot/util.rb +252 -0
  96. data/sunspot/lib/sunspot/version.rb +3 -0
  97. data/sunspot/script/console +10 -0
  98. data/sunspot/spec/api/adapters_spec.rb +68 -0
  99. data/sunspot/spec/api/batcher_spec.rb +112 -0
  100. data/sunspot/spec/api/binding_spec.rb +50 -0
  101. data/sunspot/spec/api/class_set_spec.rb +24 -0
  102. data/sunspot/spec/api/hit_enumerable_spec.rb +47 -0
  103. data/sunspot/spec/api/indexer/attributes_spec.rb +149 -0
  104. data/sunspot/spec/api/indexer/batch_spec.rb +72 -0
  105. data/sunspot/spec/api/indexer/dynamic_fields_spec.rb +42 -0
  106. data/sunspot/spec/api/indexer/fixed_fields_spec.rb +57 -0
  107. data/sunspot/spec/api/indexer/fulltext_spec.rb +43 -0
  108. data/sunspot/spec/api/indexer/removal_spec.rb +53 -0
  109. data/sunspot/spec/api/indexer/spec_helper.rb +1 -0
  110. data/sunspot/spec/api/indexer_spec.rb +14 -0
  111. data/sunspot/spec/api/query/advanced_manipulation_examples.rb +35 -0
  112. data/sunspot/spec/api/query/connectives_examples.rb +201 -0
  113. data/sunspot/spec/api/query/dsl_spec.rb +18 -0
  114. data/sunspot/spec/api/query/dynamic_fields_examples.rb +165 -0
  115. data/sunspot/spec/api/query/faceting_examples.rb +497 -0
  116. data/sunspot/spec/api/query/fulltext_examples.rb +313 -0
  117. data/sunspot/spec/api/query/function_spec.rb +79 -0
  118. data/sunspot/spec/api/query/geo_examples.rb +68 -0
  119. data/sunspot/spec/api/query/group_spec.rb +32 -0
  120. data/sunspot/spec/api/query/highlighting_examples.rb +245 -0
  121. data/sunspot/spec/api/query/more_like_this_spec.rb +140 -0
  122. data/sunspot/spec/api/query/ordering_pagination_examples.rb +116 -0
  123. data/sunspot/spec/api/query/scope_examples.rb +275 -0
  124. data/sunspot/spec/api/query/spatial_examples.rb +27 -0
  125. data/sunspot/spec/api/query/spec_helper.rb +1 -0
  126. data/sunspot/spec/api/query/standard_spec.rb +29 -0
  127. data/sunspot/spec/api/query/text_field_scoping_examples.rb +30 -0
  128. data/sunspot/spec/api/query/types_spec.rb +20 -0
  129. data/sunspot/spec/api/search/dynamic_fields_spec.rb +33 -0
  130. data/sunspot/spec/api/search/faceting_spec.rb +360 -0
  131. data/sunspot/spec/api/search/highlighting_spec.rb +69 -0
  132. data/sunspot/spec/api/search/hits_spec.rb +147 -0
  133. data/sunspot/spec/api/search/paginated_collection_spec.rb +36 -0
  134. data/sunspot/spec/api/search/results_spec.rb +72 -0
  135. data/sunspot/spec/api/search/search_spec.rb +23 -0
  136. data/sunspot/spec/api/search/spec_helper.rb +1 -0
  137. data/sunspot/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +85 -0
  138. data/sunspot/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +30 -0
  139. data/sunspot/spec/api/session_proxy/master_slave_session_proxy_spec.rb +41 -0
  140. data/sunspot/spec/api/session_proxy/retry_5xx_session_proxy_spec.rb +78 -0
  141. data/sunspot/spec/api/session_proxy/sharding_session_proxy_spec.rb +77 -0
  142. data/sunspot/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
  143. data/sunspot/spec/api/session_proxy/spec_helper.rb +9 -0
  144. data/sunspot/spec/api/session_proxy/thread_local_session_proxy_spec.rb +39 -0
  145. data/sunspot/spec/api/session_spec.rb +232 -0
  146. data/sunspot/spec/api/spec_helper.rb +3 -0
  147. data/sunspot/spec/api/sunspot_spec.rb +29 -0
  148. data/sunspot/spec/ext.rb +11 -0
  149. data/sunspot/spec/helpers/indexer_helper.rb +17 -0
  150. data/sunspot/spec/helpers/integration_helper.rb +8 -0
  151. data/sunspot/spec/helpers/mock_session_helper.rb +13 -0
  152. data/sunspot/spec/helpers/query_helper.rb +26 -0
  153. data/sunspot/spec/helpers/search_helper.rb +68 -0
  154. data/sunspot/spec/integration/dynamic_fields_spec.rb +57 -0
  155. data/sunspot/spec/integration/faceting_spec.rb +330 -0
  156. data/sunspot/spec/integration/field_grouping_spec.rb +100 -0
  157. data/sunspot/spec/integration/geospatial_spec.rb +96 -0
  158. data/sunspot/spec/integration/highlighting_spec.rb +44 -0
  159. data/sunspot/spec/integration/indexing_spec.rb +55 -0
  160. data/sunspot/spec/integration/keyword_search_spec.rb +317 -0
  161. data/sunspot/spec/integration/local_search_spec.rb +64 -0
  162. data/sunspot/spec/integration/more_like_this_spec.rb +43 -0
  163. data/sunspot/spec/integration/scoped_search_spec.rb +386 -0
  164. data/sunspot/spec/integration/stored_fields_spec.rb +12 -0
  165. data/sunspot/spec/integration/test_pagination.rb +43 -0
  166. data/sunspot/spec/integration/unicode_spec.rb +15 -0
  167. data/sunspot/spec/mocks/adapters.rb +33 -0
  168. data/sunspot/spec/mocks/blog.rb +3 -0
  169. data/sunspot/spec/mocks/comment.rb +21 -0
  170. data/sunspot/spec/mocks/connection.rb +126 -0
  171. data/sunspot/spec/mocks/mock_adapter.rb +30 -0
  172. data/sunspot/spec/mocks/mock_class_sharding_session_proxy.rb +24 -0
  173. data/sunspot/spec/mocks/mock_record.rb +52 -0
  174. data/sunspot/spec/mocks/mock_sharding_session_proxy.rb +15 -0
  175. data/sunspot/spec/mocks/photo.rb +11 -0
  176. data/sunspot/spec/mocks/post.rb +86 -0
  177. data/sunspot/spec/mocks/super_class.rb +2 -0
  178. data/sunspot/spec/mocks/user.rb +13 -0
  179. data/sunspot/spec/spec_helper.rb +40 -0
  180. data/sunspot/sunspot.gemspec +37 -0
  181. data/sunspot/tasks/rdoc.rake +27 -0
  182. data/sunspot/tasks/schema.rake +19 -0
  183. data/{dev_tasks → sunspot/tasks}/todo.rake +0 -0
  184. data/sunspot_rails/.gitignore +7 -0
  185. data/{.rspec → sunspot_rails/.rspec} +0 -0
  186. data/{History.txt → sunspot_rails/History.txt} +0 -0
  187. data/sunspot_rails/LICENSE +18 -0
  188. data/{MIT-LICENSE → sunspot_rails/MIT-LICENSE} +0 -0
  189. data/{README.rdoc → sunspot_rails/README.rdoc} +0 -0
  190. data/sunspot_rails/Rakefile +17 -0
  191. data/{TODO → sunspot_rails/TODO} +0 -0
  192. data/{dev_tasks → sunspot_rails/dev_tasks}/rdoc.rake +0 -0
  193. data/{dev_tasks → sunspot_rails/dev_tasks}/release.rake +0 -0
  194. data/{dev_tasks → sunspot_rails/dev_tasks}/spec.rake +0 -0
  195. data/sunspot_rails/dev_tasks/todo.rake +4 -0
  196. data/{gemfiles → sunspot_rails/gemfiles}/rails-2.3.14 +0 -0
  197. data/{gemfiles → sunspot_rails/gemfiles}/rails-3.0.15 +0 -0
  198. data/{gemfiles → sunspot_rails/gemfiles}/rails-3.1.6 +0 -0
  199. data/{gemfiles → sunspot_rails/gemfiles}/rails-3.2.6 +0 -0
  200. data/{generators → sunspot_rails/generators}/sunspot/sunspot_generator.rb +0 -0
  201. data/{generators → sunspot_rails/generators}/sunspot/templates/sunspot.yml +0 -0
  202. data/{install.rb → sunspot_rails/install.rb} +0 -0
  203. data/{lib → sunspot_rails/lib}/generators/sunspot_rails.rb +0 -0
  204. data/{lib → sunspot_rails/lib}/generators/sunspot_rails/install/install_generator.rb +0 -0
  205. data/{lib → sunspot_rails/lib}/generators/sunspot_rails/install/templates/config/sunspot.yml +0 -0
  206. data/{lib → sunspot_rails/lib}/sunspot/rails.rb +0 -0
  207. data/{lib → sunspot_rails/lib}/sunspot/rails/adapters.rb +5 -0
  208. data/{lib → sunspot_rails/lib}/sunspot/rails/configuration.rb +0 -0
  209. data/{lib → sunspot_rails/lib}/sunspot/rails/init.rb +0 -0
  210. data/{lib → sunspot_rails/lib}/sunspot/rails/log_subscriber.rb +12 -0
  211. data/{lib → sunspot_rails/lib}/sunspot/rails/railtie.rb +5 -0
  212. data/{lib → sunspot_rails/lib}/sunspot/rails/railties/controller_runtime.rb +0 -0
  213. data/{lib → sunspot_rails/lib}/sunspot/rails/request_lifecycle.rb +0 -0
  214. data/{lib → sunspot_rails/lib}/sunspot/rails/searchable.rb +10 -6
  215. data/{lib → sunspot_rails/lib}/sunspot/rails/server.rb +0 -0
  216. data/{lib → sunspot_rails/lib}/sunspot/rails/solr_instrumentation.rb +0 -0
  217. data/{lib → sunspot_rails/lib}/sunspot/rails/solr_logging.rb +0 -0
  218. data/{lib → sunspot_rails/lib}/sunspot/rails/spec_helper.rb +0 -0
  219. data/{lib → sunspot_rails/lib}/sunspot/rails/stub_session_proxy.rb +0 -0
  220. data/{lib → sunspot_rails/lib}/sunspot/rails/tasks.rb +0 -0
  221. data/{lib → sunspot_rails/lib}/sunspot_rails.rb +0 -0
  222. data/{spec → sunspot_rails/spec}/configuration_spec.rb +0 -0
  223. data/{spec → sunspot_rails/spec}/model_lifecycle_spec.rb +0 -0
  224. data/{spec → sunspot_rails/spec}/model_spec.rb +0 -0
  225. data/{spec → sunspot_rails/spec}/rails_template/app/controllers/application_controller.rb +0 -0
  226. data/{spec → sunspot_rails/spec}/rails_template/app/controllers/posts_controller.rb +0 -0
  227. data/{spec → sunspot_rails/spec}/rails_template/app/models/author.rb +0 -0
  228. data/{spec → sunspot_rails/spec}/rails_template/app/models/blog.rb +0 -0
  229. data/{spec → sunspot_rails/spec}/rails_template/app/models/location.rb +0 -0
  230. data/{spec → sunspot_rails/spec}/rails_template/app/models/photo_post.rb +0 -0
  231. data/{spec → sunspot_rails/spec}/rails_template/app/models/post.rb +0 -0
  232. data/{spec → sunspot_rails/spec}/rails_template/app/models/post_with_auto.rb +0 -0
  233. data/{spec → sunspot_rails/spec}/rails_template/app/models/post_with_default_scope.rb +0 -0
  234. data/{spec → sunspot_rails/spec}/rails_template/config/boot.rb +0 -0
  235. data/{spec → sunspot_rails/spec}/rails_template/config/preinitializer.rb +0 -0
  236. data/{spec → sunspot_rails/spec}/rails_template/config/routes.rb +0 -0
  237. data/{spec → sunspot_rails/spec}/rails_template/config/sunspot.yml +0 -0
  238. data/{spec → sunspot_rails/spec}/rails_template/db/schema.rb +0 -0
  239. data/{spec → sunspot_rails/spec}/request_lifecycle_spec.rb +0 -0
  240. data/{spec → sunspot_rails/spec}/schema.rb +0 -0
  241. data/{spec → sunspot_rails/spec}/searchable_spec.rb +0 -0
  242. data/{spec → sunspot_rails/spec}/server_spec.rb +0 -0
  243. data/{spec → sunspot_rails/spec}/session_spec.rb +0 -0
  244. data/{spec → sunspot_rails/spec}/shared_examples/indexed_after_save.rb +0 -0
  245. data/{spec → sunspot_rails/spec}/shared_examples/not_indexed_after_save.rb +0 -0
  246. data/{spec → sunspot_rails/spec}/spec_helper.rb +0 -0
  247. data/{spec → sunspot_rails/spec}/stub_session_proxy_spec.rb +0 -0
  248. data/{sunspot_rails.gemspec → sunspot_rails/sunspot_rails.gemspec} +0 -0
  249. data/sunspot_solr/Gemfile +3 -0
  250. data/sunspot_solr/README.rdoc +24 -0
  251. data/sunspot_solr/bin/sunspot-installer +20 -0
  252. data/sunspot_solr/bin/sunspot-solr +80 -0
  253. data/sunspot_solr/lib/sunspot/solr/installer.rb +25 -0
  254. data/sunspot_solr/lib/sunspot/solr/installer/config_installer.rb +46 -0
  255. data/sunspot_solr/lib/sunspot/solr/installer/task_helper.rb +13 -0
  256. data/sunspot_solr/lib/sunspot/solr/java.rb +10 -0
  257. data/sunspot_solr/lib/sunspot/solr/railtie.rb +15 -0
  258. data/sunspot_solr/lib/sunspot/solr/server.rb +223 -0
  259. data/sunspot_solr/lib/sunspot/solr/tasks.rb +49 -0
  260. data/sunspot_solr/lib/sunspot_solr.rb +5 -0
  261. data/sunspot_solr/solr/README.txt +42 -0
  262. data/sunspot_solr/solr/etc/jetty.xml +219 -0
  263. data/sunspot_solr/solr/etc/webdefault.xml +379 -0
  264. data/sunspot_solr/solr/lib/jetty-6.1.26-patched-JETTY-1340.jar +0 -0
  265. data/sunspot_solr/solr/lib/jetty-util-6.1.26-patched-JETTY-1340.jar +0 -0
  266. data/sunspot_solr/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
  267. data/sunspot_solr/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
  268. data/sunspot_solr/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
  269. data/sunspot_solr/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
  270. data/sunspot_solr/solr/lib/servlet-api-2.5-20081211.jar +0 -0
  271. data/sunspot_solr/solr/solr/.gitignore +1 -0
  272. data/sunspot_solr/solr/solr/README.txt +54 -0
  273. data/sunspot_solr/solr/solr/conf/admin-extra.html +31 -0
  274. data/sunspot_solr/solr/solr/conf/elevate.xml +36 -0
  275. data/sunspot_solr/solr/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  276. data/sunspot_solr/solr/solr/conf/protwords.txt +21 -0
  277. data/sunspot_solr/solr/solr/conf/schema.xml +250 -0
  278. data/sunspot_solr/solr/solr/conf/scripts.conf +24 -0
  279. data/sunspot_solr/solr/solr/conf/solrconfig.xml +934 -0
  280. data/sunspot_solr/solr/solr/conf/spellings.txt +2 -0
  281. data/sunspot_solr/solr/solr/conf/stopwords.txt +58 -0
  282. data/sunspot_solr/solr/solr/conf/synonyms.txt +31 -0
  283. data/sunspot_solr/solr/solr/conf/xslt/example.xsl +132 -0
  284. data/sunspot_solr/solr/solr/conf/xslt/example_atom.xsl +67 -0
  285. data/sunspot_solr/solr/solr/conf/xslt/example_rss.xsl +66 -0
  286. data/sunspot_solr/solr/solr/conf/xslt/luke.xsl +337 -0
  287. data/sunspot_solr/solr/start.jar +0 -0
  288. data/sunspot_solr/solr/webapps/solr.war +0 -0
  289. data/sunspot_solr/spec/server_spec.rb +98 -0
  290. data/sunspot_solr/spec/spec_helper.rb +18 -0
  291. data/sunspot_solr/sunspot_solr.gemspec +37 -0
  292. data/tools/gem_tasks.rb +69 -0
  293. metadata +356 -177
data/.gitignore CHANGED
@@ -1,7 +1,11 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ vendor/bundle
4
+ sunspot/vendor/bundle
5
+ sunspot_rails/spec/rails2/vendor
6
+ sunspot_rails/spec/rails3/vendor
7
+ **/*/vendor/bundle
1
8
  sunspot-solr.pid
2
- doc
3
- pkg/*
4
- log
5
- .bundle
6
- tmp/*
7
- gemfiles/*.lock
9
+ .yardoc
10
+ docs
11
+ *.swp
data/.travis.yml ADDED
@@ -0,0 +1,35 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ # - rbx-2.0
6
+ # - jruby
7
+
8
+ env:
9
+ - GEM=sunspot
10
+ - GEM=sunspot_rails RAILS=2.3.14
11
+ - GEM=sunspot_rails RAILS=3.0.15
12
+ - GEM=sunspot_rails RAILS=3.1.6
13
+ - GEM=sunspot_rails RAILS=3.2.6
14
+
15
+ # Limit the size of the matrix by only performing one build against
16
+ # 1.8.7 and 1.9.2
17
+ matrix:
18
+ exclude:
19
+ - rvm: 1.8.7
20
+ env: GEM=sunspot_rails RAILS=3.0.15
21
+ - rvm: 1.8.7
22
+ env: GEM=sunspot_rails RAILS=3.1.6
23
+ - rvm: 1.8.7
24
+ env: GEM=sunspot_rails RAILS=3.2.6
25
+ - rvm: 1.9.2
26
+ env: GEM=sunspot_rails RAILS=3.0.15
27
+ - rvm: 1.9.2
28
+ env: GEM=sunspot_rails RAILS=3.1.6
29
+ - rvm: 1.9.2
30
+ env: GEM=sunspot_rails RAILS=3.2.6
31
+ - rvm: 1.9.3
32
+ env: GEM=sunspot_rails RAILS=2.3.14
33
+
34
+ script:
35
+ - ci/travis.sh
data/README.md ADDED
@@ -0,0 +1,863 @@
1
+ # Sunspot
2
+
3
+ [![Build Status](https://secure.travis-ci.org/sunspot/sunspot.png)](http://travis-ci.org/sunspot/sunspot)
4
+
5
+ Sunspot is a Ruby library for expressive, powerful interaction with the Solr
6
+ search engine. Sunspot is built on top of the RSolr library, which
7
+ provides a low-level interface for Solr interaction; Sunspot provides a simple,
8
+ intuitive, expressive DSL backed by powerful features for indexing objects and
9
+ searching for them.
10
+
11
+ Sunspot is designed to be easily plugged in to any ORM, or even non-database-backed
12
+ objects such as the filesystem.
13
+
14
+ This README provides a high level overview; class-by-class and
15
+ method-by-method documentation is available in the [API
16
+ reference](http://sunspot.github.com/sunspot/docs/).
17
+
18
+ ## Quickstart with Rails 3
19
+
20
+ Add to Gemfile:
21
+
22
+ ```ruby
23
+ gem 'sunspot_rails'
24
+ gem 'sunspot_solr' # optional pre-packaged Solr distribution for use in development
25
+ ```
26
+
27
+ Bundle it!
28
+
29
+ ```bash
30
+ bundle install
31
+ ```
32
+
33
+ Generate a default configuration file:
34
+
35
+ ```bash
36
+ rails generate sunspot_rails:install
37
+ ```
38
+
39
+ If `sunspot_solr` was installed, start the packaged Solr distribution
40
+ with:
41
+
42
+ ```bash
43
+ bundle exec rake sunspot:solr:start # or sunspot:solr:run to start in foreground
44
+ ```
45
+
46
+ ## Setting Up Objects
47
+
48
+ Add a `searchable` block to the objects you wish to index.
49
+
50
+ ```ruby
51
+ class Post < ActiveRecord::Base
52
+ searchable do
53
+ text :title, :body
54
+ text :comments do
55
+ comments.map { |comment| comment.body }
56
+ end
57
+
58
+ boolean :featured
59
+ integer :blog_id
60
+ integer :author_id
61
+ integer :category_ids, :multiple => true
62
+ double :average_rating
63
+ time :published_at
64
+ time :expired_at
65
+
66
+ string :sort_title do
67
+ title.downcase.gsub(/^(an?|the)/, '')
68
+ end
69
+ end
70
+ end
71
+ ```
72
+
73
+ `text` fields will be full-text searchable. Other fields (e.g.,
74
+ `integer` and `string`) can be used to scope queries.
75
+
76
+ ## Searching Objects
77
+
78
+ ```ruby
79
+ Post.search do
80
+ fulltext 'best pizza'
81
+
82
+ with :blog_id, 1
83
+ with(:published_at).less_than Time.now
84
+ order_by :published_at, :desc
85
+ paginate :page => 2, :per_page => 15
86
+ facet :category_ids, :author_id
87
+ end
88
+ ```
89
+
90
+ ## Search In Depth
91
+
92
+ Given an object `Post` setup in earlier steps ...
93
+
94
+ ### Full Text
95
+
96
+ ```ruby
97
+ # All posts with a `text` field (:title, :body, or :comments) containing 'pizza'
98
+ Post.search { fulltext 'pizza' }
99
+
100
+ # Posts with pizza, scored higher if pizza appears in the title
101
+ Post.search do
102
+ fulltext 'pizza' do
103
+ boost_fields :title => 2.0
104
+ end
105
+ end
106
+
107
+ # Posts with pizza, scored higher if featured
108
+ Post.search do
109
+ fulltext 'pizza' do
110
+ boost(2.0) { with(:featured, true) }
111
+ end
112
+ end
113
+
114
+ # Posts with pizza *only* in the title
115
+ Post.search do
116
+ fulltext 'pizza' do
117
+ fields(:title)
118
+ end
119
+ end
120
+
121
+ # Posts with pizza in the title (boosted) or in the body (not boosted)
122
+ Post.search do
123
+ fulltext 'pizza' do
124
+ fields(:body, :title => 2.0)
125
+ end
126
+ end
127
+ ```
128
+
129
+ #### Phrases
130
+
131
+ Solr allows searching for phrases: search terms that are close together.
132
+
133
+ In the default query parser used by Sunspot (dismax), phrase searches
134
+ are represented as a double quoted group of words.
135
+
136
+ ```ruby
137
+ # Posts with the exact phrase "great pizza"
138
+ Post.search do
139
+ fulltext '"great pizza"'
140
+ end
141
+ ```
142
+
143
+ If specified, **query_phrase_slop** sets the number of words that may
144
+ appear between the words in a phrase.
145
+
146
+ ```ruby
147
+ # One word can appear between the words in the phrase, so "great big pizza"
148
+ # also matches, in addition to "great pizza"
149
+ Post.search do
150
+ fulltext '"great pizza"' do
151
+ query_phrase_slop 1
152
+ end
153
+ end
154
+ ```
155
+
156
+ ##### Phrase Boosts
157
+
158
+ Phrase boosts add boost to terms that appear in close proximity;
159
+ the terms do not *have* to appear in a phrase, but if they do, the
160
+ document will score more highly.
161
+
162
+ ```ruby
163
+ # Matches documents with great and pizza, and scores documents more
164
+ # highly if the terms appear in a phrase in the title field
165
+ Post.search do
166
+ fulltext 'great pizza' do
167
+ phrase_fields :title => 2.0
168
+ end
169
+ end
170
+
171
+ # Matches documents with great and pizza, and scores documents more
172
+ # highly if the terms appear in a phrase (or with one word between them)
173
+ # in the title field
174
+ Post.search do
175
+ fulltext 'great pizza' do
176
+ phrase_fields :title => 2.0
177
+ phrase_slop 1
178
+ end
179
+ end
180
+ ```
181
+
182
+ ### Scoping (Scalar Fields)
183
+
184
+ Fields not defined as `text` (e.g., `integer`, `boolean`, `time`,
185
+ etc...) can be used to scope (restrict) queries before full-text
186
+ matching is performed.
187
+
188
+ #### Positive Restrictions
189
+
190
+ ```ruby
191
+ # Posts with a blog_id of 1
192
+ Post.search do
193
+ with(:blog_id, 1)
194
+ end
195
+
196
+ # Posts with an average rating between 3.0 and 5.0
197
+ Post.search do
198
+ with(:average_rating, 3.0..5.0)
199
+ end
200
+
201
+ # Posts with a category of 1, 3, or 5
202
+ Post.search do
203
+ with(:category_ids, [1, 3, 5])
204
+ end
205
+
206
+ # Posts published since a week ago
207
+ Post.search do
208
+ with(:published_at).greater_than(1.week.ago)
209
+ end
210
+ ```
211
+
212
+ #### Negative Restrictions
213
+
214
+ ```ruby
215
+ # Posts not in category 1 or 3
216
+ Post.search do
217
+ without(:category_ids, [1, 3])
218
+ end
219
+
220
+ # All examples in "positive" also work negated using `without`
221
+ ```
222
+
223
+ #### Disjunctions and Conjunctions
224
+
225
+ ```ruby
226
+ # Posts that do not have an expired time or have not yet expired
227
+ Post.search do
228
+ any_of do
229
+ with(:expired_at).greater_than(Time.now)
230
+ with(:expired_at, nil)
231
+ end
232
+ end
233
+ ```
234
+
235
+ ```ruby
236
+ # Posts with blog_id 1 and author_id 2
237
+ Post.search do
238
+ all_of do
239
+ with(:blog_id, 1)
240
+ with(:author_id, 2)
241
+ end
242
+ end
243
+ ```
244
+
245
+ Disjunctions and conjunctions may be nested
246
+
247
+ ```ruby
248
+ Post.search do
249
+ any_of do
250
+ with(:blog_id, 1)
251
+ all_of do
252
+ with(:blog_id, 2)
253
+ with(:category_ids, 3)
254
+ end
255
+ end
256
+ end
257
+ ```
258
+
259
+ #### Combined with Full-Text
260
+
261
+ Scopes/restrictions can be combined with full-text searching. The
262
+ scope/restriction pares down the objects that are searched for the
263
+ full-text term.
264
+
265
+ ```ruby
266
+ # Posts with blog_id 1 and 'pizza' in the title
267
+ Post.search do
268
+ with(:blog_id, 1)
269
+ fulltext("pizza")
270
+ end
271
+ ```
272
+
273
+ ### Pagination
274
+
275
+ **All results from Solr are paginated**
276
+
277
+ The results array that is returned has methods mixed in that allow it to
278
+ operate seamlessly with common pagination libraries like will\_paginate
279
+ and kaminari.
280
+
281
+ By default, Sunspot requests the first 30 results from Solr.
282
+
283
+ ```ruby
284
+ search = Post.search do
285
+ fulltext "pizza"
286
+ end
287
+
288
+ # Imagine there are 60 *total* results (at 30 results/page, that is two pages)
289
+ results = search.results # => Array with 30 Post elements
290
+
291
+ search.total # => 60
292
+
293
+ results.total_pages # => 2
294
+ results.first_page? # => true
295
+ results.last_page? # => false
296
+ results.previous_page # => nil
297
+ results.next_page # => 2
298
+ results.out_of_bounds? # => false
299
+ results.offset # => 0
300
+ ```
301
+
302
+ To retrieve the next page of results, recreate the search and use the
303
+ `paginate` method.
304
+
305
+ ```ruby
306
+ search = Post.search do
307
+ fulltext "pizza"
308
+ paginate :page => 2
309
+ end
310
+
311
+ # Again, imagine there are 60 total results; this is the second page
312
+ results = search.results # => Array with 30 Post elements
313
+
314
+ search.total # => 60
315
+
316
+ results.total_pages # => 2
317
+ results.first_page? # => false
318
+ results.last_page? # => true
319
+ results.previous_page # => 1
320
+ results.next_page # => nil
321
+ results.out_of_bounds? # => false
322
+ results.offset # => 30
323
+ ```
324
+
325
+ A custom number of results per page can be specified with the
326
+ `:per_page` option to `paginate`:
327
+
328
+ ```ruby
329
+ search = Post.search do
330
+ fulltext "pizza"
331
+ paginate :page => 1, :per_page => 50
332
+ end
333
+ ```
334
+
335
+ ### Faceting
336
+
337
+ Faceting is a feature of Solr that determines the number of documents
338
+ that match a given search *and* an additional criterion. This allows you
339
+ to build powerful drill-down interfaces for search.
340
+
341
+ Each facet returns zero or more rows, each of which represents a
342
+ particular criterion conjoined with the actual query being performed.
343
+ For **field facets**, each row represents a particular value for a given
344
+ field. For **query facets**, each row represents an arbitrary scope; the
345
+ facet itself is just a means of logically grouping the scopes.
346
+
347
+ #### Field Facets
348
+
349
+ ```ruby
350
+ # Posts that match 'pizza' returning counts for each :author_id
351
+ search = Post.search do
352
+ fulltext "pizza"
353
+ facet :author_id
354
+ end
355
+
356
+ search.facet(:author_id).rows.each do |facet|
357
+ puts "Author #{facet.value} has #{facet.count} pizza posts!"
358
+ end
359
+ ```
360
+
361
+ #### Query Facets
362
+
363
+ ```ruby
364
+ # Posts faceted by ranges of average ratings
365
+ search = Post.search do
366
+ facet(:average_rating) do
367
+ row(1.0..2.0) do
368
+ with(:average_rating, 1.0..2.0)
369
+ end
370
+ row(2.0..3.0) do
371
+ with(:average_rating, 2.0..3.0)
372
+ end
373
+ row(3.0..4.0) do
374
+ with(:average_rating, 3.0..4.0)
375
+ end
376
+ row(4.0..5.0) do
377
+ with(:average_rating, 4.0..5.0)
378
+ end
379
+ end
380
+ end
381
+
382
+ # e.g.,
383
+ # Number of posts with rating withing 1.0..2.0: 2
384
+ # Number of posts with rating withing 2.0..3.0: 1
385
+ search.facet(:average_rating).rows.each do |facet|
386
+ puts "Number of posts with rating withing #{facet.value}: #{facet.count}"
387
+ end
388
+ ```
389
+
390
+ #### Range Facets
391
+
392
+ ```ruby
393
+ # Posts faceted by range of average ratings
394
+ Sunspot.search(Post) do
395
+ facet :average_rating, :range => 1..5, :range_interval => 1
396
+ end
397
+ ```
398
+
399
+ ### Ordering
400
+
401
+ By default, Sunspot orders results by "score": the Solr-determined
402
+ relevancy metric. Sorting can be customized with the `order_by` method:
403
+
404
+ ```ruby
405
+ # Order by average rating, descending
406
+ Post.search do
407
+ fulltext("pizza")
408
+ order_by(:average_rating, :desc)
409
+ end
410
+
411
+ # Order by relevancy score and in the case of a tie, average rating
412
+ Post.search do
413
+ fulltext("pizza")
414
+
415
+ order_by(:score, :desc)
416
+ order_by(:average_rating, :desc)
417
+ end
418
+
419
+ # Randomized ordering
420
+ Post.search do
421
+ fulltext("pizza")
422
+ order_by(:random)
423
+ end
424
+ ```
425
+
426
+ ### Grouping
427
+
428
+ **Solr 3.3 and above**
429
+
430
+ Solr supports grouping documents, similar to an SQL `GROUP BY`. More
431
+ information about result grouping/field collapsing is available on the
432
+ [Solr Wiki](http://wiki.apache.org/solr/FieldCollapsing).
433
+
434
+ **Grouping is only supported on `string` fields that are not
435
+ multivalued. To group on a field of a different type (e.g., integer),
436
+ add a denormalized `string` type**
437
+
438
+ ```ruby
439
+ class Post < ActiveRecord::Base
440
+ searchable do
441
+ # Denormalized `string` field because grouping can only be performed
442
+ # on string fields
443
+ string(:blog_id_str) { |p| p.blog_id.to_s }
444
+ end
445
+ end
446
+
447
+ # Returns only the top scoring document per blog_id
448
+ search = Post.search do
449
+ group :blog_id_str
450
+ end
451
+
452
+ search.group(:blog_id_str).matches # Total number of matches to the query
453
+
454
+ search.group(:blog_id_str).groups.each do |group|
455
+ puts group.value # blog_id of the each document in the group
456
+
457
+ # By default, there is only one document per group (the highest
458
+ # scoring one); if `limit` is specified (see below), multiple
459
+ # documents can be returned per group
460
+ group.results.each do |result|
461
+ # ...
462
+ end
463
+ end
464
+ ```
465
+
466
+ Additional options are supported by the DSL:
467
+
468
+ ```ruby
469
+ # Returns the top 3 scoring documents per blog_id
470
+ Post.search do
471
+ group :blog_id_str do
472
+ limit 3
473
+ end
474
+ end
475
+
476
+ # Returns document ordered within each group by published_at (by
477
+ # default, the ordering is score)
478
+ Post.search do
479
+ group :blog_id_str do
480
+ order_by(:average_rating, :desc)
481
+ end
482
+ end
483
+
484
+ # Facet count is based on the most relevant document of each group
485
+ # matching the query (>= Solr 3.4)
486
+ Post.search do
487
+ group :blog_id_str do
488
+ truncate
489
+ end
490
+
491
+ facet :blog_id_str, :extra => :any
492
+ end
493
+ ```
494
+
495
+ ### Geospatial
496
+
497
+ **Experimental and unreleased. The DSL may change.**
498
+
499
+ Sunspot 2.0 supports geospatial features of Solr 3.1 and above.
500
+
501
+ Geospatial features require a field defined with `latlon`:
502
+
503
+ ```ruby
504
+ class Post < ActiveRecord::Base
505
+ searchable do
506
+ # ...
507
+ latlon(:location) { Sunspot::Util::Coordinates.new(lat, lon) }
508
+ end
509
+ end
510
+ ```
511
+
512
+ #### Filter By Radius
513
+
514
+ ```ruby
515
+ # Searches posts within 100 kilometers of (32, -68)
516
+ Post.search do
517
+ with(:location).in_radius(32, -68, 100)
518
+ end
519
+ ```
520
+
521
+ #### Filter By Radius (inexact with bbox)
522
+
523
+ ```ruby
524
+ # Searches posts within 100 kilometers of (32, -68) with `bbox`. This is
525
+ # an approximation so searches run quicker, but it may include other
526
+ # points that are slightly outside of the required distance
527
+ Post.search do
528
+ with(:location).in_radius(32, -68, 100, :bbox => true)
529
+ end
530
+ ```
531
+
532
+ #### Filter By Bounding Box
533
+
534
+ ```ruby
535
+ # Searches posts within the bounding box defined by the corners (45,
536
+ # -94) to (46, -93)
537
+ Post.search do
538
+ with(:location).in_bounding_box([45, -94], [46, -93])
539
+ end
540
+ ```
541
+
542
+ #### Sort By Distance
543
+
544
+ ```ruby
545
+ # Orders documents by closeness to (32, -68)
546
+ Post.search do
547
+ order_by_geodist(:location, 32, -68)
548
+ end
549
+ ```
550
+
551
+ ### Highlighting
552
+
553
+ Highlighting allows you to display snippets of the part of the document
554
+ that matched the query.
555
+
556
+ The fields you wish to highlight must be **stored**.
557
+
558
+ ```ruby
559
+ class Post < ActiveRecord::Base
560
+ searchable do
561
+ # ...
562
+ text :body, :stored => true
563
+ end
564
+ end
565
+ ```
566
+
567
+ Highlighting matches on the `body` field, for instance, can be acheived
568
+ like:
569
+
570
+ ```ruby
571
+ search = Post.search do
572
+ fulltext "pizza" do
573
+ highlight :body
574
+ end
575
+ end
576
+
577
+ # Will output something similar to:
578
+ # Post #1
579
+ # I really love *pizza*
580
+ # *Pizza* is my favorite thing
581
+ # Post #2
582
+ # Pepperoni *pizza* is delicious
583
+ search.hits.each do |hit|
584
+ puts "Post ##{hit.primary_key}"
585
+
586
+ hit.highlights(:body).each do |highlight|
587
+ puts " " + highlight.format { |word| "*#{word}*" }
588
+ end
589
+ end
590
+ ```
591
+
592
+ ### Functions
593
+
594
+ TODO
595
+
596
+ ### More Like This
597
+
598
+ Sunspot can extract related items using more_like_this. When searching
599
+ for similar items, you can pass a block with the following options:
600
+
601
+ * fields :field_1[, :field_2, ...]
602
+ * minimum_term_frequency ##
603
+ * minimum_document_frequency ##
604
+ * minimum_word_length ##
605
+ * maximum_word_length ##
606
+ * maximum_query_terms ##
607
+ * boost_by_relevance true/false
608
+
609
+ ```ruby
610
+ class Post < ActiveRecord::Base
611
+ searchable do
612
+ # The :more_like_this option must be set to true
613
+ text :body, :more_like_this => true
614
+ end
615
+ end
616
+
617
+ post = Post.first
618
+
619
+ results = Sunspot.more_like_this(post) do
620
+ fields :body
621
+ minimum_term_frequency 5
622
+ end
623
+ ```
624
+
625
+ ## Indexing In Depth
626
+
627
+ TODO
628
+
629
+ ### Index-Time Boosts
630
+
631
+ To specify that a field should be boosted in relation to other fields for
632
+ all queries, you can specify the boost at index time:
633
+
634
+ ```ruby
635
+ class Post < ActiveRecord::Base
636
+ searchable do
637
+ text :title, :boost => 5.0
638
+ text :body
639
+ end
640
+ end
641
+ ```
642
+
643
+ ### Stored Fields
644
+
645
+ Stored fields keep an original (untokenized/unanalyzed) version of their
646
+ contents in Solr.
647
+
648
+ Stored fields allow data to be retrieved without also hitting the
649
+ underlying database (usually an SQL server). They are also required for
650
+ highlighting and more like this queries.
651
+
652
+ Stored fields come at some performance cost in the Solr index, so use
653
+ them wisely.
654
+
655
+ ```ruby
656
+ class Post < ActiveRecord::Base
657
+ searchable do
658
+ text :body, :stored => true
659
+ end
660
+ end
661
+
662
+ # Retrieving stored contents without hitting the database
663
+ Post.search.hits.each do |hit|
664
+ puts hit.stored(:body)
665
+ end
666
+ ```
667
+
668
+ ## Hits vs. Results
669
+
670
+ Sunspot simply stores the type and primary key of objects in Solr.
671
+ When results are retrieved, those primary keys are used to load the
672
+ actual object (usually from an SQL database).
673
+
674
+ ```ruby
675
+ # Using #results pulls in the records from the object-relational
676
+ # mapper (e.g., ActiveRecord + a SQL server)
677
+ Post.search.results.each do |result|
678
+ puts result.body
679
+ end
680
+ ```
681
+
682
+ To access information about the results without querying the underlying
683
+ database, use `hits`:
684
+
685
+ ```ruby
686
+ # Using #hits gives back all information requested from Solr, but does
687
+ # not load the object from the object-relational mapper
688
+ Post.search.hits.each do |hit|
689
+ puts hit.stored(:body)
690
+ end
691
+ ```
692
+
693
+ If you need both the result (ORM-loaded object) and `Hit` (e.g., for
694
+ faceting, highlighting, etc...), you can use the convenience method
695
+ `each_hit_with_result`:
696
+
697
+ ```ruby
698
+ Post.search.each_hit_with_result do |hit, result|
699
+ # ...
700
+ end
701
+ ```
702
+
703
+ ## Reindexing Objects
704
+
705
+ If you are using Rails, objects are automatically indexed to Solr as a
706
+ part of the `save` callbacks.
707
+
708
+ If you make a change to the object's "schema" (code in the `searchable` block),
709
+ you must reindex all objects so the changes are reflected in Solr:
710
+
711
+ ```bash
712
+ bundle exec rake sunspot:solr:reindex
713
+
714
+ # or, to be specific to a certain model with a certain batch size:
715
+ bundle exec rake sunspot:solr:reindex[500,Post] # some shells will require escaping [ with \[ and ] with \]
716
+ ```
717
+
718
+ ## Use Without Rails
719
+
720
+ TODO
721
+
722
+ ## Manually Adjusting Solr Parameters
723
+
724
+ To add or modify parameters sent to Solr, use `adjust_solr_params`:
725
+
726
+ ```ruby
727
+ Post.search do
728
+ adjust_solr_params do |params|
729
+ params[:q] += " AND something_s:more"
730
+ end
731
+ end
732
+ ```
733
+
734
+ ## Session Proxies
735
+
736
+ TODO
737
+
738
+ ## Type Reference
739
+
740
+ TODO
741
+
742
+ ## Development
743
+
744
+ ### Running Tests
745
+
746
+ #### sunspot
747
+
748
+ Install the required gem dependencies:
749
+
750
+ ```bash
751
+ cd /path/to/sunspot/sunspot
752
+ bundle install
753
+ ```
754
+
755
+ Start a Solr instance on port 8983:
756
+
757
+ ```bash
758
+ bundle exec sunspot-solr start -p 8983
759
+ # or `bundle exec sunspot-solr run -p 8983` to run in foreground
760
+ ```
761
+
762
+ Run the tests:
763
+
764
+ ```bash
765
+ bundle exec rake spec
766
+ ```
767
+
768
+ If desired, stop the Solr instance:
769
+
770
+ ```bash
771
+ bundle exec sunspot-solr stop
772
+ ```
773
+
774
+ #### sunspot\_rails
775
+
776
+ Install the gem dependencies for `sunspot`:
777
+
778
+ ```bash
779
+ cd /path/to/sunspot/sunspot
780
+ bundle install
781
+ ```
782
+
783
+ Start a Solr instance on port 8983:
784
+
785
+ ```bash
786
+ bundle exec sunspot-solr start -p 8983
787
+ # or `bundle exec sunspot-solr run -p 8983` to run in foreground
788
+ ```
789
+
790
+ Navigate to the `sunspot_rails` directory:
791
+
792
+ ```bash
793
+ cd ../sunspot_rails
794
+ ```
795
+
796
+ Run the tests:
797
+
798
+ ```bash
799
+ rake spec # all Rails versions
800
+ rake spec RAILS=3.1.1 # specific Rails version only
801
+ ```
802
+
803
+ If desired, stop the Solr instance:
804
+
805
+ ```bash
806
+ cd ../sunspot
807
+ bundle exec sunspot-solr stop
808
+ ```
809
+
810
+ ### Generating Documentation
811
+
812
+ Install the `yard` and `redcarpet` gems:
813
+
814
+ ```bash
815
+ $ gem install yard redcarpet
816
+ ```
817
+
818
+ Uninstall the `rdiscount` gem, if installed:
819
+
820
+ ```bash
821
+ $ gem uninstall rdiscount
822
+ ```
823
+
824
+ Generate the documentation from topmost directory:
825
+
826
+ ```bash
827
+ $ yardoc -o docs */lib/**/*.rb - README.md
828
+ ```
829
+
830
+ ## Tutorials and Articles
831
+
832
+ * [Using Sunspot, Websolr, and Solr on Heroku](http://mrdanadams.com/2012/sunspot-websolr-solr-heroku/) (mrdanadams)
833
+ * [Full Text Searching with Solr and Sunspot](http://collectiveidea.com/blog/archives/2011/03/08/full-text-searching-with-solr-and-sunspot/) (Collective Idea)
834
+ * [Full-text search in Rails with Sunspot](http://tech.favoritemedium.com/2010/01/full-text-search-in-rails-with-sunspot.html) (Tropical Software Observations)
835
+ * [Sunspot Full-text Search for Rails/Ruby](http://therailworld.com/posts/23-Sunspot-Full-text-Search-for-Rails-Ruby) (The Rail World)
836
+ * [A Few Sunspot Tips](http://blog.trydionel.com/2009/11/19/a-few-sunspot-tips/) (spiral_code)
837
+ * [Sunspot: A Solr-Powered Search Engine for Ruby](http://www.linux-mag.com/id/7341) (Linux Magazine)
838
+ * [Sunspot Showed Me the Light](http://bennyfreshness.com/2010/05/sunspot-helped-me-see-the-light/) (ben koonse)
839
+ * [RubyGems.org — A case study in upgrading to full-text search](http://blog.websolr.com/post/3505903537/rubygems-search-upgrade-1) (Websolr)
840
+ * [How to Implement Spatial Search with Sunspot and Solr](http://codequest.eu/articles/how-to-implement-spatial-search-with-sunspot-and-solr) (Code Quest)
841
+ * [Sunspot 1.2 with Spatial Solr Plugin 2.0](http://joelmats.wordpress.com/2011/02/23/getting-sunspot-1-2-with-spatial-solr-plugin-2-0-to-work/) (joelmats)
842
+ * [rails3 + heroku + sunspot : madness](http://anhaminha.tumblr.com/post/632682537/rails3-heroku-sunspot-madness) (anhaminha)
843
+ * [How to get full text search working with Sunspot](http://cookbook.hobocentral.net/recipes/57-how-to-get-full-text-search) (Hobo Cookbook)
844
+ * [Full text search with Sunspot in Rails](http://hemju.com/2011/01/04/full-text-search-with-sunspot-in-rail/) (hemju)
845
+ * [Using Sunspot for Free-Text Search with Redis](http://masonoise.wordpress.com/2010/02/06/using-sunspot-for-free-text-search-with-redis/) (While I Pondered...)
846
+ * [Fuzzy searching in SOLR with Sunspot](http://www.pipetodevnull.com/past/2010/8/5/fuzzy_searching_in_solr_with_sunspot/) (pipe :to => /dev/null)
847
+ * [Default scope with Sunspot](http://www.cloudspace.com/blog/2010/01/15/default-scope-with-sunspot/) (Cloudspace)
848
+ * [Index External Models with Sunspot/Solr](http://www.medihack.org/2011/03/19/index-external-models-with-sunspotsolr/) (Medihack)
849
+ * [Chef recipe for Sunspot in production](http://gist.github.com/336403)
850
+ * [Testing with Sunspot and Cucumber](http://collectiveidea.com/blog/archives/2011/05/25/testing-with-sunspot-and-cucumber/) (Collective Idea)
851
+ * [Cucumber and Sunspot](http://opensoul.org/2010/4/7/cucumber-and-sunspot) (opensoul.org)
852
+ * [Testing Sunspot with Cucumber](http://blog.trydionel.com/2010/02/06/testing-sunspot-with-cucumber/) (spiral_code)
853
+ * [Running cucumber features with sunspot_rails](http://blog.kabisa.nl/2010/02/03/running-cucumber-features-with-sunspot_rails) (Kabisa Blog)
854
+ * [Testing Sunspot with Test::Unit](http://timcowlishaw.co.uk/post/3179661158/testing-sunspot-with-test-unit) (Type Slowly)
855
+ * [How To Use Twitter Lists to Determine Influence](http://www.untitledstartup.com/2010/01/how-to-use-twitter-lists-to-determine-influence/) (Untitled Startup)
856
+ * [Sunspot Quickstart](http://wiki.websolr.com/index.php/Sunspot_Quickstart) (WebSolr)
857
+ * [Solr, and Sunspot](http://www.kuahyeow.com/2009/08/solr-and-sunspot.html) (YT!)
858
+ * [The Saga of the Switch](http://mrb.github.com/2010/04/08/the-saga-of-the-switch.html) (mrb -- includes comparison of Sunspot and Ultrasphinx)
859
+ * [Conditional Indexing with Sunspot](http://mikepackdev.com/blog_posts/19-conditional-indexing-with-sunspot) (mikepack)
860
+
861
+ ## License
862
+
863
+ Sunspot is distributed under the MIT License, copyright (c) 2008-2009 Mat Brown