freelancing-god-thinking-sphinx 1.2.8 → 1.2.9
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/VERSION.yml +1 -1
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record.rb +1 -1
- data/lib/thinking_sphinx/core/array.rb +7 -0
- data/lib/thinking_sphinx/facet.rb +5 -1
- data/lib/thinking_sphinx/index.rb +2 -2
- data/lib/thinking_sphinx/search.rb +32 -20
- data/lib/thinking_sphinx/source.rb +1 -1
- data/spec/lib/thinking_sphinx/core/array_spec.rb +9 -0
- data/spec/lib/thinking_sphinx/facet_spec.rb +34 -15
- data/spec/lib/thinking_sphinx/search_spec.rb +44 -0
- data/spec/lib/thinking_sphinx/source_spec.rb +10 -0
- metadata +5 -4
data/VERSION.yml
CHANGED
data/lib/thinking_sphinx.rb
CHANGED
|
@@ -281,7 +281,7 @@ module ThinkingSphinx
|
|
|
281
281
|
# @return [Integer] Unique record id for the purposes of Sphinx.
|
|
282
282
|
#
|
|
283
283
|
def primary_key_for_sphinx
|
|
284
|
-
read_attribute(self.class.primary_key_for_sphinx)
|
|
284
|
+
@primary_key_for_sphinx ||= read_attribute(self.class.primary_key_for_sphinx)
|
|
285
285
|
end
|
|
286
286
|
|
|
287
287
|
def sphinx_document_id
|
|
@@ -72,7 +72,7 @@ module ThinkingSphinx
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def value(object, attribute_value)
|
|
75
|
-
return translate(object, attribute_value) if translate?
|
|
75
|
+
return translate(object, attribute_value) if translate? || float?
|
|
76
76
|
|
|
77
77
|
case @property.type
|
|
78
78
|
when :datetime
|
|
@@ -106,5 +106,9 @@ module ThinkingSphinx
|
|
|
106
106
|
def column
|
|
107
107
|
@property.columns.first
|
|
108
108
|
end
|
|
109
|
+
|
|
110
|
+
def float?
|
|
111
|
+
@property.type == :float
|
|
112
|
+
end
|
|
109
113
|
end
|
|
110
114
|
end
|
|
@@ -194,15 +194,15 @@ module ThinkingSphinx
|
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
def excerpt_for(string, model = nil)
|
|
197
|
-
if model.nil? &&
|
|
198
|
-
model ||=
|
|
197
|
+
if model.nil? && classes.length == 1
|
|
198
|
+
model ||= classes.first
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
populate
|
|
202
202
|
client.excerpts(
|
|
203
203
|
:docs => [string],
|
|
204
204
|
:words => results[:words].keys.join(' '),
|
|
205
|
-
:index => "#{model.sphinx_name}_core"
|
|
205
|
+
:index => "#{model.source_of_sphinx_index.sphinx_name}_core"
|
|
206
206
|
).first
|
|
207
207
|
end
|
|
208
208
|
|
|
@@ -266,8 +266,8 @@ module ThinkingSphinx
|
|
|
266
266
|
def client
|
|
267
267
|
client = config.client
|
|
268
268
|
|
|
269
|
-
index_options =
|
|
270
|
-
{} :
|
|
269
|
+
index_options = classes.length != 1 ?
|
|
270
|
+
{} : classes.first.sphinx_indexes.first.local_options
|
|
271
271
|
|
|
272
272
|
[
|
|
273
273
|
:max_matches, :group_by, :group_function, :group_clause,
|
|
@@ -321,6 +321,10 @@ module ThinkingSphinx
|
|
|
321
321
|
end
|
|
322
322
|
end
|
|
323
323
|
|
|
324
|
+
def classes
|
|
325
|
+
@classes ||= options[:classes] || []
|
|
326
|
+
end
|
|
327
|
+
|
|
324
328
|
def query
|
|
325
329
|
@query ||= begin
|
|
326
330
|
q = @args.join(' ') << conditions_as_query
|
|
@@ -333,7 +337,7 @@ module ThinkingSphinx
|
|
|
333
337
|
|
|
334
338
|
# Soon to be deprecated.
|
|
335
339
|
keys = @options[:conditions].keys.reject { |key|
|
|
336
|
-
attributes.include?(key)
|
|
340
|
+
attributes.include?(key.to_sym)
|
|
337
341
|
}
|
|
338
342
|
|
|
339
343
|
' ' + keys.collect { |key|
|
|
@@ -404,9 +408,9 @@ module ThinkingSphinx
|
|
|
404
408
|
end
|
|
405
409
|
|
|
406
410
|
def field_names
|
|
407
|
-
return [] if
|
|
411
|
+
return [] if classes.length != 1
|
|
408
412
|
|
|
409
|
-
|
|
413
|
+
classes.first.sphinx_indexes.collect { |index|
|
|
410
414
|
index.fields.collect { |field| field.unique_name }
|
|
411
415
|
}.flatten
|
|
412
416
|
end
|
|
@@ -428,7 +432,7 @@ module ThinkingSphinx
|
|
|
428
432
|
weights = options[:index_weights] || {}
|
|
429
433
|
weights.keys.inject({}) do |hash, key|
|
|
430
434
|
if key.is_a?(Class)
|
|
431
|
-
name = ThinkingSphinx::Index.
|
|
435
|
+
name = ThinkingSphinx::Index.name_for(key)
|
|
432
436
|
hash["#{name}_core"] = weights[key]
|
|
433
437
|
hash["#{name}_delta"] = weights[key]
|
|
434
438
|
else
|
|
@@ -450,7 +454,7 @@ module ThinkingSphinx
|
|
|
450
454
|
def internal_filters
|
|
451
455
|
filters = [Riddle::Client::Filter.new('sphinx_deleted', [0])]
|
|
452
456
|
|
|
453
|
-
class_crcs =
|
|
457
|
+
class_crcs = classes.collect { |klass|
|
|
454
458
|
klass.to_crc32s
|
|
455
459
|
}.flatten
|
|
456
460
|
|
|
@@ -467,7 +471,7 @@ module ThinkingSphinx
|
|
|
467
471
|
|
|
468
472
|
def condition_filters
|
|
469
473
|
(options[:conditions] || {}).collect { |attrib, value|
|
|
470
|
-
if attributes.include?(attrib)
|
|
474
|
+
if attributes.include?(attrib.to_sym)
|
|
471
475
|
puts <<-MSG
|
|
472
476
|
Deprecation Warning: filters on attributes should be done using the :with
|
|
473
477
|
option, not :conditions. For example:
|
|
@@ -513,6 +517,8 @@ MSG
|
|
|
513
517
|
value.collect { |v| filter_value(v) }.flatten
|
|
514
518
|
when Time
|
|
515
519
|
value.respond_to?(:in_time_zone) ? [value.utc.to_i] : [value.to_i]
|
|
520
|
+
when NilClass
|
|
521
|
+
0
|
|
516
522
|
else
|
|
517
523
|
Array(value)
|
|
518
524
|
end
|
|
@@ -542,15 +548,15 @@ MSG
|
|
|
542
548
|
end
|
|
543
549
|
|
|
544
550
|
def index_option(key)
|
|
545
|
-
return nil if
|
|
551
|
+
return nil if classes.length != 1
|
|
546
552
|
|
|
547
|
-
|
|
553
|
+
classes.first.sphinx_indexes.collect { |index|
|
|
548
554
|
index.local_options[key]
|
|
549
555
|
}.compact.first
|
|
550
556
|
end
|
|
551
557
|
|
|
552
558
|
def attribute(*keys)
|
|
553
|
-
return nil if
|
|
559
|
+
return nil if classes.length != 1
|
|
554
560
|
|
|
555
561
|
keys.detect { |key|
|
|
556
562
|
attributes.include?(key)
|
|
@@ -558,9 +564,9 @@ MSG
|
|
|
558
564
|
end
|
|
559
565
|
|
|
560
566
|
def attributes
|
|
561
|
-
return [] if
|
|
567
|
+
return [] if classes.length != 1
|
|
562
568
|
|
|
563
|
-
attributes =
|
|
569
|
+
attributes = classes.first.sphinx_indexes.collect { |index|
|
|
564
570
|
index.attributes.collect { |attrib| attrib.unique_name }
|
|
565
571
|
}.flatten
|
|
566
572
|
end
|
|
@@ -599,7 +605,7 @@ MSG
|
|
|
599
605
|
|
|
600
606
|
# if the user has specified an SQL order, return the collection
|
|
601
607
|
# without rearranging it into the Sphinx order
|
|
602
|
-
return instances if options[:sql_order]
|
|
608
|
+
return instances if (options[:sql_order] || index_options[:sql_order])
|
|
603
609
|
|
|
604
610
|
ids.collect { |obj_id|
|
|
605
611
|
instances.detect do |obj|
|
|
@@ -612,6 +618,8 @@ MSG
|
|
|
612
618
|
# the number of #find's in multi-model searches.
|
|
613
619
|
#
|
|
614
620
|
def instances_from_matches
|
|
621
|
+
return single_class_results if classes.length == 1
|
|
622
|
+
|
|
615
623
|
groups = results[:matches].group_by { |match|
|
|
616
624
|
match[:attributes]["class_crc"]
|
|
617
625
|
}
|
|
@@ -630,6 +638,10 @@ MSG
|
|
|
630
638
|
end
|
|
631
639
|
end
|
|
632
640
|
|
|
641
|
+
def single_class_results
|
|
642
|
+
instances_from_class classes.first, results[:matches]
|
|
643
|
+
end
|
|
644
|
+
|
|
633
645
|
def class_from_crc(crc)
|
|
634
646
|
config.models_by_crc[crc].constantize
|
|
635
647
|
end
|
|
@@ -643,12 +655,12 @@ MSG
|
|
|
643
655
|
end
|
|
644
656
|
|
|
645
657
|
def is_scope?(method)
|
|
646
|
-
|
|
647
|
-
|
|
658
|
+
classes && classes.length == 1 &&
|
|
659
|
+
classes.first.sphinx_scopes.include?(method)
|
|
648
660
|
end
|
|
649
661
|
|
|
650
662
|
def add_scope(method, *args, &block)
|
|
651
|
-
merge_search
|
|
663
|
+
merge_search classes.first.send(method, *args, &block)
|
|
652
664
|
end
|
|
653
665
|
|
|
654
666
|
def merge_search(search)
|
|
@@ -82,7 +82,7 @@ module ThinkingSphinx
|
|
|
82
82
|
config = @model.connection.instance_variable_get(:@config)
|
|
83
83
|
|
|
84
84
|
source.sql_host = config[:host] || "localhost"
|
|
85
|
-
source.sql_user = config[:username] || config[:user] ||
|
|
85
|
+
source.sql_user = config[:username] || config[:user] || 'root'
|
|
86
86
|
source.sql_pass = (config[:password].to_s || "").gsub('#', '\#')
|
|
87
87
|
source.sql_db = config[:database]
|
|
88
88
|
source.sql_port = config[:port]
|
|
@@ -277,26 +277,45 @@ describe ThinkingSphinx::Facet do
|
|
|
277
277
|
end
|
|
278
278
|
|
|
279
279
|
describe "#value" do
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
@
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
280
|
+
describe 'for fields from associations' do
|
|
281
|
+
before :each do
|
|
282
|
+
@index = ThinkingSphinx::Index.new(Friendship)
|
|
283
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
284
|
+
@field = ThinkingSphinx::Field.new(
|
|
285
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:person, :first_name)
|
|
286
|
+
)
|
|
287
|
+
@facet = ThinkingSphinx::Facet.new(@field)
|
|
288
|
+
end
|
|
288
289
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
290
|
+
it "should return association values" do
|
|
291
|
+
person = Person.find(:first)
|
|
292
|
+
friendship = Friendship.new(:person => person)
|
|
292
293
|
|
|
293
|
-
|
|
294
|
+
@facet.value(friendship, 1).should == person.first_name
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it "should return nil if the association is nil" do
|
|
298
|
+
friendship = Friendship.new(:person => nil)
|
|
299
|
+
|
|
300
|
+
@facet.value(friendship, 1).should be_nil
|
|
301
|
+
end
|
|
294
302
|
end
|
|
295
303
|
|
|
296
|
-
|
|
297
|
-
|
|
304
|
+
describe 'for float attributes' do
|
|
305
|
+
before :each do
|
|
306
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
|
307
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
308
|
+
@attribute = ThinkingSphinx::Attribute.new(
|
|
309
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:cost)
|
|
310
|
+
)
|
|
311
|
+
@facet = ThinkingSphinx::Facet.new(@attribute)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
it "should translate using the given model" do
|
|
315
|
+
alpha = Alpha.new(:cost => 10.5)
|
|
298
316
|
|
|
299
|
-
|
|
317
|
+
@facet.value(alpha, 1093140480).should == 10.5
|
|
318
|
+
end
|
|
300
319
|
end
|
|
301
320
|
end
|
|
302
321
|
end
|
|
@@ -379,6 +379,13 @@ describe ThinkingSphinx::Search do
|
|
|
379
379
|
filter.exclude?.should be_false
|
|
380
380
|
end
|
|
381
381
|
|
|
382
|
+
it "should treat nils in arrays as 0" do
|
|
383
|
+
ThinkingSphinx::Search.new(:with => {:ints => [nil, 1, 2, 3]}).first
|
|
384
|
+
|
|
385
|
+
filter = @client.filters.last
|
|
386
|
+
filter.values.should == [0, 1, 2, 3]
|
|
387
|
+
end
|
|
388
|
+
|
|
382
389
|
it "should append inclusive filters of time ranges" do
|
|
383
390
|
first, last = 1.week.ago, Time.now
|
|
384
391
|
ThinkingSphinx::Search.new(:with => {
|
|
@@ -688,6 +695,35 @@ describe ThinkingSphinx::Search do
|
|
|
688
695
|
end
|
|
689
696
|
end
|
|
690
697
|
|
|
698
|
+
describe 'sql ordering' do
|
|
699
|
+
before :each do
|
|
700
|
+
@client.stub! :query => {
|
|
701
|
+
:matches => minimal_result_hashes(@alpha_b, @alpha_a)
|
|
702
|
+
}
|
|
703
|
+
Alpha.stub! :find => [@alpha_a, @alpha_b]
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
it "shouldn't re-sort SQL results based on Sphinx information" do
|
|
707
|
+
search = ThinkingSphinx::Search.new(
|
|
708
|
+
:classes => [Alpha],
|
|
709
|
+
:sql_order => 'id'
|
|
710
|
+
)
|
|
711
|
+
search.first.should == @alpha_a
|
|
712
|
+
search.last.should == @alpha_b
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
it "should use the option for the ActiveRecord::Base#find calls" do
|
|
716
|
+
Alpha.should_receive(:find) do |mode, options|
|
|
717
|
+
options[:order].should == 'id'
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
ThinkingSphinx::Search.new(
|
|
721
|
+
:classes => [Alpha],
|
|
722
|
+
:sql_order => 'id'
|
|
723
|
+
).first
|
|
724
|
+
end
|
|
725
|
+
end
|
|
726
|
+
|
|
691
727
|
describe 'excerpts' do
|
|
692
728
|
before :each do
|
|
693
729
|
@search = ThinkingSphinx::Search.new
|
|
@@ -942,6 +978,14 @@ describe ThinkingSphinx::Search do
|
|
|
942
978
|
|
|
943
979
|
@search.excerpt_for('string', Beta)
|
|
944
980
|
end
|
|
981
|
+
|
|
982
|
+
it "should use the correct index in STI situations" do
|
|
983
|
+
@client.should_receive(:excerpts) do |options|
|
|
984
|
+
options[:index].should == 'person_core'
|
|
985
|
+
end
|
|
986
|
+
|
|
987
|
+
@search.excerpt_for('string', Parent)
|
|
988
|
+
end
|
|
945
989
|
end
|
|
946
990
|
|
|
947
991
|
describe '#search' do
|
|
@@ -72,6 +72,16 @@ describe ThinkingSphinx::Source do
|
|
|
72
72
|
@riddle.sql_sock.should == config[:socket]
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
it "should use a default username of root if nothing else is provided" do
|
|
76
|
+
Person.connection.stub!(:instance_variable_get => {
|
|
77
|
+
:user => nil,
|
|
78
|
+
:username => nil
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
riddle = @source.to_riddle_for_core(1, 0)
|
|
82
|
+
riddle.sql_user.should == 'root'
|
|
83
|
+
end
|
|
84
|
+
|
|
75
85
|
it "should assign attributes" do
|
|
76
86
|
# 3 internal attributes plus the one requested
|
|
77
87
|
@riddle.sql_attr_uint.length.should == 4
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: freelancing-god-thinking-sphinx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pat Allan
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-
|
|
12
|
+
date: 2009-09-05 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
@@ -47,6 +47,7 @@ files:
|
|
|
47
47
|
- lib/thinking_sphinx/attribute.rb
|
|
48
48
|
- lib/thinking_sphinx/class_facet.rb
|
|
49
49
|
- lib/thinking_sphinx/configuration.rb
|
|
50
|
+
- lib/thinking_sphinx/core/array.rb
|
|
50
51
|
- lib/thinking_sphinx/core/string.rb
|
|
51
52
|
- lib/thinking_sphinx/deltas.rb
|
|
52
53
|
- lib/thinking_sphinx/deltas/datetime_delta.rb
|
|
@@ -105,7 +106,6 @@ files:
|
|
|
105
106
|
- vendor/riddle/lib/riddle/controller.rb
|
|
106
107
|
has_rdoc: true
|
|
107
108
|
homepage: http://ts.freelancing-gods.com
|
|
108
|
-
licenses:
|
|
109
109
|
post_install_message: |+
|
|
110
110
|
With the release of Thinking Sphinx 1.1.18, there is one important change to
|
|
111
111
|
note: previously, the default morphology for indexing was 'stem_en'. The new
|
|
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
142
142
|
requirements: []
|
|
143
143
|
|
|
144
144
|
rubyforge_project:
|
|
145
|
-
rubygems_version: 1.
|
|
145
|
+
rubygems_version: 1.2.0
|
|
146
146
|
signing_key:
|
|
147
147
|
specification_version: 2
|
|
148
148
|
summary: A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.
|
|
@@ -154,6 +154,7 @@ test_files:
|
|
|
154
154
|
- spec/lib/thinking_sphinx/association_spec.rb
|
|
155
155
|
- spec/lib/thinking_sphinx/attribute_spec.rb
|
|
156
156
|
- spec/lib/thinking_sphinx/configuration_spec.rb
|
|
157
|
+
- spec/lib/thinking_sphinx/core/array_spec.rb
|
|
157
158
|
- spec/lib/thinking_sphinx/core/string_spec.rb
|
|
158
159
|
- spec/lib/thinking_sphinx/excerpter_spec.rb
|
|
159
160
|
- spec/lib/thinking_sphinx/facet_search_spec.rb
|