picky 4.5.7 → 4.5.8

Sign up to get free protection for your applications and to get access to all the features.
data/lib/maybe_compile.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # TODO Decide what to do with this.
2
+ #
3
+
1
4
  # Note: This is handled toplevel to not confuse compilers.
2
5
  #
3
6
  failed = 0
@@ -15,30 +15,43 @@ module Picky
15
15
  class Logarithmic < Strategy
16
16
 
17
17
  def initialize constant = 0.0
18
- # Note: Optimisation since it is called
19
- # once per indexed object.
20
- #
21
- if constant == 0.0
22
- def weight_for amount
23
- return 0 if amount < 1
24
- Math.log(amount).round 3
25
- end
26
- else
27
- @constant = constant
28
- # Sets the weight value.
29
- #
30
- # If the size is 0 or one, we would get -Infinity or 0.0.
31
- # Thus we do not set a value if there is just one. The default, dynamically, is 0.
32
- #
33
- # BUT: We need the value, even if 0. To designate that there IS a weight!
34
- #
35
- def weight_for amount
36
- return @constant if amount < 1
37
- @constant + Math.log(amount).round(3)
38
- end
39
- end
18
+ @constant = constant
19
+ # # Note: Optimisation since it is called
20
+ # # once per indexed object.
21
+ # #
22
+ # if constant == 0.0
23
+ # install_without_constant
24
+ # else
25
+ # @constant = constant
26
+ # install_with_constant
27
+ # end
40
28
  end
41
-
29
+
30
+ def weight_for amount
31
+ return @constant if amount < 1
32
+ @constant + Math.log(amount).round(3)
33
+ end
34
+
35
+ # def install_with_constant
36
+ # # Sets the weight value.
37
+ # #
38
+ # # If the size is 0 or one, we would get -Infinity or 0.0.
39
+ # # Thus we do not set a value if there is just one. The default, dynamically, is 0.
40
+ # #
41
+ # # BUT: We need the value, even if 0. To designate that there IS a weight!
42
+ # #
43
+ # def weight_for amount
44
+ # return @constant if amount < 1
45
+ # @constant + Math.log(amount).round(3)
46
+ # end
47
+ # end
48
+ # def install_without_constant
49
+ # def weight_for amount
50
+ # return 0 if amount < 1
51
+ # Math.log(amount).round 3
52
+ # end
53
+ # end
54
+
42
55
  end
43
56
 
44
57
  end
data/lib/picky/index.rb CHANGED
@@ -162,6 +162,7 @@ module Picky
162
162
  # * category_name: This identifier is used in the front end, but also to categorize query text. For example, “title:hobbit” will narrow the hobbit query on categories with the identifier :title.
163
163
  #
164
164
  # === Options
165
+ # * indexing: Pass in either a tokenizer or tokenizer options.
165
166
  # * partial: Partial::None.new or Partial::Substring.new(from: starting_char, to: ending_char). Default is Partial::Substring.new(from: -3, to: -1).
166
167
  # * similarity: Similarity::None.new or Similarity::DoubleMetaphone.new(similar_words_searched). Default is Similarity::None.new.
167
168
  # * qualifiers: An array of qualifiers with which you can define which category you’d like to search, for example “title:hobbit” will search for hobbit in just title categories. Example: qualifiers: [:t, :titre, :title] (use it for example with multiple languages). Default is the name of the category.
@@ -0,0 +1,19 @@
1
+ module Picky
2
+
3
+ class Index
4
+
5
+ # Return facets for a category in the form:
6
+ # { text => weight } # or ids.size?
7
+ #
8
+ def facets category_identifier, options = {}
9
+ weights = self[category_identifier].exact.weights
10
+ if minimal_weight = options[:more_than]
11
+ weights.select { |_, weight| weight > minimal_weight }
12
+ else
13
+ weights
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ end
data/lib/picky/loader.rb CHANGED
@@ -243,6 +243,7 @@ module Picky
243
243
  load_relative 'index_indexed'
244
244
  load_relative 'index_indexing'
245
245
  load_relative 'index_realtime'
246
+ load_relative 'index_facets'
246
247
  load_relative 'index_convenience'
247
248
 
248
249
  # Results.
@@ -253,6 +254,7 @@ module Picky
253
254
  # Search.
254
255
  #
255
256
  load_relative 'search'
257
+ load_relative 'search_facets'
256
258
 
257
259
  # Interfaces
258
260
  #
@@ -12,7 +12,13 @@ module Picky
12
12
  # # bundle them in an index bundle.
13
13
  #
14
14
  class Indexes
15
-
15
+
16
+ # TODO Only needed for .
17
+ #
18
+ delegate :size,
19
+ :first,
20
+ :to => :@indexes
21
+
16
22
  attr_reader :indexes,
17
23
  :ignored_categories
18
24
 
@@ -25,10 +25,10 @@ module Picky
25
25
  # Note:
26
26
  # Use this if you do not want a normalized token.
27
27
  #
28
- def initialize text, original = nil, category = nil
28
+ def initialize text, original = nil, categories = nil
29
29
  @text = text
30
30
  @original = original
31
- @user_defined_categories = [category] if category
31
+ @user_defined_categories = categories
32
32
  end
33
33
 
34
34
  # Returns a qualified and normalized token.
@@ -214,7 +214,9 @@ module Picky
214
214
  def similar_tokens_for category
215
215
  similars = category.bundle_for(self).similar @text
216
216
  similars.map do |similar|
217
- self.class.new similar, similar, category
217
+ # The array describes all possible categories. There is only one here.
218
+ #
219
+ self.class.new similar, similar, [category]
218
220
  end
219
221
  end
220
222
 
@@ -0,0 +1,29 @@
1
+ module Picky
2
+
3
+ class Search
4
+
5
+ # Returns a list of filtered facets.
6
+ #
7
+ # Params
8
+ # category: The category whose facets to return.
9
+ #
10
+ # Options
11
+ # more_than: A minimum weight a facet needs to have (exclusive).
12
+ # filter: A query to filter the facets with.
13
+ #
14
+ # Usage:
15
+ # search.facets :name, filter: 'surname:peter', more_than: 0
16
+ #
17
+ def facets category_identifier, options = {}
18
+ raise "#{__method__} cannot be used on searches with more than 1 index yet. Sorry!" if indexes.size > 1
19
+ index = indexes.first
20
+ weights = index.facets category_identifier, options
21
+ return weights unless filter_query = options[:filter]
22
+ weights.select do |key, weight|
23
+ search("#{filter_query} #{category_identifier}:#{key}", 0, 0).total > 0
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,143 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ # This spec describes
6
+ #
7
+ describe 'facets' do
8
+
9
+ describe 'simple example' do
10
+ let(:index) {
11
+ index = Picky::Index.new :facets do
12
+ category :name
13
+ category :surname
14
+ end
15
+
16
+ thing = Struct.new :id, :name, :surname
17
+ index.add thing.new(1, 'fritz', 'hanke')
18
+ index.add thing.new(2, 'kaspar', 'schiess')
19
+ index.add thing.new(3, 'florian', 'hanke')
20
+
21
+ index
22
+ }
23
+ let(:finder) { Picky::Search.new index }
24
+
25
+ describe 'facets' do
26
+ it 'is correct' do
27
+ # Picky has 2 facets with different weights for surname.
28
+ #
29
+ index.facets(:surname).should == {
30
+ 'hanke' => 0.693,
31
+ 'schiess' => 0
32
+ }
33
+
34
+ # It has 3 facets with the same weight for name.
35
+ #
36
+ index.facets(:name).should == {
37
+ 'fritz' => 0,
38
+ 'kaspar' => 0,
39
+ 'florian' => 0
40
+ }
41
+
42
+ # Picky only selects facets with a weight >= the given one.
43
+ #
44
+ index.facets(:surname, more_than: 0.5).should == {
45
+ 'hanke' => 0.693
46
+ }
47
+ end
48
+ end
49
+
50
+ describe 'facets' do
51
+ it 'filters them correctly' do
52
+ # Passing in no filter query just returns the facets
53
+ #
54
+ finder.facets(:surname).should == {
55
+ 'hanke' => 0.693,
56
+ 'schiess' => 0.0
57
+ }
58
+
59
+ # It has two facets.
60
+ #
61
+ # TODO Rewrite API.
62
+ #
63
+ finder.facets(:name, filter: 'surname:hanke').should == {
64
+ 'fritz' => 0,
65
+ 'florian' => 0
66
+ }
67
+ end
68
+ end
69
+ end
70
+
71
+ describe 'complex example' do
72
+ let(:index) {
73
+ index = Picky::Index.new :facets do
74
+ category :name
75
+ category :surname
76
+ category :age_category
77
+ end
78
+
79
+ thing = Struct.new :id, :name, :surname, :age_category
80
+ index.add thing.new(1, 'ursula', 'meier', 40)
81
+ index.add thing.new(2, 'peter', 'meier', 45)
82
+ index.add thing.new(3, 'peter', 'kunz', 40)
83
+ index.add thing.new(4, 'peter', 'hanke', 40)
84
+ index.add thing.new(5, 'annabelle', 'hanke', 35)
85
+ index.add thing.new(5, 'hans', 'meier', 35)
86
+
87
+ index
88
+ }
89
+ let(:finder) { Picky::Search.new index }
90
+
91
+ describe 'facets' do
92
+ it 'is correct' do
93
+ # Picky has 2 facets with different weights for surname.
94
+ #
95
+ index.facets(:surname).should == {
96
+ 'hanke' => 0.693,
97
+ 'kunz' => 0.0,
98
+ 'meier' => 1.099
99
+ }
100
+
101
+ # It has 3 facets with the same weight for name.
102
+ #
103
+ index.facets(:name).should == {
104
+ 'annabelle' => 0.0,
105
+ 'hans' => 0.0,
106
+ 'peter' => 1.099,
107
+ 'ursula' => 0.0
108
+ }
109
+
110
+ # It has 1 facet with weight > 0.
111
+ #
112
+ index.facets(:name, more_than: 0).should == {
113
+ 'peter' => 1.099
114
+ }
115
+ end
116
+ end
117
+
118
+ describe 'facets' do
119
+ it 'filters them correctly' do
120
+ # It has one facet.
121
+ #
122
+ # TODO Fix problems with alternative qualifiers (like :age).
123
+ #
124
+ finder.facets(:age_category, filter: 'surname:meier name:peter').should == {
125
+ '45' => 0
126
+ }
127
+
128
+ # It has two facets.
129
+ #
130
+ finder.facets(:surname, filter: 'age_category:40 name:peter').should == {
131
+ 'kunz' => 0.0,
132
+ 'hanke' => 0.693
133
+ }
134
+
135
+ # It has 1 facet > weight 0.
136
+ #
137
+ finder.facets(:surname, filter: 'age_category:40 name:peter', more_than: 0).should == {
138
+ 'hanke' => 0.693
139
+ }
140
+ end
141
+ end
142
+ end
143
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picky
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.7
4
+ version: 4.5.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-20 00:00:00.000000000 Z
12
+ date: 2012-07-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70151588753500 !ruby/object:Gem::Requirement
16
+ requirement: &70220459152600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,21 +21,21 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70151588753500
24
+ version_requirements: *70220459152600
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: picky-client
27
- requirement: &70151588752540 !ruby/object:Gem::Requirement
27
+ requirement: &70220459151560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: 4.5.7
32
+ version: 4.5.8
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70151588752540
35
+ version_requirements: *70220459151560
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: text
38
- requirement: &70151588750500 !ruby/object:Gem::Requirement
38
+ requirement: &70220450665880 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70151588750500
46
+ version_requirements: *70220450665880
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: multi_json
49
- requirement: &70151588748300 !ruby/object:Gem::Requirement
49
+ requirement: &70220450662740 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70151588748300
57
+ version_requirements: *70220450662740
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: activesupport
60
- requirement: &70151588762580 !ruby/object:Gem::Requirement
60
+ requirement: &70220450660780 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '3.0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70151588762580
68
+ version_requirements: *70220450660780
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: procrastinate
71
- requirement: &70151588760860 !ruby/object:Gem::Requirement
71
+ requirement: &70220450680620 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0.4'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70151588760860
79
+ version_requirements: *70220450680620
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rack_fast_escape
82
- requirement: &70151588759980 !ruby/object:Gem::Requirement
82
+ requirement: &70220450679340 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70151588759980
90
+ version_requirements: *70220450679340
91
91
  description: Fast Ruby semantic text search engine with comfortable single field interface.
92
92
  email: florian.hanke+picky@gmail.com
93
93
  executables:
@@ -184,6 +184,7 @@ files:
184
184
  - lib/picky/helpers/measuring.rb
185
185
  - lib/picky/index.rb
186
186
  - lib/picky/index_convenience.rb
187
+ - lib/picky/index_facets.rb
187
188
  - lib/picky/index_indexed.rb
188
189
  - lib/picky/index_indexing.rb
189
190
  - lib/picky/index_realtime.rb
@@ -220,6 +221,7 @@ files:
220
221
  - lib/picky/results.rb
221
222
  - lib/picky/scheduler.rb
222
223
  - lib/picky/search.rb
224
+ - lib/picky/search_facets.rb
223
225
  - lib/picky/sinatra/index_actions.rb
224
226
  - lib/picky/sinatra.rb
225
227
  - lib/picky/statistics.rb
@@ -256,6 +258,7 @@ files:
256
258
  - spec/functional/custom_delimiters_spec.rb
257
259
  - spec/functional/dynamic_weights_spec.rb
258
260
  - spec/functional/exact_first_spec.rb
261
+ - spec/functional/facets_spec.rb
259
262
  - spec/functional/max_allocations_spec.rb
260
263
  - spec/functional/non_specific_ids_larger_than_20_spec.rb
261
264
  - spec/functional/only_spec.rb
@@ -412,6 +415,7 @@ test_files:
412
415
  - spec/functional/custom_delimiters_spec.rb
413
416
  - spec/functional/dynamic_weights_spec.rb
414
417
  - spec/functional/exact_first_spec.rb
418
+ - spec/functional/facets_spec.rb
415
419
  - spec/functional/max_allocations_spec.rb
416
420
  - spec/functional/non_specific_ids_larger_than_20_spec.rb
417
421
  - spec/functional/only_spec.rb