picky 4.5.7 → 4.5.8

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/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