sunspot 2.2.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/sunspot/dsl/field_query.rb +11 -9
- data/lib/sunspot/dsl/fulltext.rb +9 -1
- data/lib/sunspot/dsl/group.rb +108 -0
- data/lib/sunspot/dsl/search.rb +1 -1
- data/lib/sunspot/dsl.rb +1 -1
- data/lib/sunspot/field_factory.rb +28 -15
- data/lib/sunspot/indexer.rb +63 -17
- data/lib/sunspot/query/abstract_fulltext.rb +9 -2
- data/lib/sunspot/query/dismax.rb +11 -4
- data/lib/sunspot/query/{field_group.rb → group.rb} +16 -6
- data/lib/sunspot/query/group_query.rb +17 -0
- data/lib/sunspot/query/restriction.rb +45 -1
- data/lib/sunspot/query.rb +1 -1
- data/lib/sunspot/schema.rb +2 -1
- data/lib/sunspot/search/abstract_search.rb +7 -3
- data/lib/sunspot/search/query_group.rb +74 -0
- data/lib/sunspot/search/standard_search.rb +1 -1
- data/lib/sunspot/search.rb +1 -1
- data/lib/sunspot/session.rb +16 -0
- data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +2 -2
- data/lib/sunspot/session_proxy/retry_5xx_session_proxy.rb +1 -1
- data/lib/sunspot/session_proxy/sharding_session_proxy.rb +4 -2
- data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +1 -1
- data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +3 -1
- data/lib/sunspot/type.rb +20 -0
- data/lib/sunspot/version.rb +1 -1
- data/lib/sunspot.rb +36 -2
- data/spec/api/indexer/attributes_spec.rb +5 -0
- data/spec/api/query/function_spec.rb +103 -0
- data/spec/api/query/group_spec.rb +23 -1
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +1 -1
- data/spec/helpers/integration_helper.rb +9 -0
- data/spec/integration/atomic_updates_spec.rb +44 -0
- data/spec/integration/field_grouping_spec.rb +13 -0
- data/spec/integration/scoped_search_spec.rb +51 -0
- data/spec/mocks/post.rb +3 -1
- metadata +11 -15
- data/lib/sunspot/dsl/field_group.rb +0 -57
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4a3b915b7cc088b4c26ba0eb4ae3e541666da526
|
4
|
+
data.tar.gz: a3021876e0d940137daf4527c0d3ac354f93119c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 62193e81b7834636ad0b2a03110e0054778700fe93a7cd6d6f5a52366708703bf3ce3a0ef24cf83d78a3d3532e79c274d893019aab1e26c289932e5b501bf005
|
7
|
+
data.tar.gz: 3a69aa3883a08bdab4c31ece01218cc3ac2a5bde250704448b9ca5e8dda070a1c7aaf401f7658621e2616f15596a84acc34319173dab91cb71a25b56a199db09
|
@@ -68,20 +68,22 @@ module Sunspot
|
|
68
68
|
#
|
69
69
|
# ==== Parameters
|
70
70
|
#
|
71
|
-
#
|
71
|
+
# field_names...<Symbol>:: the fields to use for grouping
|
72
72
|
def group(*field_names, &block)
|
73
|
+
group = Sunspot::Query::Group.new()
|
74
|
+
|
73
75
|
field_names.each do |field_name|
|
74
76
|
field = @setup.field(field_name)
|
75
|
-
group
|
76
|
-
|
77
|
+
group.add_field(field)
|
78
|
+
end
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
&block
|
82
|
-
)
|
83
|
-
end
|
80
|
+
if block
|
81
|
+
dsl = Group.new(@setup, group)
|
82
|
+
Sunspot::Util.instance_eval_or_call(dsl, &block)
|
84
83
|
end
|
84
|
+
|
85
|
+
@query.add_group(group)
|
86
|
+
@search.add_group(group)
|
85
87
|
end
|
86
88
|
|
87
89
|
#
|
data/lib/sunspot/dsl/fulltext.rb
CHANGED
@@ -168,8 +168,12 @@ module Sunspot
|
|
168
168
|
# will be boosted by (average_rating + popularity * 10).
|
169
169
|
#
|
170
170
|
def boost(factor_or_function, &block)
|
171
|
+
additive_boost(factor_or_function, &block)
|
172
|
+
end
|
173
|
+
|
174
|
+
def additive_boost(factor_or_function, &block)
|
171
175
|
if factor_or_function.is_a?(Sunspot::Query::FunctionQuery)
|
172
|
-
@query.
|
176
|
+
@query.add_additive_boost_function(factor_or_function)
|
173
177
|
else
|
174
178
|
Sunspot::Util.instance_eval_or_call(
|
175
179
|
Scope.new(@query.create_boost_query(factor_or_function), @setup),
|
@@ -178,6 +182,10 @@ module Sunspot
|
|
178
182
|
end
|
179
183
|
end
|
180
184
|
|
185
|
+
def multiplicative_boost(factor_or_function)
|
186
|
+
@query.add_multiplicative_boost_function(factor_or_function)
|
187
|
+
end
|
188
|
+
|
181
189
|
#
|
182
190
|
# Add boost to certain fields, without restricting which fields are
|
183
191
|
# searched.
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module DSL
|
3
|
+
class Group
|
4
|
+
def initialize(setup, group)
|
5
|
+
@setup, @group = setup, group
|
6
|
+
end
|
7
|
+
|
8
|
+
# Specify one or more fields for result grouping.
|
9
|
+
#
|
10
|
+
# ==== Parameters
|
11
|
+
#
|
12
|
+
# field_names...<Symbol>:: the fields to use for grouping
|
13
|
+
#
|
14
|
+
def field(*field_names, &block)
|
15
|
+
field_names.each do |field_name|
|
16
|
+
field = @setup.field(field_name)
|
17
|
+
@group.add_field(field)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Specify a query to group results by.
|
22
|
+
#
|
23
|
+
# ==== Parameters
|
24
|
+
#
|
25
|
+
# label<Object>:: a label for this group; when #value is called on this
|
26
|
+
# group's results, this label will be returned.
|
27
|
+
#
|
28
|
+
def query(label, &block)
|
29
|
+
group_query = Sunspot::Query::GroupQuery.new(label)
|
30
|
+
Sunspot::Util.instance_eval_or_call(Scope.new(group_query, @setup), &block)
|
31
|
+
@group.add_query(group_query)
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Sets the number of results (documents) to return for each group.
|
36
|
+
# Defaults to 1.
|
37
|
+
#
|
38
|
+
def limit(num)
|
39
|
+
@group.limit = num
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# If set, facet counts are based on the most relevant document of
|
44
|
+
# each group matching the query.
|
45
|
+
#
|
46
|
+
# Supported in Solr 3.4 and above.
|
47
|
+
#
|
48
|
+
# ==== Example
|
49
|
+
#
|
50
|
+
# Sunspot.search(Post) do
|
51
|
+
# group :title do
|
52
|
+
# truncate
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# facet :title, :extra => :any
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
def truncate
|
59
|
+
@group.truncate = true
|
60
|
+
end
|
61
|
+
|
62
|
+
# Specify the order that results should be returned in. This method can
|
63
|
+
# be called multiple times; precedence will be in the order given.
|
64
|
+
#
|
65
|
+
# ==== Parameters
|
66
|
+
#
|
67
|
+
# field_name<Symbol>:: the field to use for ordering
|
68
|
+
# direction<Symbol>:: :asc or :desc (default :asc)
|
69
|
+
#
|
70
|
+
def order_by(field_name, direction = nil)
|
71
|
+
sort =
|
72
|
+
if special = Sunspot::Query::Sort.special(field_name)
|
73
|
+
special.new(direction)
|
74
|
+
else
|
75
|
+
Sunspot::Query::Sort::FieldSort.new(
|
76
|
+
@setup.field(field_name), direction
|
77
|
+
)
|
78
|
+
end
|
79
|
+
@group.add_sort(sort)
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Specify that results should be ordered based on a
|
84
|
+
# FunctionQuery - http://wiki.apache.org/solr/FunctionQuery
|
85
|
+
# Solr 3.1 and up
|
86
|
+
#
|
87
|
+
# For example, to order by field1 + (field2*field3):
|
88
|
+
#
|
89
|
+
# order_by_function :sum, :field1, [:product, :field2, :field3], :desc
|
90
|
+
#
|
91
|
+
# ==== Parameters
|
92
|
+
# function_name<Symbol>::
|
93
|
+
# the function to run
|
94
|
+
# arguments::
|
95
|
+
# the arguments for this function.
|
96
|
+
# - Symbol for a field or function name
|
97
|
+
# - Array for a nested function
|
98
|
+
# - String for a literal constant
|
99
|
+
# direction<Symbol>::
|
100
|
+
# :asc or :desc
|
101
|
+
def order_by_function(*args)
|
102
|
+
@group.add_sort(
|
103
|
+
Sunspot::Query::Sort::FunctionSort.new(@setup,args)
|
104
|
+
)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/sunspot/dsl/search.rb
CHANGED
data/lib/sunspot/dsl.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
%w(spellcheckable fields scope paginatable adjustable field_query
|
2
2
|
standard_query query_facet functional fulltext restriction
|
3
3
|
restriction_with_near search more_like_this_query function
|
4
|
-
|
4
|
+
group field_stats).each do |file|
|
5
5
|
require File.join(File.dirname(__FILE__), 'dsl', file)
|
6
6
|
end
|
@@ -22,6 +22,23 @@ module Sunspot
|
|
22
22
|
DataExtractor::AttributeExtractor.new(options.delete(:using) || name)
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Extract the encapsulated field's data from the given model and add it
|
28
|
+
# into the Solr document for indexing. (noop here for joins)
|
29
|
+
#
|
30
|
+
def populate_document(document, model, options = {}) #:nodoc:
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def extract_value(model, options = {})
|
36
|
+
if options.has_key?(:value)
|
37
|
+
options.delete(:value)
|
38
|
+
else
|
39
|
+
@data_extractor.value_for(model)
|
40
|
+
end
|
41
|
+
end
|
25
42
|
end
|
26
43
|
|
27
44
|
#
|
@@ -54,15 +71,16 @@ module Sunspot
|
|
54
71
|
# Extract the encapsulated field's data from the given model and add it
|
55
72
|
# into the Solr document for indexing.
|
56
73
|
#
|
57
|
-
def populate_document(document, model) #:nodoc:
|
58
|
-
|
74
|
+
def populate_document(document, model, options = {}) #:nodoc:
|
75
|
+
value = extract_value(model, options)
|
76
|
+
unless value.nil?
|
59
77
|
Util.Array(@field.to_indexed(value)).each do |scalar_value|
|
60
|
-
|
61
|
-
|
78
|
+
field_options = {}
|
79
|
+
field_options[:boost] = @field.boost if @field.boost
|
62
80
|
document.add_field(
|
63
81
|
@field.indexed_name.to_sym,
|
64
82
|
scalar_value,
|
65
|
-
options
|
83
|
+
field_options.merge(options)
|
66
84
|
)
|
67
85
|
end
|
68
86
|
end
|
@@ -92,14 +110,7 @@ module Sunspot
|
|
92
110
|
@field
|
93
111
|
end
|
94
112
|
|
95
|
-
#
|
96
|
-
# Extract the encapsulated field's data from the given model and add it
|
97
|
-
# into the Solr document for indexing. (noop here for joins)
|
98
113
|
#
|
99
|
-
def populate_document(document, model) #:nodoc:
|
100
|
-
end
|
101
|
-
|
102
|
-
#
|
103
114
|
# A unique signature identifying this field by name and type.
|
104
115
|
#
|
105
116
|
def signature
|
@@ -135,14 +146,16 @@ module Sunspot
|
|
135
146
|
# Generate dynamic fields based on hash returned by data accessor and
|
136
147
|
# add the field data to the document.
|
137
148
|
#
|
138
|
-
def populate_document(document, model)
|
139
|
-
|
149
|
+
def populate_document(document, model, options = {})
|
150
|
+
values = extract_value(model, options)
|
151
|
+
if values
|
140
152
|
values.each_pair do |dynamic_name, value|
|
141
153
|
field_instance = build(dynamic_name)
|
142
154
|
Util.Array(field_instance.to_indexed(value)).each do |scalar_value|
|
143
155
|
document.add_field(
|
144
156
|
field_instance.indexed_name.to_sym,
|
145
|
-
scalar_value
|
157
|
+
scalar_value,
|
158
|
+
options
|
146
159
|
)
|
147
160
|
end
|
148
161
|
end
|
data/lib/sunspot/indexer.rb
CHANGED
@@ -22,12 +22,23 @@ module Sunspot
|
|
22
22
|
# model<Object>:: the model to index
|
23
23
|
#
|
24
24
|
def add(model)
|
25
|
-
documents = Util.Array(model).map { |m|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
documents = Util.Array(model).map { |m| prepare_full_update(m) }
|
26
|
+
add_batch_documents(documents)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Construct a representation of the given class instances for atomic properties update
|
31
|
+
# and send it to the connection for indexing
|
32
|
+
#
|
33
|
+
# ==== Parameters
|
34
|
+
#
|
35
|
+
# clazz<Class>:: the class of the models to be updated
|
36
|
+
# updates<Hash>:: hash of updates where keys are model ids
|
37
|
+
# and values are hash with property name/values to be updated
|
38
|
+
#
|
39
|
+
def add_atomic_update(clazz, updates={})
|
40
|
+
documents = updates.map { |id, m| prepare_atomic_update(clazz, id, m) }
|
41
|
+
add_batch_documents(documents)
|
31
42
|
end
|
32
43
|
|
33
44
|
#
|
@@ -49,7 +60,7 @@ module Sunspot
|
|
49
60
|
)
|
50
61
|
end
|
51
62
|
|
52
|
-
#
|
63
|
+
#
|
53
64
|
# Delete all documents of the class indexed by this indexer from Solr.
|
54
65
|
#
|
55
66
|
def remove_all(clazz = nil)
|
@@ -90,9 +101,9 @@ module Sunspot
|
|
90
101
|
#
|
91
102
|
# Convert documents into hash of indexed properties
|
92
103
|
#
|
93
|
-
def
|
94
|
-
document = document_for(model)
|
95
|
-
setup =
|
104
|
+
def prepare_full_update(model)
|
105
|
+
document = document_for(model.class, model.id)
|
106
|
+
setup = setup_for_object(model)
|
96
107
|
if boost = setup.document_boost_for(model)
|
97
108
|
document.attrs[:boost] = boost
|
98
109
|
end
|
@@ -102,20 +113,40 @@ module Sunspot
|
|
102
113
|
document
|
103
114
|
end
|
104
115
|
|
116
|
+
def prepare_atomic_update(clazz, id, updates = {})
|
117
|
+
document = document_for(clazz, id)
|
118
|
+
setup_for_class(clazz).all_field_factories.each do |field_factory|
|
119
|
+
if updates.has_key?(field_factory.name)
|
120
|
+
field_factory.populate_document(document, nil, value: updates[field_factory.name], update: :set)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
document
|
124
|
+
end
|
125
|
+
|
105
126
|
def add_documents(documents)
|
106
127
|
@connection.add(documents)
|
107
128
|
end
|
108
129
|
|
130
|
+
def add_batch_documents(documents)
|
131
|
+
if batcher.batching?
|
132
|
+
batcher.concat(documents)
|
133
|
+
else
|
134
|
+
add_documents(documents)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
109
138
|
#
|
110
139
|
# All indexed documents index and store the +id+ and +type+ fields.
|
111
140
|
# This method constructs the document hash containing those key-value
|
112
141
|
# pairs.
|
113
142
|
#
|
114
|
-
def document_for(
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
143
|
+
def document_for(clazz, id)
|
144
|
+
if Adapters::InstanceAdapter.for(clazz)
|
145
|
+
RSolr::Xml::Document.new(
|
146
|
+
id: Adapters::InstanceAdapter.index_id_for(clazz.name, id),
|
147
|
+
type: Util.superclasses_for(clazz).map(&:name)
|
148
|
+
)
|
149
|
+
end
|
119
150
|
end
|
120
151
|
|
121
152
|
#
|
@@ -129,8 +160,23 @@ module Sunspot
|
|
129
160
|
#
|
130
161
|
# Sunspot::Setup:: The setup for the object's class
|
131
162
|
#
|
132
|
-
def
|
133
|
-
|
163
|
+
def setup_for_object(object)
|
164
|
+
setup_for_class(object.class)
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# Get the Setup object for the given class.
|
169
|
+
#
|
170
|
+
# ==== Parameters
|
171
|
+
#
|
172
|
+
# clazz<Class>:: The class whose setup is to be retrieved
|
173
|
+
#
|
174
|
+
# ==== Returns
|
175
|
+
#
|
176
|
+
# Sunspot::Setup:: The setup for the class
|
177
|
+
#
|
178
|
+
def setup_for_class(clazz)
|
179
|
+
Setup.for(clazz) || raise(NoSetupError, "Sunspot is not configured for #{clazz.inspect}")
|
134
180
|
end
|
135
181
|
end
|
136
182
|
end
|
@@ -18,8 +18,15 @@ module Sunspot
|
|
18
18
|
#
|
19
19
|
# Add a boost function
|
20
20
|
#
|
21
|
-
def
|
22
|
-
@
|
21
|
+
def add_additive_boost_function(function_query)
|
22
|
+
@additive_boost_functions << function_query
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Add a multiplicative boost function
|
27
|
+
#
|
28
|
+
def add_multiplicative_boost_function(function_query)
|
29
|
+
@multiplicative_boost_functions << function_query
|
23
30
|
end
|
24
31
|
|
25
32
|
#
|
data/lib/sunspot/query/dismax.rb
CHANGED
@@ -13,7 +13,8 @@ module Sunspot
|
|
13
13
|
@keywords = keywords
|
14
14
|
@fulltext_fields = {}
|
15
15
|
@boost_queries = []
|
16
|
-
@
|
16
|
+
@additive_boost_functions = []
|
17
|
+
@multiplicative_boost_functions = []
|
17
18
|
@highlights = []
|
18
19
|
|
19
20
|
@minimum_match = nil
|
@@ -46,9 +47,15 @@ module Sunspot
|
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
|
-
unless @
|
50
|
-
params[:bf] = @
|
51
|
-
|
50
|
+
unless @additive_boost_functions.empty?
|
51
|
+
params[:bf] = @additive_boost_functions.map do |additive_boost_function|
|
52
|
+
additive_boost_function.to_s
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
unless @multiplicative_boost_functions.empty?
|
57
|
+
params[:boost] = @multiplicative_boost_functions.map do |multiplicative_boost_function|
|
58
|
+
multiplicative_boost_function.to_s
|
52
59
|
end
|
53
60
|
end
|
54
61
|
|
@@ -1,18 +1,27 @@
|
|
1
1
|
module Sunspot
|
2
2
|
module Query
|
3
3
|
#
|
4
|
-
# A
|
4
|
+
# A Group groups by the unique values of a given field, or by given queries.
|
5
5
|
#
|
6
|
-
class
|
6
|
+
class Group
|
7
7
|
attr_accessor :limit, :truncate
|
8
|
+
attr_reader :fields, :queries
|
8
9
|
|
9
|
-
def initialize
|
10
|
+
def initialize
|
11
|
+
@sort = SortComposite.new
|
12
|
+
@fields = []
|
13
|
+
@queries = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_field(field)
|
10
17
|
if field.multiple?
|
11
18
|
raise(ArgumentError, "#{field.name} cannot be used for grouping because it is a multiple-value field")
|
12
19
|
end
|
13
|
-
@
|
20
|
+
@fields << field
|
21
|
+
end
|
14
22
|
|
15
|
-
|
23
|
+
def add_query(query)
|
24
|
+
@queries << query
|
16
25
|
end
|
17
26
|
|
18
27
|
def add_sort(sort)
|
@@ -23,10 +32,11 @@ module Sunspot
|
|
23
32
|
params = {
|
24
33
|
:group => "true",
|
25
34
|
:"group.ngroups" => "true",
|
26
|
-
:"group.field" => @field.indexed_name
|
27
35
|
}
|
28
36
|
|
29
37
|
params.merge!(@sort.to_params("group."))
|
38
|
+
params[:"group.field"] = @fields.map(&:indexed_name) if @fields.any?
|
39
|
+
params[:"group.query"] = @queries.map(&:to_boolean_phrase) if @queries.any?
|
30
40
|
params[:"group.limit"] = @limit if @limit
|
31
41
|
params[:"group.truncate"] = @truncate if @truncate
|
32
42
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Query
|
3
|
+
#
|
4
|
+
# Representation of a GroupQuery, which allows the searcher to specify a
|
5
|
+
# query to group matching documents. This is essentially a conjunction,
|
6
|
+
# with an extra instance variable containing the label for the group.
|
7
|
+
#
|
8
|
+
class GroupQuery < Connective::Conjunction #:nodoc:
|
9
|
+
attr_reader :label
|
10
|
+
|
11
|
+
def initialize(label, negated = false)
|
12
|
+
super(negated)
|
13
|
+
@label = label
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -11,7 +11,7 @@ module Sunspot
|
|
11
11
|
# Array:: Collection of restriction class names
|
12
12
|
#
|
13
13
|
def names
|
14
|
-
constants -
|
14
|
+
constants - abstract_constants
|
15
15
|
end
|
16
16
|
|
17
17
|
#
|
@@ -22,6 +22,17 @@ module Sunspot
|
|
22
22
|
@types ||= {}
|
23
23
|
@types[restriction_name.to_sym] ||= const_get(Sunspot::Util.camel_case(restriction_name.to_s))
|
24
24
|
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
#
|
29
|
+
# Return the names of all abstract restriction classes that should not
|
30
|
+
# be made available to the DSL. Considers abstract classes are any class
|
31
|
+
# ending with '::Base' or containing a namespace prefixed with 'Abstract'
|
32
|
+
#
|
33
|
+
def abstract_constants
|
34
|
+
constants.grep(/(^|::)(Base$|Abstract)/)
|
35
|
+
end
|
25
36
|
end
|
26
37
|
|
27
38
|
#
|
@@ -330,6 +341,39 @@ module Sunspot
|
|
330
341
|
"#{solr_value(@value)}*"
|
331
342
|
end
|
332
343
|
end
|
344
|
+
|
345
|
+
class AbstractRange < Between
|
346
|
+
private
|
347
|
+
|
348
|
+
def operation
|
349
|
+
@operation || self.class.name.split('::').last
|
350
|
+
end
|
351
|
+
|
352
|
+
def solr_value(value = @value)
|
353
|
+
@field.to_indexed(value)
|
354
|
+
end
|
355
|
+
|
356
|
+
def to_positive_boolean_phrase
|
357
|
+
"_query_:\"{!field f=#{@field.indexed_name} op=#{operation}}#{solr_value}\""
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
class Containing < AbstractRange
|
362
|
+
def initialize(negated, field, value)
|
363
|
+
@operation = 'Contains'
|
364
|
+
super
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
class Intersecting < AbstractRange
|
369
|
+
def initialize(negated, field, value)
|
370
|
+
@operation = 'Intersects'
|
371
|
+
super
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
class Within < AbstractRange
|
376
|
+
end
|
333
377
|
end
|
334
378
|
end
|
335
379
|
end
|
data/lib/sunspot/query.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
field_facet highlighting pagination restriction common_query spellcheck
|
3
3
|
standard_query more_like_this more_like_this_query geo geofilt bbox query_facet
|
4
4
|
scope sort sort_composite text_field_boost function_query field_stats
|
5
|
-
composite_fulltext
|
5
|
+
composite_fulltext group group_query).each do |file|
|
6
6
|
require(File.join(File.dirname(__FILE__), 'query', file))
|
7
7
|
end
|
8
8
|
module Sunspot
|
data/lib/sunspot/schema.rb
CHANGED
@@ -23,7 +23,8 @@ module Sunspot
|
|
23
23
|
FieldType.new('slong', 'SortableLong', 'l'),
|
24
24
|
FieldType.new('tint', 'TrieInteger', 'it'),
|
25
25
|
FieldType.new('tfloat', 'TrieFloat', 'ft'),
|
26
|
-
FieldType.new('tdate', 'TrieInt', 'dt')
|
26
|
+
FieldType.new('tdate', 'TrieInt', 'dt'),
|
27
|
+
FieldType.new('daterange', 'DateRange', 'dr')
|
27
28
|
|
28
29
|
]
|
29
30
|
|
@@ -222,8 +222,12 @@ module Sunspot
|
|
222
222
|
"<Sunspot::Search:#{query.to_params.inspect}>"
|
223
223
|
end
|
224
224
|
|
225
|
-
def
|
226
|
-
|
225
|
+
def add_group(group) #:nodoc:
|
226
|
+
group.fields.each do |field|
|
227
|
+
add_subgroup(field.name, FieldGroup.new(field, self))
|
228
|
+
end
|
229
|
+
|
230
|
+
add_subgroup(:queries, QueryGroup.new(group.queries, self)) if group.queries.any?
|
227
231
|
end
|
228
232
|
|
229
233
|
def add_field_facet(field, options = {}) #:nodoc:
|
@@ -303,7 +307,7 @@ module Sunspot
|
|
303
307
|
@stats_by_name[name.to_sym] = stats
|
304
308
|
end
|
305
309
|
|
306
|
-
def
|
310
|
+
def add_subgroup(name, group)
|
307
311
|
@groups << group
|
308
312
|
@groups_by_name[name.to_sym] = group
|
309
313
|
end
|