lisausa-sunspot 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. data/.gitignore +12 -0
  2. data/Gemfile +4 -0
  3. data/History.txt +222 -0
  4. data/LICENSE +18 -0
  5. data/Rakefile +17 -0
  6. data/TODO +13 -0
  7. data/VERSION.yml +4 -0
  8. data/bin/sunspot-installer +19 -0
  9. data/bin/sunspot-solr +74 -0
  10. data/installer/config/schema.yml +95 -0
  11. data/lib/light_config.rb +40 -0
  12. data/lib/sunspot.rb +569 -0
  13. data/lib/sunspot/adapters.rb +265 -0
  14. data/lib/sunspot/composite_setup.rb +202 -0
  15. data/lib/sunspot/configuration.rb +46 -0
  16. data/lib/sunspot/data_extractor.rb +50 -0
  17. data/lib/sunspot/dsl.rb +5 -0
  18. data/lib/sunspot/dsl/adjustable.rb +47 -0
  19. data/lib/sunspot/dsl/field_query.rb +279 -0
  20. data/lib/sunspot/dsl/fields.rb +103 -0
  21. data/lib/sunspot/dsl/fulltext.rb +243 -0
  22. data/lib/sunspot/dsl/function.rb +14 -0
  23. data/lib/sunspot/dsl/functional.rb +44 -0
  24. data/lib/sunspot/dsl/more_like_this_query.rb +56 -0
  25. data/lib/sunspot/dsl/paginatable.rb +28 -0
  26. data/lib/sunspot/dsl/query_facet.rb +36 -0
  27. data/lib/sunspot/dsl/restriction.rb +25 -0
  28. data/lib/sunspot/dsl/restriction_with_near.rb +121 -0
  29. data/lib/sunspot/dsl/scope.rb +217 -0
  30. data/lib/sunspot/dsl/search.rb +30 -0
  31. data/lib/sunspot/dsl/standard_query.rb +121 -0
  32. data/lib/sunspot/field.rb +193 -0
  33. data/lib/sunspot/field_factory.rb +129 -0
  34. data/lib/sunspot/indexer.rb +131 -0
  35. data/lib/sunspot/installer.rb +31 -0
  36. data/lib/sunspot/installer/library_installer.rb +45 -0
  37. data/lib/sunspot/installer/schema_builder.rb +219 -0
  38. data/lib/sunspot/installer/solrconfig_updater.rb +76 -0
  39. data/lib/sunspot/installer/task_helper.rb +18 -0
  40. data/lib/sunspot/query.rb +11 -0
  41. data/lib/sunspot/query/abstract_field_facet.rb +52 -0
  42. data/lib/sunspot/query/boost_query.rb +24 -0
  43. data/lib/sunspot/query/common_query.rb +85 -0
  44. data/lib/sunspot/query/composite_fulltext.rb +36 -0
  45. data/lib/sunspot/query/connective.rb +206 -0
  46. data/lib/sunspot/query/date_field_facet.rb +14 -0
  47. data/lib/sunspot/query/dismax.rb +128 -0
  48. data/lib/sunspot/query/field_facet.rb +41 -0
  49. data/lib/sunspot/query/filter.rb +38 -0
  50. data/lib/sunspot/query/function_query.rb +52 -0
  51. data/lib/sunspot/query/geo.rb +53 -0
  52. data/lib/sunspot/query/highlighting.rb +67 -0
  53. data/lib/sunspot/query/more_like_this.rb +61 -0
  54. data/lib/sunspot/query/more_like_this_query.rb +12 -0
  55. data/lib/sunspot/query/pagination.rb +38 -0
  56. data/lib/sunspot/query/query_facet.rb +16 -0
  57. data/lib/sunspot/query/restriction.rb +262 -0
  58. data/lib/sunspot/query/scope.rb +9 -0
  59. data/lib/sunspot/query/sort.rb +95 -0
  60. data/lib/sunspot/query/sort_composite.rb +33 -0
  61. data/lib/sunspot/query/standard_query.rb +16 -0
  62. data/lib/sunspot/query/text_field_boost.rb +17 -0
  63. data/lib/sunspot/schema.rb +151 -0
  64. data/lib/sunspot/search.rb +9 -0
  65. data/lib/sunspot/search/abstract_search.rb +293 -0
  66. data/lib/sunspot/search/date_facet.rb +35 -0
  67. data/lib/sunspot/search/facet_row.rb +27 -0
  68. data/lib/sunspot/search/field_facet.rb +88 -0
  69. data/lib/sunspot/search/highlight.rb +38 -0
  70. data/lib/sunspot/search/hit.rb +136 -0
  71. data/lib/sunspot/search/more_like_this_search.rb +31 -0
  72. data/lib/sunspot/search/paginated_collection.rb +55 -0
  73. data/lib/sunspot/search/query_facet.rb +67 -0
  74. data/lib/sunspot/search/standard_search.rb +21 -0
  75. data/lib/sunspot/server.rb +152 -0
  76. data/lib/sunspot/session.rb +260 -0
  77. data/lib/sunspot/session_proxy.rb +87 -0
  78. data/lib/sunspot/session_proxy/abstract_session_proxy.rb +29 -0
  79. data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +66 -0
  80. data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +89 -0
  81. data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +43 -0
  82. data/lib/sunspot/session_proxy/sharding_session_proxy.rb +222 -0
  83. data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
  84. data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +37 -0
  85. data/lib/sunspot/setup.rb +350 -0
  86. data/lib/sunspot/text_field_setup.rb +29 -0
  87. data/lib/sunspot/type.rb +372 -0
  88. data/lib/sunspot/util.rb +243 -0
  89. data/lib/sunspot/version.rb +3 -0
  90. data/script/console +10 -0
  91. data/solr-1.3/etc/jetty.xml +212 -0
  92. data/solr-1.3/etc/webdefault.xml +379 -0
  93. data/solr-1.3/lib/jetty-6.1.3.jar +0 -0
  94. data/solr-1.3/lib/jetty-util-6.1.3.jar +0 -0
  95. data/solr-1.3/lib/jsp-2.1/ant-1.6.5.jar +0 -0
  96. data/solr-1.3/lib/jsp-2.1/core-3.1.1.jar +0 -0
  97. data/solr-1.3/lib/jsp-2.1/jsp-2.1.jar +0 -0
  98. data/solr-1.3/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
  99. data/solr-1.3/lib/servlet-api-2.5-6.1.3.jar +0 -0
  100. data/solr-1.3/solr/conf/elevate.xml +36 -0
  101. data/solr-1.3/solr/conf/protwords.txt +21 -0
  102. data/solr-1.3/solr/conf/schema.xml +64 -0
  103. data/solr-1.3/solr/conf/solrconfig.xml +725 -0
  104. data/solr-1.3/solr/conf/stopwords.txt +57 -0
  105. data/solr-1.3/solr/conf/synonyms.txt +31 -0
  106. data/solr-1.3/solr/lib/geoapi-nogenerics-2.1-M2.jar +0 -0
  107. data/solr-1.3/solr/lib/gt2-referencing-2.3.1.jar +0 -0
  108. data/solr-1.3/solr/lib/jsr108-0.01.jar +0 -0
  109. data/solr-1.3/solr/lib/locallucene.jar +0 -0
  110. data/solr-1.3/solr/lib/localsolr.jar +0 -0
  111. data/solr-1.3/start.jar +0 -0
  112. data/solr-1.3/webapps/solr.war +0 -0
  113. data/solr/README.txt +42 -0
  114. data/solr/etc/jetty.xml +218 -0
  115. data/solr/etc/webdefault.xml +379 -0
  116. data/solr/lib/jetty-6.1.3.jar +0 -0
  117. data/solr/lib/jetty-util-6.1.3.jar +0 -0
  118. data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
  119. data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
  120. data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
  121. data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
  122. data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
  123. data/solr/solr/.gitignore +1 -0
  124. data/solr/solr/README.txt +54 -0
  125. data/solr/solr/conf/admin-extra.html +31 -0
  126. data/solr/solr/conf/elevate.xml +36 -0
  127. data/solr/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  128. data/solr/solr/conf/protwords.txt +21 -0
  129. data/solr/solr/conf/schema.xml +238 -0
  130. data/solr/solr/conf/scripts.conf +24 -0
  131. data/solr/solr/conf/solrconfig.xml +934 -0
  132. data/solr/solr/conf/spellings.txt +2 -0
  133. data/solr/solr/conf/stopwords.txt +58 -0
  134. data/solr/solr/conf/synonyms.txt +31 -0
  135. data/solr/solr/conf/xslt/example.xsl +132 -0
  136. data/solr/solr/conf/xslt/example_atom.xsl +67 -0
  137. data/solr/solr/conf/xslt/example_rss.xsl +66 -0
  138. data/solr/solr/conf/xslt/luke.xsl +337 -0
  139. data/solr/start.jar +0 -0
  140. data/solr/webapps/solr.war +0 -0
  141. data/spec/api/adapters_spec.rb +33 -0
  142. data/spec/api/binding_spec.rb +50 -0
  143. data/spec/api/indexer/attributes_spec.rb +149 -0
  144. data/spec/api/indexer/batch_spec.rb +46 -0
  145. data/spec/api/indexer/dynamic_fields_spec.rb +42 -0
  146. data/spec/api/indexer/fixed_fields_spec.rb +57 -0
  147. data/spec/api/indexer/fulltext_spec.rb +43 -0
  148. data/spec/api/indexer/removal_spec.rb +53 -0
  149. data/spec/api/indexer/spec_helper.rb +1 -0
  150. data/spec/api/indexer_spec.rb +14 -0
  151. data/spec/api/query/advanced_manipulation_examples.rb +35 -0
  152. data/spec/api/query/connectives_examples.rb +189 -0
  153. data/spec/api/query/dsl_spec.rb +18 -0
  154. data/spec/api/query/dynamic_fields_examples.rb +165 -0
  155. data/spec/api/query/faceting_examples.rb +397 -0
  156. data/spec/api/query/fulltext_examples.rb +313 -0
  157. data/spec/api/query/function_spec.rb +70 -0
  158. data/spec/api/query/geo_examples.rb +68 -0
  159. data/spec/api/query/highlighting_examples.rb +223 -0
  160. data/spec/api/query/more_like_this_spec.rb +140 -0
  161. data/spec/api/query/ordering_pagination_examples.rb +95 -0
  162. data/spec/api/query/scope_examples.rb +275 -0
  163. data/spec/api/query/spec_helper.rb +1 -0
  164. data/spec/api/query/standard_spec.rb +28 -0
  165. data/spec/api/query/text_field_scoping_examples.rb +30 -0
  166. data/spec/api/query/types_spec.rb +20 -0
  167. data/spec/api/search/dynamic_fields_spec.rb +33 -0
  168. data/spec/api/search/faceting_spec.rb +360 -0
  169. data/spec/api/search/highlighting_spec.rb +69 -0
  170. data/spec/api/search/hits_spec.rb +120 -0
  171. data/spec/api/search/paginated_collection_spec.rb +26 -0
  172. data/spec/api/search/results_spec.rb +66 -0
  173. data/spec/api/search/search_spec.rb +23 -0
  174. data/spec/api/search/spec_helper.rb +1 -0
  175. data/spec/api/server_spec.rb +91 -0
  176. data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +85 -0
  177. data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +30 -0
  178. data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +41 -0
  179. data/spec/api/session_proxy/sharding_session_proxy_spec.rb +77 -0
  180. data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
  181. data/spec/api/session_proxy/spec_helper.rb +9 -0
  182. data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +50 -0
  183. data/spec/api/session_spec.rb +220 -0
  184. data/spec/api/spec_helper.rb +3 -0
  185. data/spec/api/sunspot_spec.rb +18 -0
  186. data/spec/ext.rb +11 -0
  187. data/spec/helpers/indexer_helper.rb +29 -0
  188. data/spec/helpers/query_helper.rb +38 -0
  189. data/spec/helpers/search_helper.rb +80 -0
  190. data/spec/integration/dynamic_fields_spec.rb +55 -0
  191. data/spec/integration/faceting_spec.rb +238 -0
  192. data/spec/integration/highlighting_spec.rb +22 -0
  193. data/spec/integration/indexing_spec.rb +33 -0
  194. data/spec/integration/keyword_search_spec.rb +317 -0
  195. data/spec/integration/local_search_spec.rb +64 -0
  196. data/spec/integration/more_like_this_spec.rb +43 -0
  197. data/spec/integration/scoped_search_spec.rb +354 -0
  198. data/spec/integration/spec_helper.rb +7 -0
  199. data/spec/integration/stored_fields_spec.rb +10 -0
  200. data/spec/integration/test_pagination.rb +32 -0
  201. data/spec/mocks/adapters.rb +32 -0
  202. data/spec/mocks/blog.rb +3 -0
  203. data/spec/mocks/comment.rb +21 -0
  204. data/spec/mocks/connection.rb +126 -0
  205. data/spec/mocks/mock_adapter.rb +30 -0
  206. data/spec/mocks/mock_class_sharding_session_proxy.rb +24 -0
  207. data/spec/mocks/mock_record.rb +52 -0
  208. data/spec/mocks/mock_sharding_session_proxy.rb +15 -0
  209. data/spec/mocks/photo.rb +11 -0
  210. data/spec/mocks/post.rb +85 -0
  211. data/spec/mocks/super_class.rb +2 -0
  212. data/spec/mocks/user.rb +13 -0
  213. data/spec/spec_helper.rb +30 -0
  214. data/tasks/rdoc.rake +27 -0
  215. data/tasks/schema.rake +19 -0
  216. data/tasks/todo.rake +4 -0
  217. metadata +457 -0
@@ -0,0 +1,243 @@
1
+ module Sunspot
2
+ module DSL
3
+ #
4
+ # This DSL exposes the functionality provided by Solr's fulltext Dismax
5
+ # handler.
6
+ #
7
+ class Fulltext
8
+ attr_reader :exclude_fields #:nodoc:
9
+
10
+ # accept function in boost
11
+ include Functional
12
+
13
+ def initialize(query, setup) #:nodoc:
14
+ @query, @setup = query, setup
15
+ @fields_added = false
16
+ @exclude_fields = []
17
+ end
18
+
19
+ #
20
+ # Specify which fields to search. Field names specified as arguments are
21
+ # given default boost; field boosts can be specified by passing a hash of
22
+ # field names keyed to boost values as the last argument.
23
+ #
24
+ # If you wish to boost certain fields without restricting which fields are
25
+ # searched, use #boost_fields
26
+ #
27
+ # === Example
28
+ #
29
+ # Sunspot.search(Post) do
30
+ # keywords 'search is cool' do
31
+ # fields(:body, :title => 2.0)
32
+ # end
33
+ # end
34
+ #
35
+ # This would search the :body field with default boost (1.0), and the :title
36
+ # field with a boost of 2.0
37
+ #
38
+ def fields(*field_names)
39
+ @fields_added = true
40
+ boosted_fields = field_names.pop if field_names.last.is_a?(Hash)
41
+ field_names.each do |field_name|
42
+ @setup.text_fields(field_name).each do |field|
43
+ @query.add_fulltext_field(field, field.default_boost)
44
+ end
45
+ end
46
+ if boosted_fields
47
+ boosted_fields.each_pair do |field_name, boost|
48
+ @setup.text_fields(field_name).each do |field|
49
+ @query.add_fulltext_field(field, boost)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ #
56
+ # Exclude the given fields from the search. All fields that are configured
57
+ # for the types under search and not listed here will be searched.
58
+ #
59
+ def exclude_fields(*field_names)
60
+ @exclude_fields.concat(field_names)
61
+ end
62
+
63
+ #
64
+ # Enable keyword highlighting for this search. By default, the fields
65
+ # under search will be highlighted; you may also may pass one or more
66
+ # symbol arguments indicating fields to be highlighted (they don't even
67
+ # have to be the same fields you're searching).
68
+ #
69
+ # === Example
70
+ #
71
+ # Sunspot.search(Post) do
72
+ # keywords 'show me the highlighting' do
73
+ # highlight :title, :body
74
+ # end
75
+ # end
76
+ #
77
+ # You may also pass a hash of options as the last argument. Options are
78
+ # the following:
79
+ #
80
+ # Full disclosure: I barely understand what these options actually do;
81
+ # this documentation is pretty much just copied from the
82
+ # (http://wiki.apache.org/solr/HighlightingParameters#head-23ecd5061bc2c86a561f85dc1303979fe614b956)[Solr Wiki]
83
+ #
84
+ # :max_snippets::
85
+ # The maximum number of highlighted snippets to generate per field
86
+ # :fragment_size::
87
+ # The number of characters to consider for a highlighted fragment
88
+ # :merge_continuous_fragments::
89
+ # Collapse continuous fragments into a single fragment
90
+ # :phrase_highlighter::
91
+ # Highlight phrase terms only when they appear within the query phrase
92
+ # in the document
93
+ # :require_field_match::
94
+ # If true, a field will only be highlighted if the query matched in
95
+ # this particular field (only has an effect if :phrase_highlighter is
96
+ # true as well)
97
+ #
98
+ def highlight(*args)
99
+ options = args.last.kind_of?(Hash) ? args.pop : {}
100
+ fields = []
101
+ args.each { |field_name| fields.concat(@setup.text_fields(field_name)) }
102
+
103
+ @query.add_highlight(fields, options)
104
+ end
105
+
106
+ #
107
+ # Phrase fields are an awesome dismax feature that adds extra boost to
108
+ # documents for which all the fulltext keywords appear in close proximity
109
+ # in one of the given fields. Excellent for titles, headlines, etc.
110
+ #
111
+ # Boosted fields are specified in a hash of field names to a boost, as
112
+ # with the #fields and #boost_fields methods.
113
+ #
114
+ # === Example
115
+ #
116
+ # Sunspot.search(Post) do
117
+ # keywords 'nothing reveals like relevance' do
118
+ # phrase_fields :title => 2.0
119
+ # end
120
+ # end
121
+ #
122
+ def phrase_fields(boosted_fields)
123
+ if boosted_fields
124
+ boosted_fields.each_pair do |field_name, boost|
125
+ @setup.text_fields(field_name).each do |field|
126
+ @query.add_phrase_field(field, boost)
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ #
133
+ # The maximum number of words that can appear between search terms for a
134
+ # field to qualify for phrase field boost. See #query_phrase_slop for
135
+ # examples. Phrase slop is only meaningful if phrase fields are specified
136
+ # (see #phrase_fields), and it does not have an effect on which results
137
+ # are returned; only on what their respective boosts are.
138
+ #
139
+ def phrase_slop(slop)
140
+ @query.phrase_slop = slop
141
+ end
142
+
143
+ #
144
+ # Boost queries allow specification of an arbitrary scope for which
145
+ # matching documents should receive an extra boost. You can either specify
146
+ # a boost factor and a block, or a boost function. The block is evaluated
147
+ # in the usual scope DSL, and field names are attribute fields, not text
148
+ # fields, as in other scope.
149
+ #
150
+ # The boost function can be a constant (numeric or string literal),
151
+ # a field name or another function. You can build arbitrarily complex
152
+ # functions, which are passed transparently to solr.
153
+ #
154
+ # This method can be called more than once for different boost queries
155
+ # with different boosts.
156
+ #
157
+ # === Example
158
+ #
159
+ # Sunspot.search(Post) do
160
+ # keywords 'super fan' do
161
+ # boost(2.0) do
162
+ # with(:featured, true)
163
+ # end
164
+ #
165
+ # boost(function { sum(:average_rating, product(:popularity, 10)) })
166
+ # end
167
+ # end
168
+ #
169
+ # In the above search, featured posts will receive a boost of 2.0 and all posts
170
+ # will be boosted by (average_rating + popularity * 10).
171
+ #
172
+ def boost(factor_or_function, &block)
173
+ if factor_or_function.is_a?(Sunspot::Query::FunctionQuery)
174
+ @query.add_boost_function(factor_or_function)
175
+ else
176
+ Sunspot::Util.instance_eval_or_call(
177
+ Scope.new(@query.create_boost_query(factor_or_function), @setup),
178
+ &block
179
+ )
180
+ end
181
+ end
182
+
183
+ #
184
+ # Add boost to certain fields, without restricting which fields are
185
+ # searched.
186
+ #
187
+ # === Example
188
+ #
189
+ # Sunspot.search(Post) do
190
+ # keywords('pork sandwich') do
191
+ # boost_fields :title => 1.5
192
+ # end
193
+ # end
194
+ #
195
+ def boost_fields(boosts)
196
+ boosts.each_pair do |field_name, boost|
197
+ begin
198
+ @setup.text_fields(field_name).each do |field|
199
+ @query.add_fulltext_field(field, boost)
200
+ end
201
+ rescue Sunspot::UnrecognizedFieldError
202
+ # We'll let this one slide.
203
+ end
204
+ end
205
+ end
206
+
207
+ #
208
+ # The minimum number of search terms that a result must match. By
209
+ # default, all search terms must match; if the number of search terms
210
+ # is less than this number, the default behavior applies.
211
+ #
212
+ def minimum_match(minimum_match)
213
+ @query.minimum_match = minimum_match
214
+ end
215
+
216
+ #
217
+ # The number of words that can appear between the words in a
218
+ # user-entered phrase (i.e., keywords in quotes) and still match. For
219
+ # instance, in a search for "\"great pizza\"" with a query phrase slop of
220
+ # 1, "great pizza" and "great big pizza" will match, but "great monster of
221
+ # a pizza" will not. Default behavior is a query phrase slop of zero.
222
+ #
223
+ def query_phrase_slop(slop)
224
+ @query.query_phrase_slop = slop
225
+ end
226
+
227
+ #
228
+ # A tiebreaker coefficient for scores derived from subqueries that are
229
+ # lower-scoring than the maximum score subquery. Typically a near-zero
230
+ # value is useful. See
231
+ # http://wiki.apache.org/solr/DisMaxRequestHandler#tie_.28Tie_breaker.29
232
+ # for more information.
233
+ #
234
+ def tie(tie)
235
+ @query.tie = tie
236
+ end
237
+
238
+ def fields_added? #:nodoc:
239
+ @fields_added
240
+ end
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,14 @@
1
+ module Sunspot
2
+ module DSL
3
+ class Function #:nodoc:
4
+ def initialize(functional) #:nodoc:
5
+ @functional = functional
6
+ end
7
+
8
+ def method_missing(method, *args, &block)
9
+ function_args = args.map { |arg| @functional.create_function_query(arg) }
10
+ Sunspot::Query::FunctionalFunctionQuery.new(method, function_args)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,44 @@
1
+ module Sunspot
2
+ module DSL
3
+ #
4
+ # Mixin DSL to accept functions.
5
+ #
6
+ module Functional
7
+
8
+ #
9
+ # Specify a function query with a block that returns an expression.
10
+ #
11
+ # === Examples
12
+ #
13
+ # function { 10 }
14
+ # function { :average_rating }
15
+ # function { sum(:average_rating, 10) }
16
+ #
17
+ # See http://wiki.apache.org/solr/FunctionQuery for a list of all
18
+ # applicable functions
19
+ #
20
+ def function(&block)
21
+ expression = Sunspot::Util.instance_eval_or_call(
22
+ Function.new(self),
23
+ &block
24
+ )
25
+ create_function_query(expression)
26
+ end
27
+
28
+ #
29
+ # Creates an AbstractFunctionQuery from an expression, also called by
30
+ # Sunspot::DSL::Function
31
+ #
32
+ def create_function_query(expression) #:nodoc:
33
+ if expression.is_a?(Sunspot::Query::FunctionQuery)
34
+ expression
35
+ elsif expression.is_a?(Symbol)
36
+ Sunspot::Query::FieldFunctionQuery.new(@setup.field(expression))
37
+ else
38
+ Sunspot::Query::ConstantFunctionQuery.new(expression)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,56 @@
1
+ module Sunspot
2
+ module DSL #:nodoc:
3
+ #
4
+ # This class provides the DSL for MoreLikeThis queries.
5
+ #
6
+ class MoreLikeThisQuery < FieldQuery
7
+ include Paginatable, Adjustable
8
+
9
+ def fields(*field_names)
10
+ boosted_fields = field_names.pop if field_names.last.is_a?(Hash)
11
+ field_names.each do |name|
12
+ mlt_fields = @setup.more_like_this_fields(name)
13
+ raise(ArgumentError, "Field #{name} is not setup for more_like_this") if mlt_fields.empty?
14
+ mlt_fields.each { |field| @query.more_like_this.add_field(field) }
15
+ end
16
+ if boosted_fields
17
+ boosted_fields.each_pair do |field_name, boost|
18
+ @setup.more_like_this_fields(field_name).each do |field|
19
+ @query.more_like_this.add_field(field, boost)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def minimum_term_frequency(value)
26
+ @query.more_like_this.minimum_term_frequency = value
27
+ end
28
+ alias_method :mintf, :minimum_term_frequency
29
+
30
+ def minimum_document_frequency(value)
31
+ @query.more_like_this.minimum_document_frequency = value
32
+ end
33
+ alias_method :mindf, :minimum_document_frequency
34
+
35
+ def minimum_word_length(value)
36
+ @query.more_like_this.minimum_word_length = value
37
+ end
38
+ alias_method :minwl, :minimum_word_length
39
+
40
+ def maximum_word_length(value)
41
+ @query.more_like_this.maximum_word_length = value
42
+ end
43
+ alias_method :maxwl, :maximum_word_length
44
+
45
+ def maximum_query_terms(value)
46
+ @query.more_like_this.maximum_query_terms = value
47
+ end
48
+ alias_method :maxqt, :maximum_query_terms
49
+
50
+ def boost_by_relevance(should_boost)
51
+ @query.more_like_this.boost_by_relevance = should_boost
52
+ end
53
+ alias_method :boost, :boost_by_relevance
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,28 @@
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
+ def paginate(options = {})
21
+ page = options.delete(:page)
22
+ per_page = options.delete(:per_page)
23
+ raise ArgumentError, "unknown argument #{options.keys.first.inspect} passed to paginate" unless options.empty?
24
+ @query.paginate(page, per_page)
25
+ end
26
+ end
27
+ end
28
+ 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) #:nodoc:
9
+ @query, @setup, @facet = query, setup, facet
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
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