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.
- data/.gitignore +12 -0
- data/Gemfile +4 -0
- data/History.txt +222 -0
- data/LICENSE +18 -0
- data/Rakefile +17 -0
- data/TODO +13 -0
- data/VERSION.yml +4 -0
- data/bin/sunspot-installer +19 -0
- data/bin/sunspot-solr +74 -0
- data/installer/config/schema.yml +95 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot.rb +569 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/composite_setup.rb +202 -0
- data/lib/sunspot/configuration.rb +46 -0
- data/lib/sunspot/data_extractor.rb +50 -0
- data/lib/sunspot/dsl.rb +5 -0
- data/lib/sunspot/dsl/adjustable.rb +47 -0
- data/lib/sunspot/dsl/field_query.rb +279 -0
- data/lib/sunspot/dsl/fields.rb +103 -0
- data/lib/sunspot/dsl/fulltext.rb +243 -0
- data/lib/sunspot/dsl/function.rb +14 -0
- data/lib/sunspot/dsl/functional.rb +44 -0
- data/lib/sunspot/dsl/more_like_this_query.rb +56 -0
- data/lib/sunspot/dsl/paginatable.rb +28 -0
- data/lib/sunspot/dsl/query_facet.rb +36 -0
- data/lib/sunspot/dsl/restriction.rb +25 -0
- data/lib/sunspot/dsl/restriction_with_near.rb +121 -0
- data/lib/sunspot/dsl/scope.rb +217 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/dsl/standard_query.rb +121 -0
- data/lib/sunspot/field.rb +193 -0
- data/lib/sunspot/field_factory.rb +129 -0
- data/lib/sunspot/indexer.rb +131 -0
- data/lib/sunspot/installer.rb +31 -0
- data/lib/sunspot/installer/library_installer.rb +45 -0
- data/lib/sunspot/installer/schema_builder.rb +219 -0
- data/lib/sunspot/installer/solrconfig_updater.rb +76 -0
- data/lib/sunspot/installer/task_helper.rb +18 -0
- data/lib/sunspot/query.rb +11 -0
- data/lib/sunspot/query/abstract_field_facet.rb +52 -0
- data/lib/sunspot/query/boost_query.rb +24 -0
- data/lib/sunspot/query/common_query.rb +85 -0
- data/lib/sunspot/query/composite_fulltext.rb +36 -0
- data/lib/sunspot/query/connective.rb +206 -0
- data/lib/sunspot/query/date_field_facet.rb +14 -0
- data/lib/sunspot/query/dismax.rb +128 -0
- data/lib/sunspot/query/field_facet.rb +41 -0
- data/lib/sunspot/query/filter.rb +38 -0
- data/lib/sunspot/query/function_query.rb +52 -0
- data/lib/sunspot/query/geo.rb +53 -0
- data/lib/sunspot/query/highlighting.rb +67 -0
- data/lib/sunspot/query/more_like_this.rb +61 -0
- data/lib/sunspot/query/more_like_this_query.rb +12 -0
- data/lib/sunspot/query/pagination.rb +38 -0
- data/lib/sunspot/query/query_facet.rb +16 -0
- data/lib/sunspot/query/restriction.rb +262 -0
- data/lib/sunspot/query/scope.rb +9 -0
- data/lib/sunspot/query/sort.rb +95 -0
- data/lib/sunspot/query/sort_composite.rb +33 -0
- data/lib/sunspot/query/standard_query.rb +16 -0
- data/lib/sunspot/query/text_field_boost.rb +17 -0
- data/lib/sunspot/schema.rb +151 -0
- data/lib/sunspot/search.rb +9 -0
- data/lib/sunspot/search/abstract_search.rb +293 -0
- data/lib/sunspot/search/date_facet.rb +35 -0
- data/lib/sunspot/search/facet_row.rb +27 -0
- data/lib/sunspot/search/field_facet.rb +88 -0
- data/lib/sunspot/search/highlight.rb +38 -0
- data/lib/sunspot/search/hit.rb +136 -0
- data/lib/sunspot/search/more_like_this_search.rb +31 -0
- data/lib/sunspot/search/paginated_collection.rb +55 -0
- data/lib/sunspot/search/query_facet.rb +67 -0
- data/lib/sunspot/search/standard_search.rb +21 -0
- data/lib/sunspot/server.rb +152 -0
- data/lib/sunspot/session.rb +260 -0
- data/lib/sunspot/session_proxy.rb +87 -0
- data/lib/sunspot/session_proxy/abstract_session_proxy.rb +29 -0
- data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +66 -0
- data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +89 -0
- data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +43 -0
- data/lib/sunspot/session_proxy/sharding_session_proxy.rb +222 -0
- data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
- data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +37 -0
- data/lib/sunspot/setup.rb +350 -0
- data/lib/sunspot/text_field_setup.rb +29 -0
- data/lib/sunspot/type.rb +372 -0
- data/lib/sunspot/util.rb +243 -0
- data/lib/sunspot/version.rb +3 -0
- data/script/console +10 -0
- data/solr-1.3/etc/jetty.xml +212 -0
- data/solr-1.3/etc/webdefault.xml +379 -0
- data/solr-1.3/lib/jetty-6.1.3.jar +0 -0
- data/solr-1.3/lib/jetty-util-6.1.3.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr-1.3/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr-1.3/solr/conf/elevate.xml +36 -0
- data/solr-1.3/solr/conf/protwords.txt +21 -0
- data/solr-1.3/solr/conf/schema.xml +64 -0
- data/solr-1.3/solr/conf/solrconfig.xml +725 -0
- data/solr-1.3/solr/conf/stopwords.txt +57 -0
- data/solr-1.3/solr/conf/synonyms.txt +31 -0
- data/solr-1.3/solr/lib/geoapi-nogenerics-2.1-M2.jar +0 -0
- data/solr-1.3/solr/lib/gt2-referencing-2.3.1.jar +0 -0
- data/solr-1.3/solr/lib/jsr108-0.01.jar +0 -0
- data/solr-1.3/solr/lib/locallucene.jar +0 -0
- data/solr-1.3/solr/lib/localsolr.jar +0 -0
- data/solr-1.3/start.jar +0 -0
- data/solr-1.3/webapps/solr.war +0 -0
- data/solr/README.txt +42 -0
- data/solr/etc/jetty.xml +218 -0
- data/solr/etc/webdefault.xml +379 -0
- data/solr/lib/jetty-6.1.3.jar +0 -0
- data/solr/lib/jetty-util-6.1.3.jar +0 -0
- data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr/solr/.gitignore +1 -0
- data/solr/solr/README.txt +54 -0
- data/solr/solr/conf/admin-extra.html +31 -0
- data/solr/solr/conf/elevate.xml +36 -0
- data/solr/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
- data/solr/solr/conf/protwords.txt +21 -0
- data/solr/solr/conf/schema.xml +238 -0
- data/solr/solr/conf/scripts.conf +24 -0
- data/solr/solr/conf/solrconfig.xml +934 -0
- data/solr/solr/conf/spellings.txt +2 -0
- data/solr/solr/conf/stopwords.txt +58 -0
- data/solr/solr/conf/synonyms.txt +31 -0
- data/solr/solr/conf/xslt/example.xsl +132 -0
- data/solr/solr/conf/xslt/example_atom.xsl +67 -0
- data/solr/solr/conf/xslt/example_rss.xsl +66 -0
- data/solr/solr/conf/xslt/luke.xsl +337 -0
- data/solr/start.jar +0 -0
- data/solr/webapps/solr.war +0 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/binding_spec.rb +50 -0
- data/spec/api/indexer/attributes_spec.rb +149 -0
- data/spec/api/indexer/batch_spec.rb +46 -0
- data/spec/api/indexer/dynamic_fields_spec.rb +42 -0
- data/spec/api/indexer/fixed_fields_spec.rb +57 -0
- data/spec/api/indexer/fulltext_spec.rb +43 -0
- data/spec/api/indexer/removal_spec.rb +53 -0
- data/spec/api/indexer/spec_helper.rb +1 -0
- data/spec/api/indexer_spec.rb +14 -0
- data/spec/api/query/advanced_manipulation_examples.rb +35 -0
- data/spec/api/query/connectives_examples.rb +189 -0
- data/spec/api/query/dsl_spec.rb +18 -0
- data/spec/api/query/dynamic_fields_examples.rb +165 -0
- data/spec/api/query/faceting_examples.rb +397 -0
- data/spec/api/query/fulltext_examples.rb +313 -0
- data/spec/api/query/function_spec.rb +70 -0
- data/spec/api/query/geo_examples.rb +68 -0
- data/spec/api/query/highlighting_examples.rb +223 -0
- data/spec/api/query/more_like_this_spec.rb +140 -0
- data/spec/api/query/ordering_pagination_examples.rb +95 -0
- data/spec/api/query/scope_examples.rb +275 -0
- data/spec/api/query/spec_helper.rb +1 -0
- data/spec/api/query/standard_spec.rb +28 -0
- data/spec/api/query/text_field_scoping_examples.rb +30 -0
- data/spec/api/query/types_spec.rb +20 -0
- data/spec/api/search/dynamic_fields_spec.rb +33 -0
- data/spec/api/search/faceting_spec.rb +360 -0
- data/spec/api/search/highlighting_spec.rb +69 -0
- data/spec/api/search/hits_spec.rb +120 -0
- data/spec/api/search/paginated_collection_spec.rb +26 -0
- data/spec/api/search/results_spec.rb +66 -0
- data/spec/api/search/search_spec.rb +23 -0
- data/spec/api/search/spec_helper.rb +1 -0
- data/spec/api/server_spec.rb +91 -0
- data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +85 -0
- data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +30 -0
- data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +41 -0
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +77 -0
- data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
- data/spec/api/session_proxy/spec_helper.rb +9 -0
- data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +50 -0
- data/spec/api/session_spec.rb +220 -0
- data/spec/api/spec_helper.rb +3 -0
- data/spec/api/sunspot_spec.rb +18 -0
- data/spec/ext.rb +11 -0
- data/spec/helpers/indexer_helper.rb +29 -0
- data/spec/helpers/query_helper.rb +38 -0
- data/spec/helpers/search_helper.rb +80 -0
- data/spec/integration/dynamic_fields_spec.rb +55 -0
- data/spec/integration/faceting_spec.rb +238 -0
- data/spec/integration/highlighting_spec.rb +22 -0
- data/spec/integration/indexing_spec.rb +33 -0
- data/spec/integration/keyword_search_spec.rb +317 -0
- data/spec/integration/local_search_spec.rb +64 -0
- data/spec/integration/more_like_this_spec.rb +43 -0
- data/spec/integration/scoped_search_spec.rb +354 -0
- data/spec/integration/spec_helper.rb +7 -0
- data/spec/integration/stored_fields_spec.rb +10 -0
- data/spec/integration/test_pagination.rb +32 -0
- data/spec/mocks/adapters.rb +32 -0
- data/spec/mocks/blog.rb +3 -0
- data/spec/mocks/comment.rb +21 -0
- data/spec/mocks/connection.rb +126 -0
- data/spec/mocks/mock_adapter.rb +30 -0
- data/spec/mocks/mock_class_sharding_session_proxy.rb +24 -0
- data/spec/mocks/mock_record.rb +52 -0
- data/spec/mocks/mock_sharding_session_proxy.rb +15 -0
- data/spec/mocks/photo.rb +11 -0
- data/spec/mocks/post.rb +85 -0
- data/spec/mocks/super_class.rb +2 -0
- data/spec/mocks/user.rb +13 -0
- data/spec/spec_helper.rb +30 -0
- data/tasks/rdoc.rake +27 -0
- data/tasks/schema.rake +19 -0
- data/tasks/todo.rake +4 -0
- 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
|