picky 4.0.4 → 4.0.5

Sign up to get free protection for your applications and to get access to all the features.
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