thinking-sphinx 2.0.2 → 2.0.3
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/README.textile +6 -0
- data/VERSION +1 -1
- data/features/attribute_updates.feature +3 -3
- data/features/handling_edits.feature +5 -3
- data/features/thinking_sphinx/models/beta.rb +5 -0
- data/features/thinking_sphinx/models/developer.rb +11 -0
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record.rb +19 -18
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +1 -1
- data/lib/thinking_sphinx/active_record/delta.rb +10 -6
- data/lib/thinking_sphinx/active_record/has_many_association.rb +1 -16
- data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +21 -0
- data/lib/thinking_sphinx/active_record/scopes.rb +11 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +3 -1
- data/lib/thinking_sphinx/auto_version.rb +4 -1
- data/lib/thinking_sphinx/core/array.rb +1 -1
- data/lib/thinking_sphinx/search.rb +61 -29
- data/spec/thinking_sphinx/active_record/delta_spec.rb +1 -1
- data/spec/thinking_sphinx/active_record_spec.rb +6 -44
- data/spec/thinking_sphinx/auto_version_spec.rb +1 -1
- data/spec/thinking_sphinx/facet_search_spec.rb +8 -0
- data/spec/thinking_sphinx/search_spec.rb +30 -0
- metadata +5 -4
data/README.textile
CHANGED
|
@@ -197,3 +197,9 @@ Since I first released this library, there's been quite a few people who have su
|
|
|
197
197
|
* Robert Glaser
|
|
198
198
|
* Brenton Fletcher
|
|
199
199
|
* Paul Schyska
|
|
200
|
+
* Kirill Maximov
|
|
201
|
+
* Hans Hasselberg
|
|
202
|
+
* Robert Stern
|
|
203
|
+
* George Anderson
|
|
204
|
+
* Greg Weber
|
|
205
|
+
* Javier Ramírez
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.0.
|
|
1
|
+
2.0.3
|
|
@@ -36,7 +36,7 @@ Feature: Update attributes directly to Sphinx
|
|
|
36
36
|
And I filter by 18 on value
|
|
37
37
|
Then I should get 1 result
|
|
38
38
|
|
|
39
|
-
When I search for the document id of beta eight in the
|
|
39
|
+
When I search for the document id of beta eight in the secondary_beta_delta index
|
|
40
40
|
Then it should not exist
|
|
41
41
|
|
|
42
42
|
Scenario: Updating attributes in a delta index
|
|
@@ -48,7 +48,7 @@ Feature: Update attributes directly to Sphinx
|
|
|
48
48
|
And I wait for Sphinx to catch up
|
|
49
49
|
|
|
50
50
|
When I filter by 19 on value
|
|
51
|
-
And I use index
|
|
51
|
+
And I use index secondary_beta_delta
|
|
52
52
|
Then I should get 1 result
|
|
53
53
|
|
|
54
54
|
Scenario: Updating attributes in a delta index with deltas disabled
|
|
@@ -61,7 +61,7 @@ Feature: Update attributes directly to Sphinx
|
|
|
61
61
|
And I wait for Sphinx to catch up
|
|
62
62
|
|
|
63
63
|
When I filter by 21 on value
|
|
64
|
-
And I use index
|
|
64
|
+
And I use index secondary_beta_delta
|
|
65
65
|
Then I should get 1 result
|
|
66
66
|
And I enable delta updates
|
|
67
67
|
|
|
@@ -31,12 +31,12 @@ Feature: Keeping Sphinx in line with model changes when requested
|
|
|
31
31
|
When I search for one
|
|
32
32
|
Then I should get 1 result
|
|
33
33
|
|
|
34
|
-
When I change the name of beta one to
|
|
34
|
+
When I change the name of beta one to eleventeen
|
|
35
35
|
And I wait for Sphinx to catch up
|
|
36
36
|
And I search for one
|
|
37
37
|
Then I should get 0 results
|
|
38
38
|
|
|
39
|
-
When I search for
|
|
39
|
+
When I search for eleventeen
|
|
40
40
|
Then I should get 1 result
|
|
41
41
|
|
|
42
42
|
Scenario: Returning new records if there's a delta
|
|
@@ -63,7 +63,9 @@ Feature: Keeping Sphinx in line with model changes when requested
|
|
|
63
63
|
|
|
64
64
|
When I search for the document id of beta five in the beta_core index
|
|
65
65
|
Then it should exist if using Rails 2.1 or newer
|
|
66
|
-
When I search for the document id of beta five in the
|
|
66
|
+
When I search for the document id of beta five in the secondary_beta_core index
|
|
67
|
+
Then it should exist if using Rails 2.1 or newer
|
|
68
|
+
When I search for the document id of beta five in the secondary_beta_delta index
|
|
67
69
|
Then it should not exist if using Rails 2.1 or newer
|
|
68
70
|
|
|
69
71
|
Scenario: Handling edits with a delta when Sphinx isn't running
|
|
@@ -17,4 +17,15 @@ class Developer < ActiveRecord::Base
|
|
|
17
17
|
|
|
18
18
|
group_by 'city'
|
|
19
19
|
end
|
|
20
|
+
|
|
21
|
+
define_index 'alternate' do
|
|
22
|
+
indexes "'foo'", :as => :foo
|
|
23
|
+
|
|
24
|
+
has age, :facet => true
|
|
25
|
+
has tags(:id), :as => :tag_ids, :facet => true
|
|
26
|
+
|
|
27
|
+
facet "LOWER(city)", :as => :city, :type => :string, :value => :city
|
|
28
|
+
|
|
29
|
+
group_by 'city'
|
|
30
|
+
end
|
|
20
31
|
end
|
data/lib/thinking_sphinx.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'thinking_sphinx/active_record/attribute_updates'
|
|
|
2
2
|
require 'thinking_sphinx/active_record/delta'
|
|
3
3
|
require 'thinking_sphinx/active_record/has_many_association'
|
|
4
4
|
require 'thinking_sphinx/active_record/log_subscriber'
|
|
5
|
+
require 'thinking_sphinx/active_record/has_many_association_with_scopes'
|
|
5
6
|
require 'thinking_sphinx/active_record/scopes'
|
|
6
7
|
|
|
7
8
|
module ThinkingSphinx
|
|
@@ -24,7 +25,18 @@ module ThinkingSphinx
|
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def primary_key_for_sphinx
|
|
27
|
-
|
|
28
|
+
if custom_primary_key_for_sphinx?
|
|
29
|
+
@sphinx_primary_key_attribute || superclass.primary_key_for_sphinx
|
|
30
|
+
else
|
|
31
|
+
primary_key
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def custom_primary_key_for_sphinx?
|
|
36
|
+
(
|
|
37
|
+
superclass.respond_to?(:custom_primary_key_for_sphinx?) &&
|
|
38
|
+
superclass.custom_primary_key_for_sphinx?
|
|
39
|
+
) || !@sphinx_primary_key_attribute.nil?
|
|
28
40
|
end
|
|
29
41
|
|
|
30
42
|
def sphinx_index_options
|
|
@@ -46,8 +58,7 @@ module ThinkingSphinx
|
|
|
46
58
|
end
|
|
47
59
|
|
|
48
60
|
def sphinx_database_adapter
|
|
49
|
-
|
|
50
|
-
ThinkingSphinx::AbstractAdapter.detect(self)
|
|
61
|
+
ThinkingSphinx::AbstractAdapter.detect(self)
|
|
51
62
|
end
|
|
52
63
|
|
|
53
64
|
def sphinx_name
|
|
@@ -315,22 +326,12 @@ module ThinkingSphinx
|
|
|
315
326
|
attr_accessor :sphinx_attributes
|
|
316
327
|
attr_accessor :matching_fields
|
|
317
328
|
|
|
318
|
-
def in_index?(
|
|
319
|
-
self.class.search_for_id self.sphinx_document_id,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
def in_core_index?
|
|
323
|
-
in_index? "core"
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
def in_delta_index?
|
|
327
|
-
in_index? "delta"
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
def in_both_indexes?
|
|
331
|
-
in_core_index? && in_delta_index?
|
|
329
|
+
def in_index?(index)
|
|
330
|
+
self.class.search_for_id self.sphinx_document_id, index
|
|
331
|
+
rescue Riddle::ResponseError
|
|
332
|
+
true
|
|
332
333
|
end
|
|
333
|
-
|
|
334
|
+
|
|
334
335
|
def toggle_deleted
|
|
335
336
|
return unless ThinkingSphinx.updates_enabled?
|
|
336
337
|
|
|
@@ -43,7 +43,7 @@ module ThinkingSphinx
|
|
|
43
43
|
config = ThinkingSphinx::Configuration.instance
|
|
44
44
|
config.client.update index_name, attribute_names, {
|
|
45
45
|
sphinx_document_id => attribute_values
|
|
46
|
-
} if
|
|
46
|
+
} if in_index?(index_name)
|
|
47
47
|
rescue Riddle::ConnectionError, ThinkingSphinx::SphinxError
|
|
48
48
|
# Not the end of the world if Sphinx isn't running.
|
|
49
49
|
end
|
|
@@ -16,30 +16,34 @@ module ThinkingSphinx
|
|
|
16
16
|
# if running in the test environment.
|
|
17
17
|
#
|
|
18
18
|
def index_delta(instance = nil)
|
|
19
|
-
|
|
19
|
+
delta_objects.each { |obj| obj.index(self, instance) }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def
|
|
23
|
-
self.sphinx_indexes.
|
|
22
|
+
def delta_objects
|
|
23
|
+
self.sphinx_indexes.collect(&:delta_object).compact
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def toggled_delta?
|
|
28
|
-
self.class.
|
|
28
|
+
self.class.delta_objects.any? { |obj| obj.toggled(self) }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
private
|
|
32
32
|
|
|
33
33
|
# Set the delta value for the model to be true.
|
|
34
34
|
def toggle_delta
|
|
35
|
-
self.class.
|
|
35
|
+
self.class.delta_objects.each { |obj|
|
|
36
|
+
obj.toggle(self)
|
|
37
|
+
} if should_toggle_delta?
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
# Build the delta index for the related model. This won't be called
|
|
39
41
|
# if running in the test environment.
|
|
40
42
|
#
|
|
41
43
|
def index_delta
|
|
42
|
-
self.class.index_delta(self) if self.class.
|
|
44
|
+
self.class.index_delta(self) if self.class.delta_objects.any? { |obj|
|
|
45
|
+
obj.toggled(self)
|
|
46
|
+
}
|
|
43
47
|
end
|
|
44
48
|
|
|
45
49
|
def should_toggle_delta?
|
|
@@ -9,17 +9,7 @@ module ThinkingSphinx
|
|
|
9
9
|
args << options
|
|
10
10
|
@reflection.klass.search(*args)
|
|
11
11
|
end
|
|
12
|
-
|
|
13
|
-
def method_missing(method, *args, &block)
|
|
14
|
-
if responds_to_scope(method)
|
|
15
|
-
@reflection.klass.
|
|
16
|
-
search(:with => default_filter).
|
|
17
|
-
send(method, *args, &block)
|
|
18
|
-
else
|
|
19
|
-
super
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
12
|
+
|
|
23
13
|
private
|
|
24
14
|
|
|
25
15
|
def attribute_for_foreign_key
|
|
@@ -41,11 +31,6 @@ module ThinkingSphinx
|
|
|
41
31
|
def default_filter
|
|
42
32
|
{attribute_for_foreign_key.unique_name => @owner.id}
|
|
43
33
|
end
|
|
44
|
-
|
|
45
|
-
def responds_to_scope(scope)
|
|
46
|
-
@reflection.klass.respond_to?(:sphinx_scopes) &&
|
|
47
|
-
@reflection.klass.sphinx_scopes.include?(scope)
|
|
48
|
-
end
|
|
49
34
|
end
|
|
50
35
|
end
|
|
51
36
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module ThinkingSphinx
|
|
2
|
+
module ActiveRecord
|
|
3
|
+
module HasManyAssociationWithScopes
|
|
4
|
+
def method_missing(method, *args, &block)
|
|
5
|
+
if responds_to_scope(method)
|
|
6
|
+
@reflection.klass.
|
|
7
|
+
search(:with => default_filter).
|
|
8
|
+
send(method, *args, &block)
|
|
9
|
+
else
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
def responds_to_scope(scope)
|
|
16
|
+
@reflection.klass.respond_to?(:sphinx_scopes) &&
|
|
17
|
+
@reflection.klass.sphinx_scopes.include?(scope)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -17,6 +17,7 @@ module ThinkingSphinx
|
|
|
17
17
|
# The scope is automatically applied when the search method is called. It
|
|
18
18
|
# will only be applied if it is an existing sphinx_scope.
|
|
19
19
|
def default_sphinx_scope(sphinx_scope_name)
|
|
20
|
+
add_sphinx_scopes_support_to_has_many_associations
|
|
20
21
|
@default_sphinx_scope = sphinx_scope_name
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -43,6 +44,8 @@ module ThinkingSphinx
|
|
|
43
44
|
# @articles = Article.latest_first.search 'pancakes'
|
|
44
45
|
#
|
|
45
46
|
def sphinx_scope(method, &block)
|
|
47
|
+
add_sphinx_scopes_support_to_has_many_associations
|
|
48
|
+
|
|
46
49
|
@sphinx_scopes ||= []
|
|
47
50
|
@sphinx_scopes << method
|
|
48
51
|
|
|
@@ -76,6 +79,14 @@ module ThinkingSphinx
|
|
|
76
79
|
|
|
77
80
|
sphinx_scopes.clear
|
|
78
81
|
end
|
|
82
|
+
|
|
83
|
+
def add_sphinx_scopes_support_to_has_many_associations
|
|
84
|
+
scope_mixin = ::ThinkingSphinx::ActiveRecord::HasManyAssociationWithScopes
|
|
85
|
+
|
|
86
|
+
::ActiveRecord::Associations::HasManyAssociation.send(:include, scope_mixin)
|
|
87
|
+
::ActiveRecord::Associations::HasManyThroughAssociation.send(:include, scope_mixin)
|
|
88
|
+
end
|
|
89
|
+
|
|
79
90
|
end
|
|
80
91
|
end
|
|
81
92
|
end
|
|
@@ -117,6 +117,7 @@ module ThinkingSphinx
|
|
|
117
117
|
DECLARE tmp bigint;
|
|
118
118
|
DECLARE i int;
|
|
119
119
|
DECLARE j int;
|
|
120
|
+
DECLARE byte_length int;
|
|
120
121
|
DECLARE word_array bytea;
|
|
121
122
|
BEGIN
|
|
122
123
|
IF COALESCE(word, '') = '' THEN
|
|
@@ -125,6 +126,7 @@ module ThinkingSphinx
|
|
|
125
126
|
|
|
126
127
|
i = 0;
|
|
127
128
|
tmp = 4294967295;
|
|
129
|
+
byte_length = bit_length(word) / 8;
|
|
128
130
|
word_array = decode(replace(word, E'\\\\', E'\\\\\\\\'), 'escape');
|
|
129
131
|
LOOP
|
|
130
132
|
tmp = (tmp # get_byte(word_array, i))::bigint;
|
|
@@ -137,7 +139,7 @@ module ThinkingSphinx
|
|
|
137
139
|
EXIT;
|
|
138
140
|
END IF;
|
|
139
141
|
END LOOP;
|
|
140
|
-
IF i >=
|
|
142
|
+
IF i >= byte_length THEN
|
|
141
143
|
EXIT;
|
|
142
144
|
END IF;
|
|
143
145
|
END LOOP;
|
|
@@ -5,9 +5,12 @@ module ThinkingSphinx
|
|
|
5
5
|
case version
|
|
6
6
|
when '0.9.8', '0.9.9'
|
|
7
7
|
require "riddle/#{version}"
|
|
8
|
-
when '1.10-beta', '1.10-id64-beta'
|
|
8
|
+
when '1.10-beta', '1.10-id64-beta', '1.10-dev'
|
|
9
9
|
require 'riddle/1.10'
|
|
10
10
|
else
|
|
11
|
+
unless version.nil? or version.empty?
|
|
12
|
+
STDERR.puts "Unsupported version: #{version}"
|
|
13
|
+
end
|
|
11
14
|
STDERR.puts %Q{
|
|
12
15
|
Sphinx cannot be found on your system. You may need to configure the following
|
|
13
16
|
settings in your config/sphinx.yml file:
|
|
@@ -30,31 +30,31 @@ module ThinkingSphinx
|
|
|
30
30
|
# Deprecated. Use ThinkingSphinx.search
|
|
31
31
|
def self.search(*args)
|
|
32
32
|
warn 'ThinkingSphinx::Search.search is deprecated. Please use ThinkingSphinx.search instead.'
|
|
33
|
-
ThinkingSphinx.search
|
|
33
|
+
ThinkingSphinx.search(*args)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Deprecated. Use ThinkingSphinx.search_for_ids
|
|
37
37
|
def self.search_for_ids(*args)
|
|
38
38
|
warn 'ThinkingSphinx::Search.search_for_ids is deprecated. Please use ThinkingSphinx.search_for_ids instead.'
|
|
39
|
-
ThinkingSphinx.search_for_ids
|
|
39
|
+
ThinkingSphinx.search_for_ids(*args)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
# Deprecated. Use ThinkingSphinx.search_for_ids
|
|
43
43
|
def self.search_for_id(*args)
|
|
44
44
|
warn 'ThinkingSphinx::Search.search_for_id is deprecated. Please use ThinkingSphinx.search_for_id instead.'
|
|
45
|
-
ThinkingSphinx.search_for_id
|
|
45
|
+
ThinkingSphinx.search_for_id(*args)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# Deprecated. Use ThinkingSphinx.count
|
|
49
49
|
def self.count(*args)
|
|
50
50
|
warn 'ThinkingSphinx::Search.count is deprecated. Please use ThinkingSphinx.count instead.'
|
|
51
|
-
ThinkingSphinx.count
|
|
51
|
+
ThinkingSphinx.count(*args)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# Deprecated. Use ThinkingSphinx.facets
|
|
55
55
|
def self.facets(*args)
|
|
56
56
|
warn 'ThinkingSphinx::Search.facets is deprecated. Please use ThinkingSphinx.facets instead.'
|
|
57
|
-
ThinkingSphinx.facets
|
|
57
|
+
ThinkingSphinx.facets(*args)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def self.warn(message)
|
|
@@ -202,6 +202,12 @@ module ThinkingSphinx
|
|
|
202
202
|
@options[:page].blank? ? 1 : @options[:page].to_i
|
|
203
203
|
end
|
|
204
204
|
|
|
205
|
+
# Kaminari support
|
|
206
|
+
def page(page_number)
|
|
207
|
+
@options[:page] = page_number
|
|
208
|
+
self
|
|
209
|
+
end
|
|
210
|
+
|
|
205
211
|
# The next page number of the result set. If there are no more pages
|
|
206
212
|
# available, nil is returned.
|
|
207
213
|
#
|
|
@@ -230,6 +236,14 @@ module ThinkingSphinx
|
|
|
230
236
|
@options[:limit] ||= 20
|
|
231
237
|
@options[:limit].to_i
|
|
232
238
|
end
|
|
239
|
+
# Kaminari support
|
|
240
|
+
alias_method :limit_value, :per_page
|
|
241
|
+
|
|
242
|
+
# Kaminari support
|
|
243
|
+
def per(limit)
|
|
244
|
+
@options[:limit] = limit
|
|
245
|
+
self
|
|
246
|
+
end
|
|
233
247
|
|
|
234
248
|
# The total number of pages available if the results are paginated.
|
|
235
249
|
#
|
|
@@ -241,8 +255,9 @@ module ThinkingSphinx
|
|
|
241
255
|
|
|
242
256
|
@total_pages ||= (@results[:total] / per_page.to_f).ceil
|
|
243
257
|
end
|
|
244
|
-
# Compatibility with older versions of will_paginate
|
|
258
|
+
# Compatibility with kaminari and older versions of will_paginate
|
|
245
259
|
alias_method :page_count, :total_pages
|
|
260
|
+
alias_method :num_pages, :total_pages
|
|
246
261
|
|
|
247
262
|
# Query time taken
|
|
248
263
|
#
|
|
@@ -318,7 +333,7 @@ module ThinkingSphinx
|
|
|
318
333
|
{
|
|
319
334
|
:docs => [string.to_s],
|
|
320
335
|
:words => results[:words].keys.join(' '),
|
|
321
|
-
:index => options[:index] || "#{model.
|
|
336
|
+
:index => options[:index] || "#{model.core_index_names.first}"
|
|
322
337
|
}.merge(options[:excerpt_options] || {})
|
|
323
338
|
).first
|
|
324
339
|
end
|
|
@@ -343,7 +358,7 @@ module ThinkingSphinx
|
|
|
343
358
|
merge_search self, args, options
|
|
344
359
|
args << options
|
|
345
360
|
|
|
346
|
-
ThinkingSphinx::FacetSearch.new
|
|
361
|
+
ThinkingSphinx::FacetSearch.new(*args)
|
|
347
362
|
end
|
|
348
363
|
|
|
349
364
|
def client
|
|
@@ -363,16 +378,7 @@ module ThinkingSphinx
|
|
|
363
378
|
@populated = true
|
|
364
379
|
@results = results
|
|
365
380
|
|
|
366
|
-
|
|
367
|
-
replace @results[:matches].collect { |match|
|
|
368
|
-
match[:attributes]["sphinx_internal_id"]
|
|
369
|
-
}
|
|
370
|
-
else
|
|
371
|
-
replace instances_from_matches
|
|
372
|
-
add_excerpter
|
|
373
|
-
add_sphinx_attributes
|
|
374
|
-
add_matching_fields if client.rank_mode == :fieldmask
|
|
375
|
-
end
|
|
381
|
+
compose_results
|
|
376
382
|
end
|
|
377
383
|
|
|
378
384
|
private
|
|
@@ -403,18 +409,44 @@ module ThinkingSphinx
|
|
|
403
409
|
raise ThinkingSphinx::ConnectionError,
|
|
404
410
|
'Connection to Sphinx Daemon (searchd) failed.'
|
|
405
411
|
end
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
412
|
+
|
|
413
|
+
compose_results
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def compose_results
|
|
418
|
+
if options[:ids_only]
|
|
419
|
+
compose_ids_results
|
|
420
|
+
elsif options[:only]
|
|
421
|
+
compose_only_results
|
|
422
|
+
else
|
|
423
|
+
replace instances_from_matches
|
|
424
|
+
add_excerpter
|
|
425
|
+
add_sphinx_attributes
|
|
426
|
+
add_matching_fields if client.rank_mode == :fieldmask
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
def compose_ids_results
|
|
431
|
+
replace @results[:matches].collect { |match|
|
|
432
|
+
match[:attributes]['sphinx_internal_id']
|
|
433
|
+
}
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def compose_only_results
|
|
437
|
+
replace @results[:matches].collect { |match|
|
|
438
|
+
case only = options[:only]
|
|
439
|
+
when String, Symbol
|
|
440
|
+
match[:attributes][only.to_s]
|
|
441
|
+
when Array
|
|
442
|
+
only.inject({}) do |hash, attribute|
|
|
443
|
+
hash[attribute.to_sym] = match[:attributes][attribute.to_s]
|
|
444
|
+
hash
|
|
445
|
+
end
|
|
411
446
|
else
|
|
412
|
-
|
|
413
|
-
add_excerpter
|
|
414
|
-
add_sphinx_attributes
|
|
415
|
-
add_matching_fields if client.rank_mode == :fieldmask
|
|
447
|
+
raise "Unexpected object for :only argument. String or Array is expected, #{only.class} was received."
|
|
416
448
|
end
|
|
417
|
-
|
|
449
|
+
}
|
|
418
450
|
end
|
|
419
451
|
|
|
420
452
|
def add_excerpter
|
|
@@ -908,7 +940,7 @@ module ThinkingSphinx
|
|
|
908
940
|
end
|
|
909
941
|
|
|
910
942
|
def scoped_count
|
|
911
|
-
return self.total_entries if
|
|
943
|
+
return self.total_entries if(@options[:ids_only] || @options[:only])
|
|
912
944
|
|
|
913
945
|
@options[:ids_only] = true
|
|
914
946
|
results_count = self.total_entries
|
|
@@ -70,7 +70,7 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
|
|
|
70
70
|
ThinkingSphinx.deltas_enabled = true
|
|
71
71
|
ThinkingSphinx.updates_enabled = true
|
|
72
72
|
ThinkingSphinx.stub!(:sphinx_running? => true)
|
|
73
|
-
Person.
|
|
73
|
+
Person.delta_objects.first.stub!(:` => "", :toggled => true)
|
|
74
74
|
|
|
75
75
|
@person = Person.new
|
|
76
76
|
Person.stub!(:search_for_id => false)
|
|
@@ -234,50 +234,6 @@ describe ThinkingSphinx::ActiveRecord do
|
|
|
234
234
|
Beta.sphinx_indexes.length.should == 1
|
|
235
235
|
end
|
|
236
236
|
end
|
|
237
|
-
|
|
238
|
-
describe "index methods" do
|
|
239
|
-
before(:all) do
|
|
240
|
-
@person = Person.find(:first)
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
describe "in_both_indexes?" do
|
|
244
|
-
it "should return true if in core and delta indexes" do
|
|
245
|
-
@person.should_receive(:in_core_index?).and_return(true)
|
|
246
|
-
@person.should_receive(:in_delta_index?).and_return(true)
|
|
247
|
-
@person.in_both_indexes?.should be_true
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
it "should return false if in one index and not the other" do
|
|
251
|
-
@person.should_receive(:in_core_index?).and_return(true)
|
|
252
|
-
@person.should_receive(:in_delta_index?).and_return(false)
|
|
253
|
-
@person.in_both_indexes?.should be_false
|
|
254
|
-
end
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
describe "in_core_index?" do
|
|
258
|
-
it "should call in_index? with core" do
|
|
259
|
-
@person.should_receive(:in_index?).with('core')
|
|
260
|
-
@person.in_core_index?
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
describe "in_delta_index?" do
|
|
265
|
-
it "should call in_index? with delta" do
|
|
266
|
-
@person.should_receive(:in_index?).with('delta')
|
|
267
|
-
@person.in_delta_index?
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
describe "in_index?" do
|
|
272
|
-
it "should return true if in the specified index" do
|
|
273
|
-
@person.should_receive(:sphinx_document_id).and_return(1)
|
|
274
|
-
@person.should_receive(:sphinx_index_name).and_return('person_core')
|
|
275
|
-
Person.should_receive(:search_for_id).with(1, 'person_core').and_return(true)
|
|
276
|
-
|
|
277
|
-
@person.in_index?('core').should be_true
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
237
|
|
|
282
238
|
describe '.source_of_sphinx_index' do
|
|
283
239
|
it "should return self if model defines an index" do
|
|
@@ -450,6 +406,12 @@ describe ThinkingSphinx::ActiveRecord do
|
|
|
450
406
|
@person.stub!(:id => 'unique_hash')
|
|
451
407
|
@person.primary_key_for_sphinx.should == id
|
|
452
408
|
end
|
|
409
|
+
|
|
410
|
+
it "should be inherited by subclasses" do
|
|
411
|
+
Person.set_sphinx_primary_key :first_name
|
|
412
|
+
Parent.superclass.custom_primary_key_for_sphinx?
|
|
413
|
+
Parent.primary_key_for_sphinx.should == Person.primary_key_for_sphinx
|
|
414
|
+
end
|
|
453
415
|
end
|
|
454
416
|
|
|
455
417
|
describe '.sphinx_index_names' do
|
|
@@ -39,7 +39,7 @@ describe ThinkingSphinx::AutoVersion do
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
it "should output a warning if the detected version is something else" do
|
|
42
|
-
STDERR.should_receive(:puts)
|
|
42
|
+
STDERR.should_receive(:puts).twice
|
|
43
43
|
|
|
44
44
|
@config.stub!(:version => '0.9.7')
|
|
45
45
|
ThinkingSphinx::AutoVersion.detect
|
|
@@ -98,6 +98,14 @@ describe ThinkingSphinx::FacetSearch do
|
|
|
98
98
|
:classes => [Person], :facets => :state
|
|
99
99
|
)
|
|
100
100
|
end
|
|
101
|
+
|
|
102
|
+
it "should handle multiple facets" do
|
|
103
|
+
ThinkingSphinx.should_receive(:search).twice.and_return(search)
|
|
104
|
+
|
|
105
|
+
ThinkingSphinx::FacetSearch.new(
|
|
106
|
+
:classes => [Person], :facets => [:state, :city]
|
|
107
|
+
)
|
|
108
|
+
end
|
|
101
109
|
end
|
|
102
110
|
|
|
103
111
|
describe "empty result set for attributes" do
|
|
@@ -877,6 +877,36 @@ describe ThinkingSphinx::Search do
|
|
|
877
877
|
end
|
|
878
878
|
end
|
|
879
879
|
|
|
880
|
+
describe ':only option' do
|
|
881
|
+
it "returns the requested attribute as an array" do
|
|
882
|
+
ThinkingSphinx::Search.new(:only => :class_crc).first.
|
|
883
|
+
should == Alpha.to_crc32
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
it "returns multiple attributes as hashes with values" do
|
|
887
|
+
ThinkingSphinx::Search.new(
|
|
888
|
+
:only => [:class_crc, :sphinx_internal_id]
|
|
889
|
+
).first.should == {
|
|
890
|
+
:class_crc => Alpha.to_crc32,
|
|
891
|
+
:sphinx_internal_id => @alpha_a.id
|
|
892
|
+
}
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
it "handles strings for a single attribute name" do
|
|
896
|
+
ThinkingSphinx::Search.new(:only => 'class_crc').first.
|
|
897
|
+
should == Alpha.to_crc32
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
it "handles strings for multiple attribute names" do
|
|
901
|
+
ThinkingSphinx::Search.new(
|
|
902
|
+
:only => ['class_crc', 'sphinx_internal_id']
|
|
903
|
+
).first.should == {
|
|
904
|
+
:class_crc => Alpha.to_crc32,
|
|
905
|
+
:sphinx_internal_id => @alpha_a.id
|
|
906
|
+
}
|
|
907
|
+
end
|
|
908
|
+
end
|
|
909
|
+
|
|
880
910
|
context 'result objects' do
|
|
881
911
|
describe '#excerpts' do
|
|
882
912
|
before :each do
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: thinking-sphinx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 9
|
|
5
5
|
prerelease: false
|
|
6
6
|
segments:
|
|
7
7
|
- 2
|
|
8
8
|
- 0
|
|
9
|
-
-
|
|
10
|
-
version: 2.0.
|
|
9
|
+
- 3
|
|
10
|
+
version: 2.0.3
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Pat Allan
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2011-
|
|
18
|
+
date: 2011-04-03 00:00:00 +11:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies:
|
|
21
21
|
- !ruby/object:Gem::Dependency
|
|
@@ -296,6 +296,7 @@ files:
|
|
|
296
296
|
- lib/thinking_sphinx/active_record/attribute_updates.rb
|
|
297
297
|
- lib/thinking_sphinx/active_record/delta.rb
|
|
298
298
|
- lib/thinking_sphinx/active_record/has_many_association.rb
|
|
299
|
+
- lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb
|
|
299
300
|
- lib/thinking_sphinx/active_record/log_subscriber.rb
|
|
300
301
|
- lib/thinking_sphinx/active_record/scopes.rb
|
|
301
302
|
- lib/thinking_sphinx/adapters/abstract_adapter.rb
|