picky 4.0.4 → 4.0.5

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/picky/index.rb CHANGED
@@ -239,7 +239,7 @@ module Picky
239
239
  #
240
240
  # === Options
241
241
  # * precision: Default is 1 (20% error margin, very fast), up to 5 (5% error margin, slower) makes sense.
242
- # * anchor: Where to anchor the geo grid.
242
+ # * anchor: Where to anchor the grid.
243
243
  # * ... all options of #category.
244
244
  #
245
245
  def ranged_category category_name, range, options = {}
@@ -15,7 +15,7 @@ module Picky
15
15
  #
16
16
  #
17
17
  def initialize index, combinations
18
- @combinations = combinations
18
+ @combinations = combinations
19
19
 
20
20
  # Could this be rewritten?
21
21
  #
@@ -25,16 +25,8 @@ module Picky
25
25
  IndexesCheck.check_backends indexes
26
26
 
27
27
  @indexes = indexes
28
-
29
- map_categories
30
- end
31
- def map_categories
32
- @mapper = Query::QualifierCategoryMapper.new
33
- @indexes.each do |index|
34
- index.each_category do |category|
35
- @mapper.add category
36
- end
37
- end
28
+
29
+ @mapper = QualifierCategoryMapper.new indexes # TODO Move out?
38
30
  end
39
31
 
40
32
  # Ignore the categories with these qualifiers.
@@ -51,6 +43,19 @@ module Picky
51
43
  @ignored_categories += qualifiers.map { |qualifier| @mapper.map qualifier }.compact
52
44
  @ignored_categories.uniq!
53
45
  end
46
+
47
+ # Restrict categories to the given ones.
48
+ #
49
+ # Functionally equivalent as if indexes didn't
50
+ # have the categories at all.
51
+ #
52
+ # Note: Probably only makes sense when an index
53
+ # is used in multiple searches. If not, why even
54
+ # have the categories?
55
+ #
56
+ def only *qualifiers
57
+ @mapper.restrict_to *qualifiers
58
+ end
54
59
 
55
60
  # Returns a number of prepared (sorted, reduced etc.) allocations for the given tokens.
56
61
  #
@@ -9,11 +9,16 @@ module Picky
9
9
  class QualifierCategoryMapper # :nodoc:all
10
10
 
11
11
  attr_reader :mapping
12
-
12
+
13
13
  #
14
14
  #
15
- def initialize
15
+ def initialize indexes
16
16
  @mapping = {}
17
+ indexes.each do |index|
18
+ index.each_category do |category|
19
+ add category
20
+ end
21
+ end
17
22
  end
18
23
 
19
24
  #
@@ -35,6 +40,19 @@ module Picky
35
40
 
36
41
  @mapping[qualifier.intern]
37
42
  end
43
+
44
+ # Restricts the given categories.
45
+ #
46
+ def restrict user_qualified
47
+ if @restricted
48
+ user_qualified ? @restricted & user_qualified : @restricted
49
+ else
50
+ user_qualified
51
+ end
52
+ end
53
+ def restrict_to *qualifiers
54
+ @restricted = qualifiers.map { |qualifier| map qualifier }.compact
55
+ end
38
56
 
39
57
  end
40
58
 
@@ -57,13 +57,20 @@ module Picky
57
57
 
58
58
  # Translates this token's qualifiers into actual categories.
59
59
  #
60
- # Note:
61
- # If this is not done, there is no mapping.
60
+ # Note: If this is not done, there is no mapping.
61
+ # Note: predefined is an Array of mapped categories.
62
62
  #
63
- # THINK Can this be improved somehow?
63
+ # TODO Rename @user_defined_categories. It could now also be predefined by the query.
64
64
  #
65
65
  def categorize mapper
66
- @user_defined_categories = @qualifiers && @qualifiers.map do |qualifier|
66
+ @user_defined_categories ||= extract_predefined mapper
67
+ end
68
+ def extract_predefined mapper
69
+ user_qualified = categorize_with mapper, @qualifiers
70
+ mapper.restrict user_qualified
71
+ end
72
+ def categorize_with mapper, qualifiers
73
+ qualifiers && qualifiers.map do |qualifier|
67
74
  mapper.map qualifier
68
75
  end.compact
69
76
  end
data/lib/picky/search.rb CHANGED
@@ -8,10 +8,9 @@ module Picky
8
8
  # * holds one or more indexes
9
9
  # * offers an interface to query these indexes.
10
10
  #
11
- # You connect URL paths to indexes via a Query.
12
- #
13
- # We recommend to not use this directly, but connect it to an URL and query through one of these
14
- # (Protip: Use "curl 'localhost:8080/query/path?query=exampletext')" in a Terminal.
11
+ # Example:
12
+ # search = Picky::Search.new index1, index2
13
+ # search.search 'query'
15
14
  #
16
15
  class Search
17
16
 
@@ -25,6 +24,7 @@ module Picky
25
24
  :boosts
26
25
 
27
26
  delegate :ignore,
27
+ :only,
28
28
  :to => :indexes
29
29
 
30
30
  # Takes:
@@ -38,8 +38,8 @@ module Picky
38
38
  # [:title, :isbn] => +1
39
39
  # end
40
40
  #
41
- def initialize *index_definitions
42
- @indexes = Query::Indexes.new *index_definitions
41
+ def initialize *indexes
42
+ @indexes = Query::Indexes.new *indexes
43
43
 
44
44
  instance_eval(&Proc.new) if block_given?
45
45
 
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe 'Search#only' do
6
+
7
+ it 'offers the option only' do
8
+ index = Picky::Index.new :only do
9
+ category :text1
10
+ category :text2
11
+ category :text3
12
+ end
13
+
14
+ index.add Struct.new(:id, :text1, :text2, :text3).new(1, 'text1', 'text2', 'text3')
15
+
16
+ try = Picky::Search.new index
17
+ try.search('text1').ids.should == [1]
18
+ try.search('text2').ids.should == [1]
19
+ try.search('text3').ids.should == [1]
20
+
21
+ try_again = Picky::Search.new index do
22
+ only :text1
23
+ end
24
+ try_again.search('text1').ids.should == [1]
25
+ try_again.search('text2').ids.should == []
26
+ try_again.search('text3').ids.should == []
27
+
28
+ try_again.only :text2, :text3
29
+ try_again.search('text1').ids.should == []
30
+ try_again.search('text2').ids.should == [1]
31
+ try_again.search('text3').ids.should == [1]
32
+
33
+ try_again.search('text1:text1').ids.should == []
34
+ try_again.search('text2:text2').ids.should == [1]
35
+ try_again.search('text3:text3').ids.should == [1]
36
+
37
+ try_again.search('text1,text2,text3:text1').ids.should == []
38
+ try_again.search('text1,text2:text1').ids.should == []
39
+ try_again.search('text1,text3:text1').ids.should == []
40
+ try_again.search('text2,text3:text1').ids.should == []
41
+
42
+ try_again.search('text1,text2,text3:text2').ids.should == [1]
43
+ try_again.search('text1,text2:text2').ids.should == [1]
44
+ try_again.search('text1,text3:text2').ids.should == []
45
+ try_again.search('text2,text3:text2').ids.should == [1]
46
+
47
+ try_again.search('text1,text2,text3:text3').ids.should == [1]
48
+ try_again.search('text1,text2:text3').ids.should == []
49
+ try_again.search('text1,text3:text3').ids.should == [1]
50
+ try_again.search('text2,text3:text3').ids.should == [1]
51
+ end
52
+ end
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe "Regression" do
6
-
6
+
7
7
  it 'does not get confused' do
8
8
  index = Picky::Index.new :dynamic_weights do
9
9
  category :text1
@@ -7,10 +7,8 @@ describe Picky::Query::Indexes do
7
7
  end
8
8
 
9
9
  3.times do |i|
10
- n = i + 1
11
- name = :"index#{n}"
12
- indexed = :"indexed#{n}"
13
- let(name) { stub name, :internal_indexed => stub(indexed) }
10
+ name = :"index#{i+1}"
11
+ let(name) { Picky::Index.new(name) }
14
12
  end
15
13
 
16
14
  let(:indexes) do
@@ -2,15 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  describe Picky::Query::QualifierCategoryMapper do
4
4
 
5
- let(:mapper) { described_class.new }
6
- before(:each) do
7
- @category1 = stub(:category1, :qualifiers => ['t1', 'tt1', 'ttt1'])
8
- @category2 = stub(:category2, :qualifiers => [:t2, :tt2, :ttt2])
9
- @category3 = stub(:category3, :qualifiers => [:t3, :tt3, :ttt3])
10
- mapper.add @category1
11
- mapper.add @category2
12
- mapper.add @category3
5
+ let(:index) do
6
+ categories = Picky::Index.new :categories
7
+ @category1 = categories.category :category1, :qualifiers => ['t1', 'tt1', 'ttt1']
8
+ @category2 = categories.category :category2, :qualifiers => [:t2, :tt2, :ttt2]
9
+ @category3 = categories.category :category3, :qualifiers => [:t3, :tt3, :ttt3]
10
+ categories
13
11
  end
12
+ let(:indexes) { [index] }
13
+ let(:mapper) { described_class.new indexes }
14
14
 
15
15
  def self.it_should_map(qualifier, expected)
16
16
  it "should map #{qualifier} to #{expected}" do
@@ -11,6 +11,64 @@ describe Picky::Query::Token do
11
11
  described_class.processed('similar~', 'Similar~').should_not == described_class.processed('similar', 'Similar')
12
12
  end
13
13
  end
14
+
15
+ describe 'categorize' do
16
+ let(:mapper) do
17
+ categories = Picky::Index.new :categories
18
+ @category1 = categories.category :category1
19
+ @category2 = categories.category :category2
20
+ @category3 = categories.category :category3
21
+ Picky::Query::QualifierCategoryMapper.new [categories]
22
+ end
23
+ context 'with qualifiers' do
24
+ let(:token) { described_class.processed 'category1:qualifier', 'category1:Qualifier' }
25
+ context 'unrestricted' do
26
+ it 'categorizes correctly' do
27
+ token.categorize(mapper).should == [@category1]
28
+ end
29
+ end
30
+ context 'restricted' do
31
+ before(:each) do
32
+ mapper.restrict_to :category1
33
+ end
34
+ it 'categorizes correctly' do
35
+ token.categorize(mapper).should == [@category1]
36
+ end
37
+ end
38
+ context 'restricted' do
39
+ before(:each) do
40
+ mapper.restrict_to :category2, :category3
41
+ end
42
+ it 'categorizes correctly' do
43
+ token.categorize(mapper).should == []
44
+ end
45
+ end
46
+ end
47
+ context 'without qualifiers' do
48
+ let(:token) { described_class.processed 'noqualifier', 'NoQualifier' }
49
+ context 'unrestricted' do
50
+ it 'categorizes correctly' do
51
+ token.categorize(mapper).should == nil
52
+ end
53
+ end
54
+ context 'restricted' do
55
+ before(:each) do
56
+ mapper.restrict_to :category1
57
+ end
58
+ it 'categorizes correctly' do
59
+ token.categorize(mapper).should == [@category1]
60
+ end
61
+ end
62
+ context 'restricted' do
63
+ before(:each) do
64
+ mapper.restrict_to :category2, :category3
65
+ end
66
+ it 'categorizes correctly' do
67
+ token.categorize(mapper).should == [@category2, @category3]
68
+ end
69
+ end
70
+ end
71
+ end
14
72
 
15
73
  describe 'similar_tokens_for' do
16
74
  let(:token) { described_class.processed 'similar~', 'Similar~' }
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.0.4
4
+ version: 4.0.5
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: 2011-12-22 00:00:00.000000000 Z
12
+ date: 2011-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70357445983920 !ruby/object:Gem::Requirement
16
+ requirement: &70174977200100 !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: *70357445983920
24
+ version_requirements: *70174977200100
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: picky-client
27
- requirement: &70357445983240 !ruby/object:Gem::Requirement
27
+ requirement: &70174977199140 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: 4.0.4
32
+ version: 4.0.5
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70357445983240
35
+ version_requirements: *70174977199140
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: text
38
- requirement: &70357445982560 !ruby/object:Gem::Requirement
38
+ requirement: &70174977198140 !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: *70357445982560
46
+ version_requirements: *70174977198140
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: yajl-ruby
49
- requirement: &70357445998020 !ruby/object:Gem::Requirement
49
+ requirement: &70174977197100 !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: *70357445998020
57
+ version_requirements: *70174977197100
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: activesupport
60
- requirement: &70357445997240 !ruby/object:Gem::Requirement
60
+ requirement: &70174977195740 !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: *70357445997240
68
+ version_requirements: *70174977195740
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: procrastinate
71
- requirement: &70357445996260 !ruby/object:Gem::Requirement
71
+ requirement: &70174977194540 !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: *70357445996260
79
+ version_requirements: *70174977194540
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rack_fast_escape
82
- requirement: &70357445995560 !ruby/object:Gem::Requirement
82
+ requirement: &70174977192780 !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: *70357445995560
90
+ version_requirements: *70174977192780
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:
@@ -247,6 +247,7 @@ files:
247
247
  - spec/functional/dynamic_weights_spec.rb
248
248
  - spec/functional/exact_first_spec.rb
249
249
  - spec/functional/max_allocations_spec.rb
250
+ - spec/functional/only_spec.rb
250
251
  - spec/functional/realtime_spec.rb
251
252
  - spec/functional/regression_spec.rb
252
253
  - spec/functional/speed_spec.rb
@@ -390,6 +391,7 @@ test_files:
390
391
  - spec/functional/dynamic_weights_spec.rb
391
392
  - spec/functional/exact_first_spec.rb
392
393
  - spec/functional/max_allocations_spec.rb
394
+ - spec/functional/only_spec.rb
393
395
  - spec/functional/realtime_spec.rb
394
396
  - spec/functional/regression_spec.rb
395
397
  - spec/functional/speed_spec.rb