sunspot 0.10.5 → 0.10.6
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/History.txt +13 -0
- data/README.rdoc +3 -3
- data/TODO +4 -5
- data/VERSION.yml +1 -1
- data/bin/sunspot-solr +18 -6
- data/lib/sunspot/dsl/field_query.rb +69 -18
- data/lib/sunspot/dsl/fields.rb +6 -5
- data/lib/sunspot/dsl/fulltext.rb +57 -1
- data/lib/sunspot/dsl/query.rb +30 -3
- data/lib/sunspot/dsl/query_facet.rb +8 -3
- data/lib/sunspot/dsl/search.rb +1 -1
- data/lib/sunspot/dsl.rb +1 -1
- data/lib/sunspot/field_factory.rb +6 -3
- data/lib/sunspot/query/abstract_field_facet.rb +43 -0
- data/lib/sunspot/query/date_field_facet.rb +14 -0
- data/lib/sunspot/query/dismax.rb +26 -7
- data/lib/sunspot/query/field_facet.rb +2 -122
- data/lib/sunspot/query/highlighting.rb +17 -5
- data/lib/sunspot/query/query.rb +12 -23
- data/lib/sunspot/query/query_facet.rb +4 -66
- data/lib/sunspot/query.rb +5 -1
- 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 +44 -0
- data/lib/sunspot/search/hit.rb +10 -6
- data/lib/sunspot/search/query_facet.rb +62 -0
- data/lib/sunspot/search.rb +22 -44
- data/lib/sunspot/setup.rb +22 -7
- data/lib/sunspot/type.rb +4 -0
- data/lib/sunspot/util.rb +8 -0
- data/lib/sunspot.rb +7 -6
- data/solr/solr/conf/solrconfig.xml +1 -2
- data/solr/solr/lib/locallucene.jar +0 -0
- data/solr/solr/lib/localsolr.jar +0 -0
- data/spec/api/indexer/attributes_spec.rb +5 -0
- data/spec/api/query/faceting_spec.rb +24 -0
- data/spec/api/query/fulltext_spec.rb +80 -1
- data/spec/api/query/highlighting_spec.rb +84 -6
- data/spec/api/search/faceting_spec.rb +45 -9
- data/spec/api/search/highlighting_spec.rb +2 -2
- data/spec/api/search/hits_spec.rb +5 -0
- data/spec/integration/faceting_spec.rb +19 -0
- data/spec/integration/keyword_search_spec.rb +101 -4
- data/spec/mocks/photo.rb +3 -0
- data/tasks/gemspec.rake +8 -2
- data/tasks/rcov.rake +2 -2
- metadata +9 -11
- data/lib/sunspot/facet.rb +0 -24
- data/lib/sunspot/facet_data.rb +0 -169
- data/lib/sunspot/facet_row.rb +0 -12
- data/lib/sunspot/instantiated_facet.rb +0 -39
- data/lib/sunspot/instantiated_facet_row.rb +0 -27
- data/lib/sunspot/query/fulltext_base_query.rb +0 -47
- data/lib/sunspot/query/query_facet_row.rb +0 -19
- data/lib/sunspot/query/query_field_facet.rb +0 -20
data/History.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
== 0.10.6 2009-11-05
|
2
|
+
* Support more dismax parameters
|
3
|
+
* Support multiple boost queries
|
4
|
+
* Allow "extra" facet rows
|
5
|
+
* Allow exclusion of fulltext fields
|
6
|
+
* Allow specification of per-field highlighting params
|
7
|
+
* Specify coordinates using block extraction
|
8
|
+
* Return empty array if no highlights available
|
9
|
+
* Get stored text fields from hits
|
10
|
+
* Update docs to reflect a requirement of at least one search type
|
11
|
+
* added --max-memory and --min-memory parameters to sunspot-solr
|
12
|
+
* LocalLucene and LocalSolr compatible with Java 1.5
|
13
|
+
|
1
14
|
== 0.10.5 2009-10-22
|
2
15
|
* Fix highlighting for multiple-model search
|
3
16
|
|
data/README.rdoc
CHANGED
@@ -125,9 +125,9 @@ me so I can rectify the situation!
|
|
125
125
|
|
126
126
|
== Dependencies
|
127
127
|
|
128
|
-
1. RSolr
|
129
|
-
2. Daemons
|
130
|
-
4. Java
|
128
|
+
1. RSolr 0.9.6
|
129
|
+
2. Daemons 1.x
|
130
|
+
4. Java 1.5+
|
131
131
|
|
132
132
|
Sunspot has been tested with MRI 1.8.6 and 1.8.7, REE 1.8.6, YARV 1.9.1, and
|
133
133
|
JRuby 1.2.0
|
data/TODO
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
=== 0.10 ===
|
2
|
-
*
|
3
|
-
* Allow boosting without field constraints
|
4
|
-
* Allow coordinates to be specified with block in setup
|
5
|
-
=== 0.11 ===
|
1
|
+
=== 0.10.x ===
|
2
|
+
* Assumed inconsistency
|
6
3
|
* Support all operations in batches. Make it smart.
|
7
4
|
* Don't use more than one commits when one is equivalent
|
8
5
|
* Preserve adds/deletes that are done after last commit
|
9
6
|
* Don't do adds and deletes for the same document out of order
|
10
7
|
* Don't do more than one add for the same document
|
11
8
|
* Do use as few requests as possible within those constraints
|
9
|
+
=== Future ===
|
10
|
+
* Support Solr functions (e.g. dismax :bf)
|
data/VERSION.yml
CHANGED
data/bin/sunspot-solr
CHANGED
@@ -19,12 +19,14 @@ end
|
|
19
19
|
working_directory = FileUtils.pwd
|
20
20
|
solr_install = File.expand_path(File.join(File.dirname(__FILE__), '..', 'solr'))
|
21
21
|
|
22
|
-
port
|
23
|
-
data_dir
|
24
|
-
solr_home
|
25
|
-
pid_dir
|
26
|
-
log_file
|
27
|
-
log_level
|
22
|
+
port = '8983'
|
23
|
+
data_dir = File.expand_path(File.join(Dir.tmpdir, 'solr_data'))
|
24
|
+
solr_home = File.join(solr_install, 'solr')
|
25
|
+
pid_dir = working_directory
|
26
|
+
log_file = nil
|
27
|
+
log_level = 'OFF'
|
28
|
+
min_memory = '128m'
|
29
|
+
max_memory = '512m'
|
28
30
|
|
29
31
|
OptionParser.new do |opts|
|
30
32
|
opts.banner = "Usage: sunspot-solr start [options]"
|
@@ -52,6 +54,14 @@ OptionParser.new do |opts|
|
|
52
54
|
opts.on '--log-file=LOG_FILE', 'Path to Solr log file' do |lf|
|
53
55
|
log_file = File.expand_path(lf)
|
54
56
|
end
|
57
|
+
|
58
|
+
opts.on '--max-memory=MEMORY', 'Specify the maximum size of the memory allocation pool' do |mm|
|
59
|
+
max_memory = mm
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on '--min-memory=MEMORY', 'Specify the initial size of the memory allocation pool' do |mm|
|
63
|
+
min_memory = mm
|
64
|
+
end
|
55
65
|
end.parse!
|
56
66
|
|
57
67
|
options = { :dir_mode => :normal, :dir => pid_dir }
|
@@ -72,6 +82,8 @@ end
|
|
72
82
|
Daemons.run_proc('sunspot-solr', options) do
|
73
83
|
FileUtils.cd(solr_install) do
|
74
84
|
args = ['java']
|
85
|
+
args << "-Xms#{min_memory}"
|
86
|
+
args << "-Xmx#{max_memory}"
|
75
87
|
args << "-Djetty.port=#{port}" if port
|
76
88
|
args << "-Dsolr.data.dir=#{data_dir}" if data_dir
|
77
89
|
args << "-Dsolr.solr.home=#{solr_home}" if solr_home
|
@@ -6,8 +6,8 @@ module Sunspot
|
|
6
6
|
# query DSL.
|
7
7
|
#
|
8
8
|
class FieldQuery < Scope
|
9
|
-
def initialize(query, setup)
|
10
|
-
@query = query
|
9
|
+
def initialize(search, query, setup) #:nodoc:
|
10
|
+
@search, @query = search, query
|
11
11
|
super(query.scope, setup)
|
12
12
|
end
|
13
13
|
|
@@ -58,39 +58,90 @@ module Sunspot
|
|
58
58
|
# :zeros<Boolean>::
|
59
59
|
# Return facet rows for which there are no matches (equivalent to
|
60
60
|
# :minimum_count => 0). Default is false.
|
61
|
+
# :extra<Symbol,Array>::
|
62
|
+
# One or more of :any and :none. :any returns a facet row with a count
|
63
|
+
# of all matching documents that have some value for this field. :none
|
64
|
+
# returns a facet row with a count of all matching documents that have
|
65
|
+
# no value for this field. The facet row(s) corresponding to the extras
|
66
|
+
# have a value of the symbol passed.
|
61
67
|
#
|
62
68
|
def facet(*field_names, &block)
|
69
|
+
options = Sunspot::Util.extract_options_from(field_names)
|
70
|
+
|
63
71
|
if block
|
64
|
-
options =
|
65
|
-
if field_names.last.is_a?(Hash)
|
66
|
-
field_names.pop
|
67
|
-
else
|
68
|
-
{}
|
69
|
-
end
|
70
72
|
if field_names.length != 1
|
71
73
|
raise(
|
72
74
|
ArgumentError,
|
73
75
|
"wrong number of arguments (#{field_names.length} for 1)"
|
74
76
|
)
|
75
77
|
end
|
76
|
-
|
77
|
-
|
78
|
+
search_facet = @search.add_query_facet(field_names.first, options)
|
79
|
+
Sunspot::Util.instance_eval_or_call(
|
80
|
+
QueryFacet.new(@query, @setup, search_facet),
|
81
|
+
&block
|
82
|
+
)
|
83
|
+
elsif options[:only]
|
84
|
+
field_names.each do |field_name|
|
85
|
+
field = @setup.field(field_name)
|
86
|
+
search_facet = @search.add_field_facet(field, options)
|
87
|
+
Array(options[:only]).each do |value|
|
88
|
+
facet = Sunspot::Query::QueryFacet.new
|
89
|
+
facet.add_restriction(field, Sunspot::Query::Restriction::EqualTo, value)
|
90
|
+
@query.add_query_facet(facet)
|
91
|
+
search_facet.add_row(value, facet.to_boolean_phrase)
|
92
|
+
end
|
93
|
+
end
|
78
94
|
else
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
95
|
+
field_names.each do |field_name|
|
96
|
+
search_facet = nil
|
97
|
+
field = @setup.field(field_name)
|
98
|
+
facet =
|
99
|
+
if options[:time_range]
|
100
|
+
unless field.type == Sunspot::Type::TimeType
|
101
|
+
raise(
|
102
|
+
ArgumentError,
|
103
|
+
':time_range can only be specified for Date or Time fields'
|
104
|
+
)
|
105
|
+
end
|
106
|
+
search_facet = @search.add_date_facet(field, options)
|
107
|
+
Sunspot::Query::DateFieldFacet.new(field, options)
|
108
|
+
else
|
109
|
+
search_facet = @search.add_field_facet(field)
|
110
|
+
Sunspot::Query::FieldFacet.new(field, options)
|
111
|
+
end
|
112
|
+
@query.add_field_facet(facet)
|
113
|
+
Array(options[:extra]).each do |extra|
|
114
|
+
extra_facet = Sunspot::Query::QueryFacet.new
|
115
|
+
case extra
|
116
|
+
when :any
|
117
|
+
extra_facet.add_negated_restriction(
|
118
|
+
field,
|
119
|
+
Sunspot::Query::Restriction::EqualTo,
|
120
|
+
nil
|
121
|
+
)
|
122
|
+
when :none
|
123
|
+
extra_facet.add_restriction(
|
124
|
+
field,
|
125
|
+
Sunspot::Query::Restriction::EqualTo,
|
126
|
+
nil
|
127
|
+
)
|
128
|
+
else
|
129
|
+
raise(
|
130
|
+
ArgumentError,
|
131
|
+
"Allowed values for :extra are :any and :none"
|
132
|
+
)
|
133
|
+
end
|
134
|
+
search_facet.add_row(extra, extra_facet.to_boolean_phrase)
|
135
|
+
@query.add_query_facet(extra_facet)
|
84
136
|
end
|
85
|
-
for field_name in field_names
|
86
|
-
@query.add_field_facet(@setup.field(field_name), options)
|
87
137
|
end
|
88
138
|
end
|
89
139
|
end
|
90
140
|
|
91
141
|
def dynamic(base_name, &block)
|
142
|
+
dynamic_field_factory = @setup.dynamic_field_factory(base_name)
|
92
143
|
Sunspot::Util.instance_eval_or_call(
|
93
|
-
FieldQuery.new(@query,
|
144
|
+
FieldQuery.new(@search, @query, dynamic_field_factory),
|
94
145
|
&block
|
95
146
|
)
|
96
147
|
end
|
data/lib/sunspot/dsl/fields.rb
CHANGED
@@ -44,12 +44,13 @@ module Sunspot
|
|
44
44
|
end
|
45
45
|
|
46
46
|
#
|
47
|
-
# Specify a method that returns the geographical coordinates
|
48
|
-
# with the document. The object returned must respond to #first
|
49
|
-
# (e.g., a two-element Array); or to #lat and one of #lng, #lon,
|
47
|
+
# Specify a method or block that returns the geographical coordinates
|
48
|
+
# associated with the document. The object returned must respond to #first
|
49
|
+
# and #last (e.g., a two-element Array); or to #lat and one of #lng, #lon,
|
50
|
+
# or #long
|
50
51
|
#
|
51
|
-
def coordinates(name)
|
52
|
-
@setup.set_coordinates_field(name)
|
52
|
+
def coordinates(name = nil, &block)
|
53
|
+
@setup.set_coordinates_field(name, &block)
|
53
54
|
end
|
54
55
|
|
55
56
|
#
|
data/lib/sunspot/dsl/fulltext.rb
CHANGED
@@ -5,9 +5,12 @@ module Sunspot
|
|
5
5
|
# handler.
|
6
6
|
#
|
7
7
|
class Fulltext
|
8
|
+
attr_reader :exclude_fields #:nodoc:
|
9
|
+
|
8
10
|
def initialize(query, setup) #:nodoc:
|
9
11
|
@query, @setup = query, setup
|
10
12
|
@fields_added = false
|
13
|
+
@exclude_fields = []
|
11
14
|
end
|
12
15
|
|
13
16
|
#
|
@@ -46,6 +49,14 @@ module Sunspot
|
|
46
49
|
end
|
47
50
|
end
|
48
51
|
|
52
|
+
#
|
53
|
+
# Exclude the given fields from the search. All fields that are configured
|
54
|
+
# for the types under search and not listed here will be searched.
|
55
|
+
#
|
56
|
+
def exclude_fields(*field_names)
|
57
|
+
@exclude_fields.concat(field_names)
|
58
|
+
end
|
59
|
+
|
49
60
|
#
|
50
61
|
# Enable keyword highlighting for this search. By default, the fields
|
51
62
|
# under search will be highlighted; you may also may pass one or more
|
@@ -86,7 +97,7 @@ module Sunspot
|
|
86
97
|
fields = []
|
87
98
|
args.each { |field_name| fields.concat(@setup.text_fields(field_name)) }
|
88
99
|
|
89
|
-
@query.
|
100
|
+
@query.add_highlight(fields, options)
|
90
101
|
end
|
91
102
|
|
92
103
|
#
|
@@ -115,12 +126,26 @@ module Sunspot
|
|
115
126
|
end
|
116
127
|
end
|
117
128
|
|
129
|
+
#
|
130
|
+
# The maximum number of words that can appear between search terms for a
|
131
|
+
# field to qualify for phrase field boost. See #query_phrase_slop for
|
132
|
+
# examples. Phrase slop is only meaningful if phrase fields are specified
|
133
|
+
# (see #phrase_fields), and it does not have an effect on which results
|
134
|
+
# are returned; only on what their respective boosts are.
|
135
|
+
#
|
136
|
+
def phrase_slop(slop)
|
137
|
+
@query.phrase_slop = slop
|
138
|
+
end
|
139
|
+
|
118
140
|
#
|
119
141
|
# Boost queries allow specification of an arbitrary scope for which
|
120
142
|
# matching documents should receive an extra boost. The block is evaluated
|
121
143
|
# in the usual scope DSL, and field names are attribute fields, not text
|
122
144
|
# fields, as in other scope.
|
123
145
|
#
|
146
|
+
# This method can be called more than once for different boost queries
|
147
|
+
# with different boosts.
|
148
|
+
#
|
124
149
|
# === Example
|
125
150
|
#
|
126
151
|
# Sunspot.search(Post) do
|
@@ -159,6 +184,37 @@ module Sunspot
|
|
159
184
|
end
|
160
185
|
end
|
161
186
|
end
|
187
|
+
|
188
|
+
#
|
189
|
+
# The minimum number of search terms that a result must match. By
|
190
|
+
# default, all search terms must match; if the number of search terms
|
191
|
+
# is less than this number, the default behavior applies.
|
192
|
+
#
|
193
|
+
def minimum_match(minimum_match)
|
194
|
+
@query.minimum_match = minimum_match
|
195
|
+
end
|
196
|
+
|
197
|
+
#
|
198
|
+
# The number of words that can appear between the words in a
|
199
|
+
# user-entered phrase (i.e., keywords in quotes) and still match. For
|
200
|
+
# instance, in a search for "\"great pizza\"" with a query phrase slop of
|
201
|
+
# 1, "great pizza" and "great big pizza" will match, but "great monster of
|
202
|
+
# a pizza" will not. Default behavior is a query phrase slop of zero.
|
203
|
+
#
|
204
|
+
def query_phrase_slop(slop)
|
205
|
+
@query.query_phrase_slop = slop
|
206
|
+
end
|
207
|
+
|
208
|
+
#
|
209
|
+
# A tiebreaker coefficient for scores derived from subqueries that are
|
210
|
+
# lower-scoring than the maximum score subquery. Typically a near-zero
|
211
|
+
# value is useful. See
|
212
|
+
# http://wiki.apache.org/solr/DisMaxRequestHandler#tie_.28Tie_breaker.29
|
213
|
+
# for more information.
|
214
|
+
#
|
215
|
+
def tie(tie)
|
216
|
+
@query.tie = tie
|
217
|
+
end
|
162
218
|
|
163
219
|
def fields_added? #:nodoc:
|
164
220
|
@fields_added
|
data/lib/sunspot/dsl/query.rb
CHANGED
@@ -34,6 +34,22 @@ module Sunspot
|
|
34
34
|
# If true, perform keyword highlighting on all searched fields. If an
|
35
35
|
# array of field names, perform highlighting on the specified fields.
|
36
36
|
# This can also be called from within the fulltext block.
|
37
|
+
# :minimum_match<Integer>::
|
38
|
+
# The minimum number of search terms that a result must match. By
|
39
|
+
# default, all search terms must match; if the number of search terms
|
40
|
+
# is less than this number, the default behavior applies.
|
41
|
+
# :tie<Float>::
|
42
|
+
# A tiebreaker coefficient for scores derived from subqueries that are
|
43
|
+
# lower-scoring than the maximum score subquery. Typically a near-zero
|
44
|
+
# value is useful. See
|
45
|
+
# http://wiki.apache.org/solr/DisMaxRequestHandler#tie_.28Tie_breaker.29
|
46
|
+
# for more information.
|
47
|
+
# :query_phrase_slop<Integer>::
|
48
|
+
# The number of words that can appear between the words in a
|
49
|
+
# user-entered phrase (i.e., keywords in quotes) and still match. For
|
50
|
+
# instance, in a search for "\"great pizza\"" with a phrase slop of 1,
|
51
|
+
# "great pizza" and "great big pizza" will match, but "great monster of
|
52
|
+
# a pizza" will not. Default behavior is a query phrase slop of zero.
|
37
53
|
#
|
38
54
|
def fulltext(keywords, options = {}, &block)
|
39
55
|
if keywords && !(keywords.to_s =~ /^\s*$/)
|
@@ -45,15 +61,24 @@ module Sunspot
|
|
45
61
|
end
|
46
62
|
end
|
47
63
|
end
|
64
|
+
if minimum_match = options.delete(:minimum_match)
|
65
|
+
fulltext_query.minimum_match = minimum_match.to_i
|
66
|
+
end
|
67
|
+
if tie = options.delete(:tie)
|
68
|
+
fulltext_query.tie = tie.to_f
|
69
|
+
end
|
70
|
+
if query_phrase_slop = options.delete(:query_phrase_slop)
|
71
|
+
fulltext_query.query_phrase_slop = query_phrase_slop.to_i
|
72
|
+
end
|
48
73
|
if highlight_field_names = options.delete(:highlight)
|
49
74
|
if highlight_field_names == true
|
50
|
-
fulltext_query.
|
75
|
+
fulltext_query.add_highlight
|
51
76
|
else
|
52
77
|
highlight_fields = []
|
53
78
|
Array(highlight_field_names).each do |field_name|
|
54
79
|
highlight_fields.concat(@setup.text_fields(field_name))
|
55
80
|
end
|
56
|
-
fulltext_query.
|
81
|
+
fulltext_query.add_highlight(highlight_fields)
|
57
82
|
end
|
58
83
|
end
|
59
84
|
if block && fulltext_query
|
@@ -66,7 +91,9 @@ module Sunspot
|
|
66
91
|
if !field_names && (!fulltext_dsl || !fulltext_dsl.fields_added?)
|
67
92
|
@setup.all_text_fields.each do |field|
|
68
93
|
unless fulltext_query.has_fulltext_field?(field)
|
69
|
-
|
94
|
+
unless fulltext_dsl && fulltext_dsl.exclude_fields.include?(field.name)
|
95
|
+
fulltext_query.add_fulltext_field(field, field.default_boost)
|
96
|
+
end
|
70
97
|
end
|
71
98
|
end
|
72
99
|
end
|
@@ -5,8 +5,8 @@ module Sunspot
|
|
5
5
|
# method.
|
6
6
|
#
|
7
7
|
class QueryFacet
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(query, setup, facet) #:nodoc:
|
9
|
+
@query, @setup, @facet = query, setup, facet
|
10
10
|
end
|
11
11
|
|
12
12
|
#
|
@@ -24,7 +24,12 @@ module Sunspot
|
|
24
24
|
# An object used to identify this facet row in the results.
|
25
25
|
#
|
26
26
|
def row(label, &block)
|
27
|
-
|
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)
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|
data/lib/sunspot/dsl/search.rb
CHANGED
data/lib/sunspot/dsl.rb
CHANGED
@@ -123,10 +123,13 @@ module Sunspot
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
-
#XXX Right now this doubles as a Field and a FieldFactory - good idea?
|
127
126
|
class Coordinates
|
128
|
-
def initialize(name)
|
129
|
-
|
127
|
+
def initialize(name = nil, &block)
|
128
|
+
if block
|
129
|
+
@data_extractor = DataExtractor::BlockExtractor.new(&block)
|
130
|
+
else
|
131
|
+
@data_extractor = DataExtractor::AttributeExtractor.new(name)
|
132
|
+
end
|
130
133
|
end
|
131
134
|
|
132
135
|
def populate_document(document, model)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Query
|
3
|
+
class AbstractFieldFacet
|
4
|
+
def initialize(field, options)
|
5
|
+
@field, @options = field, options
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_params
|
9
|
+
params = {
|
10
|
+
:facet => 'true',
|
11
|
+
}
|
12
|
+
case @options[:sort]
|
13
|
+
when :count
|
14
|
+
params[qualified_param('sort')] = 'true'
|
15
|
+
when :index
|
16
|
+
params[qualified_param('sort')] = 'false'
|
17
|
+
when nil
|
18
|
+
else
|
19
|
+
raise(
|
20
|
+
ArgumentError,
|
21
|
+
"#{@options[:sort].inspect} is not an allowed value for :sort. Allowed options are :count and :index"
|
22
|
+
)
|
23
|
+
end
|
24
|
+
if @options[:limit]
|
25
|
+
params[qualified_param('limit')] = @options[:limit].to_i
|
26
|
+
end
|
27
|
+
params[qualified_param('mincount')] =
|
28
|
+
case
|
29
|
+
when @options[:minimum_count] then @options[:minimum_count].to_i
|
30
|
+
when @options[:zeros] then 0
|
31
|
+
else 1
|
32
|
+
end
|
33
|
+
params
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def qualified_param(param)
|
39
|
+
:"f.#{@field.indexed_name}.facet.#{param}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Query
|
3
|
+
class DateFieldFacet < AbstractFieldFacet
|
4
|
+
def to_params
|
5
|
+
params = super
|
6
|
+
params[:"facet.date"] = [@field.indexed_name]
|
7
|
+
params[qualified_param('date.start')] = @field.to_indexed(@options[:time_range].first)
|
8
|
+
params[qualified_param('date.end')] = @field.to_indexed(@options[:time_range].last)
|
9
|
+
params[qualified_param('date.gap')] = "+#{@options[:time_interval] || 86400}SECONDS"
|
10
|
+
params
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/sunspot/query/dismax.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
module Sunspot
|
2
2
|
module Query
|
3
3
|
class Dismax
|
4
|
+
attr_writer :minimum_match, :phrase_slop, :query_phrase_slop, :tie
|
5
|
+
|
4
6
|
def initialize(keywords)
|
5
7
|
@keywords = keywords
|
6
8
|
@fulltext_fields = {}
|
9
|
+
@boost_queries = []
|
10
|
+
@highlights = []
|
7
11
|
end
|
8
12
|
|
9
13
|
#
|
@@ -17,11 +21,25 @@ module Sunspot
|
|
17
21
|
if @phrase_fields
|
18
22
|
params[:pf] = @phrase_fields.map { |field| field.to_boosted_field }.join(' ')
|
19
23
|
end
|
20
|
-
|
21
|
-
params[:bq] = @boost_query
|
24
|
+
unless @boost_queries.empty?
|
25
|
+
params[:bq] = @boost_queries.map do |boost_query|
|
26
|
+
boost_query.to_boolean_phrase
|
27
|
+
end
|
28
|
+
end
|
29
|
+
if @minimum_match
|
30
|
+
params[:mm] = @minimum_match
|
31
|
+
end
|
32
|
+
if @phrase_slop
|
33
|
+
params[:ps] = @phrase_slop
|
34
|
+
end
|
35
|
+
if @query_phrase_slop
|
36
|
+
params[:qs] = @query_phrase_slop
|
37
|
+
end
|
38
|
+
if @tie
|
39
|
+
params[:tie] = @tie
|
22
40
|
end
|
23
|
-
|
24
|
-
Sunspot::Util.deep_merge!(params,
|
41
|
+
@highlights.each do |highlight|
|
42
|
+
Sunspot::Util.deep_merge!(params, highlight.to_params)
|
25
43
|
end
|
26
44
|
params
|
27
45
|
end
|
@@ -30,7 +48,8 @@ module Sunspot
|
|
30
48
|
# Assign a new boost query and return it.
|
31
49
|
#
|
32
50
|
def create_boost_query(factor)
|
33
|
-
@boost_query = BoostQuery.new(factor)
|
51
|
+
@boost_queries << boost_query = BoostQuery.new(factor)
|
52
|
+
boost_query
|
34
53
|
end
|
35
54
|
|
36
55
|
#
|
@@ -53,8 +72,8 @@ module Sunspot
|
|
53
72
|
# Highlighting object won't pass field names at all, which means
|
54
73
|
# the dismax's :qf parameter will be used by Solr.
|
55
74
|
#
|
56
|
-
def
|
57
|
-
@
|
75
|
+
def add_highlight(fields=[], options={})
|
76
|
+
@highlights << Highlighting.new(fields, options)
|
58
77
|
end
|
59
78
|
|
60
79
|
#
|