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
@@ -0,0 +1,32 @@
1
+ module Sunspot
2
+ module DSL #:nodoc
3
+ module Paginatable
4
+ # Paginate your search. This works the same way as WillPaginate's
5
+ # paginate().
6
+ #
7
+ # Note that Solr searches are _always_ paginated. Not calling #paginate is
8
+ # the equivalent of calling:
9
+ #
10
+ # paginate(:page => 1, :per_page => Sunspot.config.pagination.default_per_page)
11
+ #
12
+ # ==== Options (options)
13
+ #
14
+ # :page<Integer,String>:: The requested page. The default is 1.
15
+ #
16
+ # :per_page<Integer,String>::
17
+ # How many results to return per page. The default is the value in
18
+ # +Sunspot.config.pagination.default_per_page+
19
+ #
20
+ # :offset<Integer,String>::
21
+ # Applies a shift to paginated records. The default is 0.
22
+ #
23
+ def paginate(options = {})
24
+ page = options.delete(:page)
25
+ per_page = options.delete(:per_page)
26
+ offset = options.delete(:offset)
27
+ raise ArgumentError, "unknown argument #{options.keys.first.inspect} passed to paginate" unless options.empty?
28
+ @query.paginate(page, per_page, offset)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,36 @@
1
+ module Sunspot
2
+ module DSL
3
+ #
4
+ # This tiny DSL class implements the DSL for the FieldQuery.facet
5
+ # method.
6
+ #
7
+ class QueryFacet
8
+ def initialize(query, setup, facet, options) #:nodoc:
9
+ @query, @setup, @facet, @options = query, setup, facet, options
10
+ end
11
+
12
+ #
13
+ # Add a row to this query facet. The label argument can be anything; it's
14
+ # simply the value that's passed into the Sunspot::QueryFacetRow object
15
+ # corresponding to the row that's created. Use whatever seems most
16
+ # intuitive.
17
+ #
18
+ # The block is evaluated in the context of a Sunspot::DSL::Scope, meaning
19
+ # any restrictions can be placed on the documents matching this facet row.
20
+ #
21
+ # ==== Parameters
22
+ #
23
+ # label<Object>::
24
+ # An object used to identify this facet row in the results.
25
+ #
26
+ def row(label, &block)
27
+ query_facet = Sunspot::Query::QueryFacet.new(@options)
28
+ Sunspot::Util.instance_eval_or_call(
29
+ Scope.new(@query.add_query_facet(query_facet), @setup),
30
+ &block
31
+ )
32
+ @facet.add_row(label, query_facet.to_boolean_phrase)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ module Sunspot
2
+ module DSL
3
+ #
4
+ # This class presents an API for building restrictions in the query DSL. The
5
+ # methods exposed are the snake-cased names of the classes defined in the
6
+ # Sunspot::Restriction module, with the exception of Base. All
7
+ # methods take a single argument, which is the value to be applied to the
8
+ # restriction.
9
+ #
10
+ class Restriction
11
+ def initialize(field, scope, negative) #:nodoc:
12
+ @field, @scope, @negative = field, scope, negative
13
+ end
14
+
15
+ Sunspot::Query::Restriction.names.each do |class_name|
16
+ method_name = Util.snake_case(class_name.to_s)
17
+ module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
18
+ def #{method_name}(*value)
19
+ @scope.add_restriction(@negative, @field, Sunspot::Query::Restriction::#{class_name}, *value)
20
+ end
21
+ RUBY
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,160 @@
1
+ module Sunspot
2
+ module DSL
3
+ class RestrictionWithNear < Restriction
4
+ def initialize(field, scope, query, negated)
5
+ super(field, scope, negated)
6
+ @query = query
7
+ end
8
+
9
+ #
10
+ # Perform a Geohash-based location restriction for the given `location`
11
+ # field. Though this uses the same API as other attribute-field
12
+ # restrictions, there are several differences between this and other
13
+ # scoping methods:
14
+ #
15
+ # * It can only be called from the top-level query; it cannot be nested
16
+ # in a `dynamic`, `any_of`, or `all_of` block. This is because geohash
17
+ # queries are not sent to Solr as filter queries like other scopes, but
18
+ # rather are part of the fulltext query sent to Solr.
19
+ # * Because it is included with the fulltext query (if any), location
20
+ # restrictions can be given boost. By default, an "exact"
21
+ # (maximum-precision) match will give the result a boost of 1.0; each
22
+ # lower level of precision gives a boost of 1/2 the next highest
23
+ # precision. See below for options to modify this behavior.
24
+ #
25
+ # ==== What is a Geohash?
26
+ #
27
+ # Geohash is a clever algorithm that creates a decodable digest of a
28
+ # geographical point. It does this by dividing the globe into
29
+ # quadrants, encoding the quadrant in which the point sits in the hash,
30
+ # dividing the quadrant into smaller quadrants, and repeating an arbitrary
31
+ # number of times (the "precision"). Because of the way Geohash are
32
+ # built, the shared Geohash prefix length of two locations will
33
+ # <em>usually</em> increase as the distance between the points decreases.
34
+ # Put another way, the geohashes of two nearby points will
35
+ # <em>usually</em> have a longer shared prefix than two points which are
36
+ # distant from one another.
37
+ #
38
+ # Read more about Geohashes on
39
+ # {Wikipedia}[http://en.wikipedia.org/wiki/Geohash] or play around with
40
+ # generating your own at {geohash.org}[http://geohash.org/].
41
+ #
42
+ # In Sunspot, GeoHashes can have a precision between 3 and 12; this is the
43
+ # number of characters in the hash. The precisions have the following
44
+ # maximum bounding box sizes, in miles:
45
+ #
46
+ # <dt>3</dt>
47
+ # <dd>389.07812</dd>
48
+ # <dt>4</dt>
49
+ # <dd>97.26953</dd>
50
+ # <dt>5</dt>
51
+ # <dd>24.31738</dd>
52
+ # <dt>6</dt>
53
+ # <dd>6.07935</dd>
54
+ # <dt>7</dt>
55
+ # <dd>1.51984
56
+ # <dt>8</dt>
57
+ # <dd>0.37996</dd>
58
+ # <dt>9</dt>
59
+ # <dd>0.09499</dd>
60
+ # <dt>10</dt>
61
+ # <dd>0.02375</dd>
62
+ # <dt>11</dt>
63
+ # <dd>0.00594</dd>
64
+ # <dt>12</dt>
65
+ # <dd>0.00148</dd>
66
+ #
67
+ # ==== Score, boost, and sorting with location search
68
+ #
69
+ # The concept of relevance scoring is a familiar one from fulltext search;
70
+ # Solr (or Lucene, actually) gives each result document a score based on
71
+ # how relevant the document's text is to the search phrase. Sunspot's
72
+ # location search also uses scoring to determine geographical relevance;
73
+ # using boosts, longer prefix matches (which are, in general,
74
+ # geographically closer to the search origin) are assigned higher
75
+ # relevance. This means that the results of a pure location search are
76
+ # <em>roughly</em> in order of geographical distance, as long as no other
77
+ # sort is specified explicitly.
78
+ #
79
+ # This geographical relevance plays on the same field as fulltext scoring;
80
+ # if you use both fulltext and geographical components in a single search,
81
+ # both types of relevance will be taken into account when scoring the
82
+ # matches. Thus, a very close fulltext match that's further away from the
83
+ # geographical origin will be scored similarly to a less precise fulltext
84
+ # match that is very close to the geographical origin. That's likely to be
85
+ # consistent with the way most users would expect a fulltext geographical
86
+ # search to work.
87
+ #
88
+ # ==== Options
89
+ #
90
+ # <dt><code>:precision</code></dt>
91
+ # <dd>The minimum precision at which locations should match. See the table
92
+ # of precisions and bounding-box sizes above; the proximity value will
93
+ # ensure that all matching documents share a bounding box of the
94
+ # corresponding maximum size with your origin point. The default value
95
+ # is 7, meaning all results will share a bounding box with edges of
96
+ # about one and a half miles with the origin.</dd>
97
+ # <dt><code>:boost</code></dt>
98
+ # <dd>The boost to apply to maximum-precision matches. Default is 1.0. You
99
+ # can use this option to adjust the weight given to geographic
100
+ # proximity versus fulltext matching, if you are doing both in a
101
+ # search.</dd>
102
+ # <dt><code>:precision_factor</code></dt>
103
+ # <dd>This option determines how much boost is applied to matches at lower
104
+ # precisions. The default value, 16.0, means that a match at precision
105
+ # N is 1/16 as relevant as a match at precision N+1 (this is consistent
106
+ # with the fact that each precision's bounding box is about sixteen
107
+ # times the size of the next highest precision.)</dd>
108
+ #
109
+ # ==== Example
110
+ #
111
+ # Sunspot.search(Post) do
112
+ # fulltext('pizza')
113
+ # with(:location).near(-40.0, -70.0, :boost => 2, :precision => 6)
114
+ # end
115
+ #
116
+ def near(lat, lng, options = {})
117
+ @query.fulltext.add_location(@field, lat, lng, options)
118
+ end
119
+
120
+ #
121
+ # Performs a query that is filtered by a radius around a given
122
+ # latitude and longitude.
123
+ #
124
+ # ==== Parameters
125
+ #
126
+ # :lat<Numeric>::
127
+ # Latitude (in degrees)
128
+ # :lon<Numeric>::
129
+ # Longitude (in degrees)
130
+ # :radius<Numeric>::
131
+ # Radius (in kilometers)
132
+ #
133
+ # ==== Options
134
+ #
135
+ # <dt><code>:bbox</code></dt>
136
+ # <dd>If `true`, performs the search using `bbox`. `bbox` is
137
+ # more performant, but also more inexact (guaranteed to encompass
138
+ # all of the points of interest, but may also include other points
139
+ # that are slightly outside of the required distance).</dd>
140
+ #
141
+ def in_radius(lat, lon, radius, options = {})
142
+ @query.add_geo(Sunspot::Query::Geofilt.new(@field, lat, lon, radius, options))
143
+ end
144
+
145
+ #
146
+ # Performs a query that is filtered by a bounding box
147
+ #
148
+ # ==== Parameters
149
+ #
150
+ # :first_corner<Array>::
151
+ # First corner (expressed as an array `[latitude, longitude]`)
152
+ # :second_corner<Array>::
153
+ # Second corner (expressed as an array `[latitude, longitude]`)
154
+ #
155
+ def in_bounding_box(first_corner, second_corner)
156
+ @query.add_geo(Sunspot::Query::Bbox.new(@field, first_corner, second_corner))
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,214 @@
1
+ module Sunspot
2
+ module DSL #:nodoc:
3
+ #
4
+ # This DSL presents methods for constructing restrictions and other query
5
+ # elements that are specific to fields. As well as being a superclass of
6
+ # Sunspot::DSL::StandardQuery, which presents the main query block, this
7
+ # DSL class is also used directly inside the #dynamic() block, which only
8
+ # allows operations on specific fields.
9
+ #
10
+ class Scope
11
+ def initialize(scope, setup) #:nodoc:
12
+ @scope, @setup = scope, setup
13
+ end
14
+
15
+ #
16
+ # Build a positive restriction. This method can take three forms: equality
17
+ # restriction, restriction by another restriction, or identity
18
+ # restriction.
19
+ # In the first two forms, the first argument is a field name. If only a
20
+ # field name is specified, this method returns another DSL object which
21
+ # presents methods for attaching various restriction types.
22
+ # With two arguments, this creates a shorthand restriction: if the second
23
+ # argument is a scalar, an equality restriction is created; if it is a
24
+ # Range, a between restriction will be created; and if it is an Array, an
25
+ # any_of restriction will be created.
26
+ # The third from restricts the search results to a specific instance.
27
+ #
28
+ # ==== Parameters (restriction by field value)
29
+ #
30
+ # field_name<Symbol>:: Name of the field on which to place the restriction
31
+ # value<Object,Range,Array>::
32
+ # If passed, creates an equality, range, or any-of restriction based on
33
+ # the type of value passed.
34
+ #
35
+ # ==== Parameters (restriction by identity)
36
+ #
37
+ # args<Object>...::
38
+ # One or more instances that should be included in the results
39
+ #
40
+ # ==== Returns
41
+ #
42
+ # Sunspot::DSL::Restriction::
43
+ # Restriction DSL object (if only one argument is passed which is a
44
+ # field name)
45
+ #
46
+ # ==== Examples
47
+ #
48
+ # An equality restriction:
49
+ #
50
+ # Sunspot.search do
51
+ # with(:blog_id, 1)
52
+ # end
53
+ #
54
+ # Restrict by range:
55
+ #
56
+ # Sunspot.search do
57
+ # with(:average_rating, 3.0..5.0)
58
+ # end
59
+ #
60
+ # Restrict by a set of allowed values:
61
+ #
62
+ # Sunspot.search do
63
+ # with(:category_ids, [1, 5, 9])
64
+ # end
65
+ #
66
+ # Other restriction types:
67
+ #
68
+ # Sunspot.search(Post) do
69
+ # with(:average_rating).greater_than(3.0)
70
+ # end
71
+ #
72
+ # Restriction by identity:
73
+ #
74
+ # Sunspot.search(Post) do
75
+ # with(some_post_instance)
76
+ # end
77
+ #
78
+ def with(*args)
79
+ add_restriction(false, *args)
80
+ end
81
+
82
+ #
83
+ # Build a negative restriction (exclusion). This method works the same way
84
+ # asthe #with method.
85
+ #
86
+ def without(*args)
87
+ add_restriction(true, *args)
88
+ end
89
+
90
+ #
91
+ # Create a disjunction, scoping the results to documents that match any
92
+ # of the enclosed restrictions.
93
+ #
94
+ # ==== Example
95
+ #
96
+ # Sunspot.search(Post) do
97
+ # any_of do
98
+ # with(:expired_at).greater_than Time.now
99
+ # with :expired_at, nil
100
+ # end
101
+ # end
102
+ #
103
+ # This will return all documents who either have an expiration time in the
104
+ # future, or who do not have any expiration time at all.
105
+ #
106
+ def any_of(&block)
107
+ disjunction = @scope.add_disjunction
108
+ Util.instance_eval_or_call(Scope.new(disjunction, @setup), &block)
109
+ disjunction
110
+ end
111
+
112
+ #
113
+ # Create a conjunction, scoping the results to documents that match all of
114
+ # the enclosed restrictions. When called from the top level of a search
115
+ # block, this has no effect, but can be useful for grouping a conjunction
116
+ # inside a disjunction.
117
+ #
118
+ # ==== Example
119
+ #
120
+ # Sunspot.search(Post) do
121
+ # any_of do
122
+ # with(:blog_id, 1)
123
+ # all_of do
124
+ # with(:blog_id, 2)
125
+ # with(:category_ids, 3)
126
+ # end
127
+ # end
128
+ # end
129
+ #
130
+ def all_of(&block)
131
+ conjunction = @scope.add_conjunction
132
+ Util.instance_eval_or_call(Scope.new(conjunction, @setup), &block)
133
+ conjunction
134
+ end
135
+
136
+ #
137
+ # Apply restrictions, facets, and ordering to dynamic field instances.
138
+ # The block API is implemented by Sunspot::DSL::FieldQuery, which is a
139
+ # superclass of the Query DSL (thus providing a subset of the API, in
140
+ # particular only methods that refer to particular fields).
141
+ #
142
+ # ==== Parameters
143
+ #
144
+ # base_name<Symbol>:: The base name for the dynamic field definition
145
+ #
146
+ # ==== Example
147
+ #
148
+ # Sunspot.search Post do
149
+ # dynamic :custom do
150
+ # with :cuisine, 'Pizza'
151
+ # facet :atmosphere
152
+ # order_by :chef_name
153
+ # end
154
+ # end
155
+ #
156
+ def dynamic(base_name, &block)
157
+ Sunspot::Util.instance_eval_or_call(
158
+ Scope.new(@scope, @setup.dynamic_field_factory(base_name)),
159
+ &block
160
+ )
161
+ end
162
+
163
+ #
164
+ # Apply scope-type restrictions on fulltext fields. In certain situations,
165
+ # it may be desirable to place logical restrictions on text fields.
166
+ # Remember that text fields are tokenized; your mileage may very.
167
+ #
168
+ # The block works exactly like a normal scope, except that the field names
169
+ # refer to text fields instead of attribute fields.
170
+ #
171
+ # === Example
172
+ #
173
+ # Sunspot.search(Post) do
174
+ # text_fields do
175
+ # with :body, nil
176
+ # end
177
+ # end
178
+ #
179
+ # This will return all documents that do not have a body.
180
+ #
181
+ def text_fields(&block)
182
+ Sunspot::Util.instance_eval_or_call(
183
+ Scope.new(@scope, TextFieldSetup.new(@setup)),
184
+ &block
185
+ )
186
+ end
187
+
188
+ private
189
+
190
+ def add_restriction(negated, *args)
191
+ case args.first
192
+ when String, Symbol
193
+ raise ArgumentError if args.length > 2
194
+ field = @setup.field(args[0].to_sym)
195
+ if args.length > 1
196
+ value = args[1]
197
+ @scope.add_shorthand_restriction(negated, field, value)
198
+ else # NONE
199
+ DSL::Restriction.new(field, @scope, negated)
200
+ end
201
+ else # args are instances
202
+ @scope.add_restriction(
203
+ negated,
204
+ IdField.instance,
205
+ Sunspot::Query::Restriction::AnyOf,
206
+ args.flatten.map { |instance|
207
+ Sunspot::Adapters::InstanceAdapter.adapt(instance).index_id }
208
+ )
209
+ end
210
+ end
211
+
212
+ end
213
+ end
214
+ end