freelancing-god-thinking-sphinx 1.1.8 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -126,3 +126,4 @@ Since I first released this library, there's been quite a few people who have su
126
126
  - László Bácsi
127
127
  - Peter Wagenet
128
128
  - Max Lapshin
129
+ - Martin Emde
@@ -36,7 +36,7 @@ module ThinkingSphinx
36
36
  module Version #:nodoc:
37
37
  Major = 1
38
38
  Minor = 1
39
- Tiny = 8
39
+ Tiny = 9
40
40
 
41
41
  String = [Major, Minor, Tiny].join('.')
42
42
  end
@@ -9,10 +9,23 @@ module ThinkingSphinx
9
9
  raise "Can't translate Facets on multiple-column field or attribute"
10
10
  end
11
11
  end
12
+
13
+ def self.name_for(facet)
14
+ case facet
15
+ when Facet
16
+ facet.name
17
+ when String, Symbol
18
+ facet.to_s.gsub(/(_facet|_crc)$/,'').to_sym
19
+ end
20
+ end
12
21
 
13
22
  def name
14
23
  reference.unique_name
15
24
  end
25
+
26
+ def self.attribute_name_for(name)
27
+ name.to_s == 'class' ? 'class_crc' : "#{name}_facet"
28
+ end
16
29
 
17
30
  def attribute_name
18
31
  # @attribute_name ||= case @reference
@@ -55,4 +68,4 @@ module ThinkingSphinx
55
68
  @reference.columns.first
56
69
  end
57
70
  end
58
- end
71
+ end
@@ -5,22 +5,26 @@ module ThinkingSphinx
5
5
  def initialize(arguments)
6
6
  @arguments = arguments.clone
7
7
  @attribute_values = {}
8
- @facets = []
8
+ @facet_names = []
9
9
  end
10
10
 
11
11
  def add_from_results(facet, results)
12
+ name = ThinkingSphinx::Facet.name_for(facet)
13
+
14
+ self[name] ||= {}
15
+ @attribute_values[name] ||= {}
16
+ @facet_names << name
17
+
18
+ return if results.empty?
19
+
12
20
  facet = facet_from_object(results.first, facet) if facet.is_a?(String)
13
21
 
14
- self[facet.name] ||= {}
15
- @attribute_values[facet.name] ||= {}
16
- @facets << facet
17
-
18
22
  results.each_with_groupby_and_count { |result, group, count|
19
23
  facet_value = facet.value(result, group)
20
24
 
21
- self[facet.name][facet_value] ||= 0
22
- self[facet.name][facet_value] += count
23
- @attribute_values[facet.name][facet_value] = group
25
+ self[name][facet_value] ||= 0
26
+ self[name][facet_value] += count
27
+ @attribute_values[name][facet_value] = group
24
28
  }
25
29
  end
26
30
 
@@ -30,7 +34,7 @@ module ThinkingSphinx
30
34
  options[:with] ||= {}
31
35
 
32
36
  hash.each do |key, value|
33
- attrib = facet_for_key(key).attribute_name
37
+ attrib = ThinkingSphinx::Facet.attribute_name_for(key)
34
38
  options[:with][attrib] = underlying_value key, value
35
39
  end
36
40
 
@@ -49,12 +53,8 @@ module ThinkingSphinx
49
53
  end
50
54
  end
51
55
 
52
- def facet_for_key(key)
53
- @facets.detect { |facet| facet.name == key }
54
- end
55
-
56
56
  def facet_from_object(object, name)
57
57
  object.sphinx_facets.detect { |facet| facet.attribute_name == name }
58
58
  end
59
59
  end
60
- end
60
+ end
@@ -720,11 +720,11 @@ module ThinkingSphinx
720
720
 
721
721
  def facets_for_model(klass, args, options)
722
722
  hash = ThinkingSphinx::FacetCollection.new args + [options]
723
- options = options.clone.merge! :group_function => :attr
723
+ options = options.clone.merge! facet_query_options
724
724
 
725
725
  klass.sphinx_facets.inject(hash) do |hash, facet|
726
726
  unless facet.name == :class && !options[:class_facet]
727
- options[:group_by] = facet.attribute_name
727
+ options[:group_by] = facet.attribute_name
728
728
  hash.add_from_results facet, search(*(args + [options]))
729
729
  end
730
730
 
@@ -735,7 +735,7 @@ module ThinkingSphinx
735
735
  def facets_for_all_models(args, options)
736
736
  options = GlobalFacetOptions.merge(options)
737
737
  hash = ThinkingSphinx::FacetCollection.new args + [options]
738
- options = options.merge! :group_function => :attr
738
+ options = options.merge! facet_query_options
739
739
 
740
740
  facet_names(options).inject(hash) do |hash, name|
741
741
  options[:group_by] = name
@@ -744,6 +744,17 @@ module ThinkingSphinx
744
744
  end
745
745
  end
746
746
 
747
+ def facet_query_options
748
+ config = ThinkingSphinx::Configuration.instance
749
+ max = config.configuration.searchd.max_matches || 1000
750
+
751
+ {
752
+ :group_function => :attr,
753
+ :limit => max,
754
+ :max_matches => max
755
+ }
756
+ end
757
+
747
758
  def facet_classes(options)
748
759
  options[:classes] || ThinkingSphinx.indexed_models.collect { |model|
749
760
  model.constantize
@@ -0,0 +1,64 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::FacetCollection do
4
+ before do
5
+ @facet_collection = ThinkingSphinx::FacetCollection.new([])
6
+ end
7
+
8
+ # TODO fix nasty hack when we have internet!
9
+ def mock_results
10
+ return @results if defined? @results
11
+ @result = Person.find(:first)
12
+ @results = [@result]
13
+ @results.stub!(:each_with_groupby_and_count).and_yield(@result, @result.city.to_crc32, 1)
14
+ @results
15
+ end
16
+
17
+ describe "#add_from_results" do
18
+ describe "with empty result set" do
19
+ before do
20
+ @facet_collection.add_from_results('attribute_facet', [])
21
+ end
22
+
23
+ it "should add key as attribute" do
24
+ @facet_collection.should have_key(:attribute)
25
+ end
26
+
27
+ it "should return an empty hash for the facet results" do
28
+ @facet_collection[:attribute].should be_empty
29
+ end
30
+ end
31
+
32
+ describe "with non-empty result set" do
33
+ before do
34
+ @facet_collection.add_from_results('city_facet', mock_results)
35
+ end
36
+
37
+ it "should return a hash" do
38
+ @facet_collection.should be_a_kind_of(Hash)
39
+ end
40
+
41
+ it "should add key as attribute" do
42
+ @facet_collection.keys.should include(:city)
43
+ end
44
+
45
+ it "should return a hash" do
46
+ @facet_collection[:city].should == {@result.city => 1}
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "#for" do
52
+ before do
53
+ @facet_collection.add_from_results('city_facet', mock_results)
54
+ end
55
+
56
+ it "should return the search results for the attribute and key pair" do
57
+ ThinkingSphinx::Search.should_receive(:search) do |options|
58
+ options[:with].should have_key('city_facet')
59
+ options[:with]['city_facet'].should == @result.city.to_crc32
60
+ end
61
+ @facet_collection.for(:city => @result.city)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Facet do
4
+ describe ".name_for" do
5
+ it "should remove '_facet' from provided string and return a symbol" do
6
+ ThinkingSphinx::Facet.name_for('attribute_facet').should == :attribute
7
+ end
8
+
9
+ it "should remove '_facet' from provided symbol" do
10
+ ThinkingSphinx::Facet.name_for(:attribute_facet).should == :attribute
11
+ end
12
+
13
+ it "should return the name of the facet if a Facet is passed" do
14
+ facet = ThinkingSphinx::Facet.new(
15
+ ThinkingSphinx::Attribute.stub_instance(:unique_name => :attribute, :columns => ['attribute'])
16
+ )
17
+ ThinkingSphinx::Facet.name_for(facet).should == :attribute
18
+ end
19
+
20
+ it "should return 'class' for special case name 'class_crc'" do
21
+ ThinkingSphinx::Facet.name_for(:class_crc).should == :class
22
+ end
23
+
24
+ it "should cycle" do
25
+ ThinkingSphinx::Facet.name_for(ThinkingSphinx::Facet.attribute_name_for(:attribute)).should == :attribute
26
+ end
27
+ end
28
+
29
+ describe ".attribute_name_for" do
30
+ it "should append '_facet' to provided string" do
31
+ ThinkingSphinx::Facet.attribute_name_for('attribute').should == 'attribute_facet'
32
+ end
33
+
34
+ it "should append '_facet' to provided symbol and return a string" do
35
+ ThinkingSphinx::Facet.attribute_name_for(:attribute).should == 'attribute_facet'
36
+ end
37
+
38
+ it "should return 'class_crc' for special case attribute 'class'" do
39
+ ThinkingSphinx::Facet.attribute_name_for(:class).should == 'class_crc'
40
+ end
41
+
42
+ it "should cycle" do
43
+ ThinkingSphinx::Facet.attribute_name_for(ThinkingSphinx::Facet.name_for('attribute_facet')).should == 'attribute_facet'
44
+ end
45
+ end
46
+ end
@@ -50,6 +50,50 @@ describe ThinkingSphinx::Search do
50
50
 
51
51
  end
52
52
  end
53
+
54
+ describe "facets method" do
55
+ before :each do
56
+ @results = [Person.find(:first)]
57
+ @results.stub!(:each_with_groupby_and_count).
58
+ and_yield(@results.first, @results.first.city.to_crc32, 1)
59
+ ThinkingSphinx::Search.stub!(:search => @results)
60
+
61
+ @config = ThinkingSphinx::Configuration.instance
62
+ @config.configuration.searchd.max_matches = 10_000
63
+ end
64
+
65
+ it "should use the system-set max_matches for limit on facet calls" do
66
+ ThinkingSphinx::Search.should_receive(:search) do |options|
67
+ options[:max_matches].should == 10_000
68
+ options[:limit].should == 10_000
69
+ end
70
+
71
+ ThinkingSphinx::Search.facets :all_attributes => true
72
+ end
73
+
74
+ it "should use the default max-matches if there is no explicit setting" do
75
+ @config.configuration.searchd.max_matches = nil
76
+ ThinkingSphinx::Search.should_receive(:search) do |options|
77
+ options[:max_matches].should == 1000
78
+ options[:limit].should == 1000
79
+ end
80
+
81
+ ThinkingSphinx::Search.facets :all_attributes => true
82
+ end
83
+
84
+ it "should ignore user-provided max_matches and limit on facet calls" do
85
+ ThinkingSphinx::Search.should_receive(:search) do |options|
86
+ options[:max_matches].should == 10_000
87
+ options[:limit].should == 10_000
88
+ end
89
+
90
+ ThinkingSphinx::Search.facets(
91
+ :all_attributes => true,
92
+ :max_matches => 500,
93
+ :limit => 200
94
+ )
95
+ end
96
+ end
53
97
  end
54
98
 
55
99
  describe ThinkingSphinx::Search, "playing nice with Search model" do
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.1.8
4
+ version: 1.1.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-05-06 00:00:00 -07:00
12
+ date: 2009-05-07 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -109,6 +109,8 @@ files:
109
109
  - spec/unit/thinking_sphinx/collection_spec.rb
110
110
  - spec/unit/thinking_sphinx/configuration_spec.rb
111
111
  - spec/unit/thinking_sphinx/core/string_spec.rb
112
+ - spec/unit/thinking_sphinx/facet_collection_spec.rb
113
+ - spec/unit/thinking_sphinx/facet_spec.rb
112
114
  - spec/unit/thinking_sphinx/field_spec.rb
113
115
  - spec/unit/thinking_sphinx/index/builder_spec.rb
114
116
  - spec/unit/thinking_sphinx/index/faux_column_spec.rb
@@ -154,6 +156,8 @@ test_files:
154
156
  - spec/unit/thinking_sphinx/collection_spec.rb
155
157
  - spec/unit/thinking_sphinx/configuration_spec.rb
156
158
  - spec/unit/thinking_sphinx/core/string_spec.rb
159
+ - spec/unit/thinking_sphinx/facet_collection_spec.rb
160
+ - spec/unit/thinking_sphinx/facet_spec.rb
157
161
  - spec/unit/thinking_sphinx/field_spec.rb
158
162
  - spec/unit/thinking_sphinx/index/builder_spec.rb
159
163
  - spec/unit/thinking_sphinx/index/faux_column_spec.rb