picky 3.0.0.pre5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/picky/adapters/rack/search.rb +1 -1
- data/lib/picky/application.rb +1 -1
- data/lib/picky/backend/file/marshal.rb +1 -1
- data/lib/picky/character_substituters/west_european.rb +21 -11
- data/lib/picky/extensions/hash.rb +5 -5
- data/lib/picky/generators/weights/logarithmic.rb +1 -2
- data/lib/picky/indexed/wrappers/bundle/calculation.rb +13 -5
- data/lib/picky/indexed/wrappers/bundle/location.rb +1 -1
- data/lib/picky/indexed/wrappers/category/location.rb +2 -0
- data/lib/picky/indexes/index.rb +3 -1
- data/lib/picky/query/allocations.rb +7 -1
- data/lib/picky/query/combination.rb +29 -12
- data/lib/picky/query/combinations/base.rb +1 -1
- data/lib/picky/query/weights.rb +48 -22
- data/lib/picky/results.rb +38 -37
- data/lib/picky/search.rb +5 -5
- data/lib/picky/tokenizers/base.rb +1 -1
- data/spec/lib/backend/file/marshal_spec.rb +1 -1
- data/spec/lib/extensions/hash_spec.rb +2 -2
- data/spec/lib/query/combinations/base_spec.rb +1 -1
- data/spec/lib/query/combinations/memory_spec.rb +1 -1
- data/spec/lib/query/combinations/redis_spec.rb +1 -1
- data/spec/lib/query/weights_spec.rb +13 -2
- data/spec/lib/results_spec.rb +23 -12
- data/spec/lib/search_spec.rb +9 -2
- metadata +6 -6
data/lib/picky/application.rb
CHANGED
@@ -197,7 +197,7 @@ module Picky
|
|
197
197
|
# Reloads & finalizes the apps.
|
198
198
|
#
|
199
199
|
def reload
|
200
|
-
Loader.load_user 'app' # Sinatra
|
200
|
+
Loader.load_user 'app' # Sinatra appfile.
|
201
201
|
Loader.load_user 'app/application' # Standard Picky appfile.
|
202
202
|
finalize_apps
|
203
203
|
exclaim "Application #{apps.map(&:name).join(', ')} loaded."
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
#
|
3
|
-
#
|
4
|
-
# diactritics from japanese characters, like べ to へ.
|
3
|
+
# THINK Does it also remove diaritics, like べ to へ?
|
5
4
|
#
|
6
5
|
module Picky
|
7
6
|
|
8
|
-
module CharacterSubstituters
|
7
|
+
module CharacterSubstituters
|
9
8
|
|
10
9
|
# Substitutes Umlauts like
|
11
10
|
# ä, ö, ü => ae, oe, ue.
|
@@ -13,32 +12,43 @@ module Picky
|
|
13
12
|
#
|
14
13
|
class WestEuropean
|
15
14
|
|
16
|
-
def initialize
|
15
|
+
def initialize # :nodoc:
|
17
16
|
@chars = ActiveSupport::Multibyte.proxy_class
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
# Substitutes occurrences of certain characters
|
20
|
+
# (like Umlauts) with ASCII representations of them.
|
21
|
+
#
|
22
|
+
# Examples:
|
23
|
+
# ä -> ae
|
24
|
+
# Ö -> Oe
|
25
|
+
# ß -> ss
|
26
|
+
# ç -> c
|
27
|
+
#
|
28
|
+
# (See the associated spec for all examples)
|
29
|
+
#
|
24
30
|
def substitute text
|
25
31
|
trans = @chars.new(text).normalize(:kd)
|
26
32
|
|
27
|
-
#
|
33
|
+
# Substitute special cases.
|
28
34
|
#
|
29
35
|
trans.gsub!('ß', 'ss')
|
30
36
|
|
31
|
-
#
|
37
|
+
# Substitute umlauts (of A,O,U,a,o,u).
|
32
38
|
#
|
33
39
|
trans.gsub!(/([AOUaou])\314\210/u, '\1e')
|
34
40
|
|
35
|
-
#
|
41
|
+
# Get rid of ecutes, graves etc.
|
36
42
|
#
|
37
43
|
trans.unpack('U*').select { |cp|
|
38
44
|
cp < 0x0300 || cp > 0x035F
|
39
45
|
}.pack('U*')
|
40
46
|
end
|
41
47
|
|
48
|
+
def to_s # :nodoc:
|
49
|
+
self.class.name
|
50
|
+
end
|
51
|
+
|
42
52
|
end
|
43
53
|
|
44
54
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Extensions for the Hash.
|
2
2
|
#
|
3
3
|
class Hash # :nodoc:all
|
4
|
-
|
4
|
+
|
5
5
|
# Dumps jsonized self to the path given. Minus extension.
|
6
6
|
#
|
7
7
|
def dump_json path
|
@@ -9,19 +9,19 @@ class Hash # :nodoc:all
|
|
9
9
|
Yajl::Encoder.encode self, out_file
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# Dumps binary self to the path given. Minus extension.
|
14
14
|
#
|
15
|
-
def
|
15
|
+
def dump_marshal path
|
16
16
|
File.open(path, 'w:binary') do |out_file|
|
17
17
|
Marshal.dump self, out_file
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Use yajl's encoding.
|
22
22
|
#
|
23
23
|
def to_json options = {}
|
24
24
|
Yajl::Encoder.encode self, options
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
end
|
@@ -14,8 +14,7 @@ module Picky
|
|
14
14
|
# Generates a partial index from the given inverted index.
|
15
15
|
#
|
16
16
|
def generate_from inverted
|
17
|
-
inverted.inject({}) do |hash,
|
18
|
-
text, ids = *text_ids
|
17
|
+
inverted.inject({}) do |hash, (text, ids)|
|
19
18
|
weight = weight_for ids.size
|
20
19
|
hash[text] ||= weight.round(2) if weight
|
21
20
|
hash
|
@@ -7,11 +7,19 @@ module Picky
|
|
7
7
|
|
8
8
|
# A calculation rewrites the symbol into a float.
|
9
9
|
#
|
10
|
-
#
|
10
|
+
# Note: A calculation will try to find a float in the index,
|
11
|
+
# not a sym.
|
12
|
+
#
|
13
|
+
# TODO I really need to allow integers as keys.
|
14
|
+
# The code below is just not up to the needed quality.
|
15
|
+
# Use key_format :to_i?
|
11
16
|
#
|
12
17
|
class Calculation < Wrapper
|
13
18
|
|
19
|
+
# API.
|
14
20
|
#
|
21
|
+
# By default, a calculation does not
|
22
|
+
# recalculate anything.
|
15
23
|
#
|
16
24
|
def recalculate float
|
17
25
|
float
|
@@ -19,14 +27,14 @@ module Picky
|
|
19
27
|
|
20
28
|
#
|
21
29
|
#
|
22
|
-
def ids
|
23
|
-
@bundle.ids recalculate(
|
30
|
+
def ids float_as_sym
|
31
|
+
@bundle.ids recalculate(float_as_sym.to_s.to_f).to_s.to_sym
|
24
32
|
end
|
25
33
|
|
26
34
|
#
|
27
35
|
#
|
28
|
-
def weight
|
29
|
-
@bundle.weight recalculate(
|
36
|
+
def weight float_as_sym
|
37
|
+
@bundle.weight recalculate(float_as_sym.to_s.to_f).to_s.to_sym
|
30
38
|
end
|
31
39
|
|
32
40
|
end
|
@@ -30,7 +30,7 @@ module Picky
|
|
30
30
|
# Load first the bundle, then extract the config.
|
31
31
|
#
|
32
32
|
bundle.load
|
33
|
-
#
|
33
|
+
# THINK Can I move the to_f to the backend?
|
34
34
|
#
|
35
35
|
minimum = bundle[:location_minimum] && bundle[:location_minimum].to_f || raise("Configuration :location_minimum for #{bundle.identifier} missing. Did you run rake index already?")
|
36
36
|
@calculation.minimum = minimum
|
data/lib/picky/indexes/index.rb
CHANGED
@@ -224,8 +224,10 @@ module Picky
|
|
224
224
|
# * ... all options of #define_category.
|
225
225
|
#
|
226
226
|
def ranged_category category_name, range, options = {}
|
227
|
-
precision = options[:precision] || 1
|
227
|
+
precision = options[:precision] || 1 # THINK options.delete?
|
228
228
|
|
229
|
+
# Note: :key_format => :to_f ?
|
230
|
+
#
|
229
231
|
options = { partial: Partial::None.new }.merge options
|
230
232
|
|
231
233
|
define_category category_name, options do |category|
|
@@ -6,9 +6,14 @@ module Picky
|
|
6
6
|
#
|
7
7
|
class Allocations # :nodoc:all
|
8
8
|
|
9
|
-
delegate :each, :inject, :empty?, :size, :to => :@allocations
|
10
9
|
attr_reader :total
|
11
10
|
|
11
|
+
delegate :each,
|
12
|
+
:inject,
|
13
|
+
:empty?,
|
14
|
+
:size,
|
15
|
+
:to => :@allocations
|
16
|
+
|
12
17
|
def initialize allocations = []
|
13
18
|
@allocations = allocations
|
14
19
|
end
|
@@ -20,6 +25,7 @@ module Picky
|
|
20
25
|
allocation.calculate_score weights
|
21
26
|
end
|
22
27
|
end
|
28
|
+
|
23
29
|
# Sort the allocations.
|
24
30
|
#
|
25
31
|
def sort!
|
@@ -13,19 +13,30 @@ module Picky
|
|
13
13
|
#
|
14
14
|
class Combination # :nodoc:all
|
15
15
|
|
16
|
-
attr_reader :token,
|
16
|
+
attr_reader :token,
|
17
|
+
:category
|
17
18
|
|
18
19
|
def initialize token, category
|
19
|
-
@token
|
20
|
-
@
|
21
|
-
@bundle = category.bundle_for token
|
22
|
-
@text = @token.text # don't want to use reset_similar already
|
20
|
+
@token = token
|
21
|
+
@category = category
|
23
22
|
end
|
24
23
|
|
25
|
-
#
|
24
|
+
# Returns the token's text.
|
26
25
|
#
|
27
|
-
def
|
28
|
-
|
26
|
+
def text
|
27
|
+
@text ||= token.text
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the category's bundle.
|
31
|
+
#
|
32
|
+
def bundle
|
33
|
+
@bundle ||= category.bundle_for(token)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the category's name.
|
37
|
+
#
|
38
|
+
def category_name
|
39
|
+
@category_name ||= category.name
|
29
40
|
end
|
30
41
|
|
31
42
|
# Returns the weight of this combination.
|
@@ -33,7 +44,7 @@ module Picky
|
|
33
44
|
# Note: Caching is most of the time useful.
|
34
45
|
#
|
35
46
|
def weight
|
36
|
-
@weight ||=
|
47
|
+
@weight ||= bundle.weight(text)
|
37
48
|
end
|
38
49
|
|
39
50
|
# Returns an array of ids for the given text.
|
@@ -41,13 +52,13 @@ module Picky
|
|
41
52
|
# Note: Caching is most of the time useful.
|
42
53
|
#
|
43
54
|
def ids
|
44
|
-
@ids ||=
|
55
|
+
@ids ||= bundle.ids(text)
|
45
56
|
end
|
46
57
|
|
47
58
|
# The identifier for this combination.
|
48
59
|
#
|
49
60
|
def identifier
|
50
|
-
"#{bundle.identifier}:#{
|
61
|
+
"#{bundle.identifier}:#{token.identifier}"
|
51
62
|
end
|
52
63
|
|
53
64
|
# Is the identifier in the given identifiers?
|
@@ -56,6 +67,12 @@ module Picky
|
|
56
67
|
identifiers.include? identifier
|
57
68
|
end
|
58
69
|
|
70
|
+
# Note: Required for uniq!
|
71
|
+
#
|
72
|
+
def hash
|
73
|
+
[token.to_s, bundle].hash
|
74
|
+
end
|
75
|
+
|
59
76
|
# Combines the category names with the original names.
|
60
77
|
# [
|
61
78
|
# [:title, 'Flarbl', :flarbl],
|
@@ -63,7 +80,7 @@ module Picky
|
|
63
80
|
# ]
|
64
81
|
#
|
65
82
|
def to_result
|
66
|
-
[
|
83
|
+
[category_name, *token.to_result]
|
67
84
|
end
|
68
85
|
|
69
86
|
# Example:
|
data/lib/picky/query/weights.rb
CHANGED
@@ -2,51 +2,77 @@ module Picky
|
|
2
2
|
|
3
3
|
module Query
|
4
4
|
|
5
|
-
# Calculates weights for
|
5
|
+
# Calculates scores/weights for combinations.
|
6
6
|
#
|
7
|
-
|
7
|
+
# Example:
|
8
|
+
# Someone searches for peter fish.
|
9
|
+
# Picky might match this to categories as follows:
|
10
|
+
# [:name, :food]
|
11
|
+
# and
|
12
|
+
# [:name, :surname]
|
13
|
+
#
|
14
|
+
# This class is concerned with calculating scores
|
15
|
+
# for the category combinations.
|
16
|
+
#
|
17
|
+
# Implement either
|
18
|
+
# #score_for(combinations)
|
19
|
+
# or
|
20
|
+
# #weight_for(category_names) # Subclass this class for this.
|
21
|
+
#
|
22
|
+
# And return a weight.
|
23
|
+
#
|
24
|
+
class Weights
|
8
25
|
|
9
26
|
attr_reader :weights
|
10
27
|
|
11
|
-
delegate :empty?,
|
28
|
+
delegate :empty?,
|
29
|
+
:to => :weights
|
12
30
|
|
13
|
-
#
|
31
|
+
# Needs a Hash of
|
32
|
+
# [:category_name1, :category_name2] => +3
|
33
|
+
# (some positive or negative weight)
|
14
34
|
#
|
15
35
|
def initialize weights = {}
|
16
36
|
@weights = weights
|
17
37
|
end
|
18
38
|
|
19
|
-
#
|
39
|
+
# API.
|
20
40
|
#
|
21
|
-
|
22
|
-
|
41
|
+
# Get the weight for an array of category names.
|
42
|
+
#
|
43
|
+
# Example:
|
44
|
+
# [:name, :height, :color] returns +3, but
|
45
|
+
# [:name, :height, :street] returns -1.
|
46
|
+
#
|
47
|
+
# Note: Use Array#clustered_uniq_fast to make
|
48
|
+
# [:a, :a, :b, :a] => [:a, :b, :a]
|
49
|
+
#
|
50
|
+
def weight_for category_names
|
51
|
+
@weights[category_names.clustered_uniq_fast] || 0
|
23
52
|
end
|
24
53
|
|
25
|
-
#
|
26
|
-
# by P(allocation) = 1/Z * exp (-1/T * E(allocation)),
|
27
|
-
# where Z is the normalizing partition function
|
28
|
-
# sum_allocations exp(-1/T *E(allocation)), and T is a temperature constant.
|
29
|
-
# If T is high the distribution will be close to equally distributed.
|
30
|
-
# If T is low, the distribution will be the indicator function
|
31
|
-
# for min (E(allocation))…
|
54
|
+
# API.
|
32
55
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
56
|
+
# Calculates a score for the combinations.
|
57
|
+
# Implement #weight_for(category_names) if you don't need the
|
58
|
+
# actual combinations, just the category names.
|
36
59
|
#
|
37
60
|
# Note: Cache this if more complicated weighings become necessary.
|
61
|
+
# Note: Maybe make combinations comparable to Symbols?
|
38
62
|
#
|
39
|
-
def
|
40
|
-
|
41
|
-
#
|
42
|
-
weight_for combinations.map(&:category_name).clustered_uniq_fast
|
63
|
+
def score_for combinations
|
64
|
+
weight_for combinations.map(&:category_name)
|
43
65
|
end
|
44
66
|
|
67
|
+
# A Weights instance is == to another if
|
68
|
+
# the weights are the same.
|
69
|
+
#
|
45
70
|
def == other
|
46
71
|
@weights == other.weights
|
47
72
|
end
|
48
73
|
|
49
|
-
# Prints out a nice representation of the
|
74
|
+
# Prints out a nice representation of the
|
75
|
+
# configured weights.
|
50
76
|
#
|
51
77
|
def to_s
|
52
78
|
"#{self.class}(#{@weights})"
|
data/lib/picky/results.rb
CHANGED
@@ -8,44 +8,38 @@ module Picky
|
|
8
8
|
# Duration is set externally by the query.
|
9
9
|
#
|
10
10
|
attr_writer :duration
|
11
|
-
attr_reader :allocations,
|
11
|
+
attr_reader :allocations,
|
12
|
+
:offset,
|
13
|
+
:amount,
|
14
|
+
:query
|
12
15
|
|
13
16
|
# Takes instances of Query::Allocations as param.
|
14
17
|
#
|
15
|
-
def initialize amount = 0, offset = 0, allocations = Query::Allocations.new
|
16
|
-
@offset = offset
|
18
|
+
def initialize query = nil, amount = 0, offset = 0, allocations = Query::Allocations.new
|
17
19
|
@amount = amount
|
20
|
+
@query = query
|
21
|
+
@offset = offset
|
18
22
|
@allocations = allocations
|
19
23
|
end
|
24
|
+
|
20
25
|
# Create new results and calculate the ids.
|
21
26
|
#
|
22
|
-
def self.from amount, offset, allocations
|
23
|
-
results = new amount, offset, allocations
|
27
|
+
def self.from query, amount, offset, allocations
|
28
|
+
results = new query, amount, offset, allocations
|
24
29
|
results.prepare!
|
25
30
|
results
|
26
31
|
end
|
27
32
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
def to_hash
|
31
|
-
{ allocations: allocations.to_result,
|
32
|
-
offset: offset,
|
33
|
-
duration: duration,
|
34
|
-
total: total }
|
35
|
-
end
|
36
|
-
# Convert to json format.
|
33
|
+
# Delegates to allocations.
|
37
34
|
#
|
38
|
-
def
|
39
|
-
|
35
|
+
def ids amount = 20
|
36
|
+
allocations.ids amount
|
40
37
|
end
|
41
38
|
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# Without this, the allocations are not processed,
|
45
|
-
# and no ids are calculated.
|
39
|
+
# The total results. Delegates to the allocations.
|
46
40
|
#
|
47
|
-
def
|
48
|
-
allocations.
|
41
|
+
def total
|
42
|
+
@total || @total = allocations.total || 0
|
49
43
|
end
|
50
44
|
|
51
45
|
# Duration default is 0.
|
@@ -53,30 +47,31 @@ module Picky
|
|
53
47
|
def duration
|
54
48
|
@duration || 0
|
55
49
|
end
|
56
|
-
|
50
|
+
|
51
|
+
# This starts the actual processing.
|
57
52
|
#
|
58
|
-
#
|
53
|
+
# Without this, the allocations are not processed,
|
54
|
+
# and no ids are calculated.
|
59
55
|
#
|
60
|
-
def
|
61
|
-
|
56
|
+
def prepare!
|
57
|
+
allocations.process! amount, offset
|
62
58
|
end
|
63
59
|
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
# Delegates to allocations.
|
60
|
+
# Returns a hash with the allocations, offset, duration and total.
|
68
61
|
#
|
69
|
-
def
|
70
|
-
allocations.
|
62
|
+
def to_hash
|
63
|
+
{ allocations: allocations.to_result,
|
64
|
+
offset: offset,
|
65
|
+
duration: duration,
|
66
|
+
total: total }
|
71
67
|
end
|
72
68
|
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# TODO Should this be to_s? (And it should also hold the original query?)
|
69
|
+
# Convert to json format.
|
76
70
|
#
|
77
|
-
def
|
78
|
-
|
71
|
+
def to_json options = {}
|
72
|
+
to_hash.to_json options
|
79
73
|
end
|
74
|
+
|
80
75
|
# The first character in the blog designates what type of query it is.
|
81
76
|
#
|
82
77
|
# No calculated ids means: No results.
|
@@ -85,6 +80,12 @@ module Picky
|
|
85
80
|
amount.zero?? :'.' : :'>'
|
86
81
|
end
|
87
82
|
|
83
|
+
# For logging.
|
84
|
+
#
|
85
|
+
def to_s
|
86
|
+
"#{log_type}|#{Time.now.to_s(:db)}|#{'%8f' % duration}|#{'%-50s' % query}|#{'%8d' % total}|#{'%4d' % offset}|#{'%2d' % allocations.size}|"
|
87
|
+
end
|
88
|
+
|
88
89
|
end
|
89
90
|
|
90
91
|
end
|
data/lib/picky/search.rb
CHANGED
@@ -84,18 +84,18 @@ module Picky
|
|
84
84
|
# Note: The Rack adapter calls this method after unravelling the HTTP request.
|
85
85
|
#
|
86
86
|
def search text, ids = 20, offset = 0
|
87
|
-
search_with tokenized(text), ids.to_i, offset.to_i
|
87
|
+
search_with tokenized(text), ids.to_i, offset.to_i, text
|
88
88
|
end
|
89
89
|
|
90
90
|
# Runs the actual search using Query::Tokens.
|
91
91
|
#
|
92
92
|
# Note: Internal method, use #search
|
93
93
|
#
|
94
|
-
def search_with tokens, ids = 20, offset = 0
|
94
|
+
def search_with tokens, ids = 20, offset = 0, original_text = nil
|
95
95
|
results = nil
|
96
96
|
|
97
97
|
duration = timed do
|
98
|
-
results = execute tokens, ids, offset
|
98
|
+
results = execute tokens, ids, offset, original_text
|
99
99
|
end
|
100
100
|
results.duration = duration.round 6
|
101
101
|
|
@@ -106,8 +106,8 @@ module Picky
|
|
106
106
|
#
|
107
107
|
# Note: Internal method, use #search.
|
108
108
|
#
|
109
|
-
def execute tokens, ids, offset
|
110
|
-
Results.from ids, offset, sorted_allocations(tokens)
|
109
|
+
def execute tokens, ids, offset, original_text = nil
|
110
|
+
Results.from original_text, ids, offset, sorted_allocations(tokens)
|
111
111
|
end
|
112
112
|
|
113
113
|
# Delegates the tokenizing to the query tokenizer.
|
@@ -120,7 +120,7 @@ Case sensitive? #{@case_sensitive ? "Yes." : "-"}
|
|
120
120
|
|
121
121
|
# Reject tokens after tokenizing based on the given criteria.
|
122
122
|
#
|
123
|
-
# Note: Currently only for indexing.
|
123
|
+
# Note: Currently only for indexing. TODO Put into searching as well.
|
124
124
|
#
|
125
125
|
def rejects_token_if &condition
|
126
126
|
@reject_condition = condition
|
@@ -8,7 +8,7 @@ describe Picky::Backend::File::Marshal do
|
|
8
8
|
it "delegates to the given hash" do
|
9
9
|
hash = stub :hash
|
10
10
|
|
11
|
-
hash.should_receive(:
|
11
|
+
hash.should_receive(:dump_marshal).once.with "some/cache/path/to/file.dump"
|
12
12
|
|
13
13
|
file.dump hash
|
14
14
|
end
|
@@ -22,7 +22,7 @@ describe Hash do
|
|
22
22
|
it 'uses the right file' do
|
23
23
|
File.should_receive(:open).once.with('some/file/path.dump', 'w:binary')
|
24
24
|
|
25
|
-
{}.
|
25
|
+
{}.dump_marshal 'some/file/path.dump'
|
26
26
|
end
|
27
27
|
it "uses the right encoder" do
|
28
28
|
file = stub :file
|
@@ -30,7 +30,7 @@ describe Hash do
|
|
30
30
|
|
31
31
|
Marshal.should_receive(:dump).once.with({ :some => :hash }, file)
|
32
32
|
|
33
|
-
{ :some => :hash }.
|
33
|
+
{ :some => :hash }.dump_marshal 'unimportant'
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -27,7 +27,7 @@ describe Picky::Query::Combinations::Base do
|
|
27
27
|
describe "weighted_score" do
|
28
28
|
it "uses the weights' score method" do
|
29
29
|
weights = stub :weights
|
30
|
-
weights.should_receive(:
|
30
|
+
weights.should_receive(:score_for).once.with @combinations_ary
|
31
31
|
|
32
32
|
@combinations.weighted_score weights
|
33
33
|
end
|
@@ -27,7 +27,7 @@ describe Picky::Query::Combinations::Memory do
|
|
27
27
|
describe "weighted_score" do
|
28
28
|
it "uses the weights' score method" do
|
29
29
|
weights = stub :weights
|
30
|
-
weights.should_receive(:
|
30
|
+
weights.should_receive(:score_for).once.with @combinations_ary
|
31
31
|
|
32
32
|
@combinations.weighted_score weights
|
33
33
|
end
|
@@ -71,7 +71,7 @@ describe Picky::Query::Combinations::Redis do
|
|
71
71
|
describe "weighted_score" do
|
72
72
|
it "uses the weights' score method" do
|
73
73
|
weights = stub :weights
|
74
|
-
weights.should_receive(:
|
74
|
+
weights.should_receive(:score_for).once.with @combinations_ary
|
75
75
|
|
76
76
|
@combinations.weighted_score weights
|
77
77
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Picky::Query::Weights do
|
4
|
-
|
4
|
+
|
5
5
|
context 'with weights' do
|
6
6
|
before(:each) do
|
7
7
|
@weights = described_class.new [:test1, :test2] => 6,
|
@@ -18,7 +18,18 @@ describe Picky::Query::Weights do
|
|
18
18
|
[:test3, :test1] => 2,
|
19
19
|
[:test1, :test3] => 2
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
|
+
describe 'score_for' do
|
23
|
+
it 'gets the category names from the combinations' do
|
24
|
+
combinations = [
|
25
|
+
stub(:combination1, :category_name => :test1),
|
26
|
+
stub(:combination1, :category_name => :test2)
|
27
|
+
]
|
28
|
+
|
29
|
+
@weights.score_for(combinations).should == +6
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
22
33
|
describe "weight_for" do
|
23
34
|
it "should return zero if there is no specific weight" do
|
24
35
|
@weights.weight_for([:not_a_specific_allocation]).should be_zero
|
data/spec/lib/results_spec.rb
CHANGED
@@ -10,14 +10,14 @@ describe Picky::Results do
|
|
10
10
|
@results.stub! :prepare!
|
11
11
|
end
|
12
12
|
it "should generate a result" do
|
13
|
-
described_class.from(20, 0, @allocations).should == @results
|
13
|
+
described_class.from("some query", 20, 0, @allocations).should == @results
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe "ids" do
|
18
18
|
before(:each) do
|
19
19
|
@allocations = stub :allocations
|
20
|
-
@results = described_class.new :unimportant, :unimportant, @allocations
|
20
|
+
@results = described_class.new :unimportant, :unimportant, :unimportant, @allocations
|
21
21
|
end
|
22
22
|
it "delegates" do
|
23
23
|
@allocations.should_receive(:ids).once.with :anything
|
@@ -26,17 +26,17 @@ describe Picky::Results do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
describe '
|
29
|
+
describe 'to_s' do
|
30
30
|
before(:each) do
|
31
31
|
time = stub :time, :to_s => '0-08-16 10:07:33'
|
32
32
|
Time.stub! :now => time
|
33
33
|
end
|
34
34
|
context 'without results' do
|
35
35
|
before(:each) do
|
36
|
-
@results = described_class.new
|
36
|
+
@results = described_class.new "some_query"
|
37
37
|
end
|
38
38
|
it 'should output a default log' do
|
39
|
-
@results.
|
39
|
+
@results.to_s.should == '.|0-08-16 10:07:33|0.000000|some_query | 0| 0| 0|'
|
40
40
|
end
|
41
41
|
end
|
42
42
|
context 'with results' do
|
@@ -45,12 +45,12 @@ describe Picky::Results do
|
|
45
45
|
:process! => nil,
|
46
46
|
:size => 12
|
47
47
|
|
48
|
-
@results = described_class.new 20, 1234, @allocations
|
48
|
+
@results = described_class.new "some_query", 20, 1234, @allocations
|
49
49
|
@results.stub! :duration => 0.1234567890,
|
50
50
|
:total => 12345678
|
51
51
|
end
|
52
52
|
it 'should output a specific log' do
|
53
|
-
@results.
|
53
|
+
@results.to_s.should == '>|0-08-16 10:07:33|0.123457|some_query |12345678|1234|12|'
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -70,7 +70,7 @@ describe Picky::Results do
|
|
70
70
|
before(:each) do
|
71
71
|
@allocations = stub :allocations, :process! => nil, :to_result => :allocations, :total => :some_total
|
72
72
|
|
73
|
-
@results = described_class.new :some_results_amount, :some_offset, @allocations
|
73
|
+
@results = described_class.new :unimportant, :some_results_amount, :some_offset, @allocations
|
74
74
|
@results.duration = :some_duration
|
75
75
|
end
|
76
76
|
it 'should do it correctly' do
|
@@ -82,12 +82,23 @@ describe Picky::Results do
|
|
82
82
|
|
83
83
|
describe "accessors" do
|
84
84
|
before(:each) do
|
85
|
-
@results = described_class.new :
|
86
|
-
|
85
|
+
@results = described_class.new :query, :amount, :offset, :allocations
|
86
|
+
end
|
87
|
+
it "should have accessors for query" do
|
88
|
+
@results.query.should == :query
|
89
|
+
end
|
90
|
+
it "should have accessors for amount" do
|
91
|
+
@results.amount.should == :amount
|
92
|
+
end
|
93
|
+
it "should have accessors for offset" do
|
94
|
+
@results.offset.should == :offset
|
95
|
+
end
|
96
|
+
it "should have accessors for allocations" do
|
97
|
+
@results.allocations.should == :allocations
|
87
98
|
end
|
88
99
|
it "should have accessors for duration" do
|
89
|
-
@results.duration =
|
90
|
-
@results.duration.should ==
|
100
|
+
@results.duration = :some_duration
|
101
|
+
@results.duration.should == :some_duration
|
91
102
|
end
|
92
103
|
end
|
93
104
|
|
data/spec/lib/search_spec.rb
CHANGED
@@ -102,10 +102,17 @@ describe Picky::Search do
|
|
102
102
|
before(:each) do
|
103
103
|
@search = described_class.new
|
104
104
|
end
|
105
|
-
it "delegates to search_with" do
|
105
|
+
it "delegates to search_with correctly" do
|
106
106
|
@search.stub! :tokenized => :tokens
|
107
107
|
|
108
|
-
@search.should_receive(:search_with).once.with :tokens, 20,
|
108
|
+
@search.should_receive(:search_with).once.with :tokens, 20, 10, :text
|
109
|
+
|
110
|
+
@search.search :text, 20, 10
|
111
|
+
end
|
112
|
+
it "delegates to search_with correctly" do
|
113
|
+
@search.stub! :tokenized => :tokens
|
114
|
+
|
115
|
+
@search.should_receive(:search_with).once.with :tokens, 20, 0, :text
|
109
116
|
|
110
117
|
@search.search :text, 20, 0
|
111
118
|
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: picky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 3.0.0
|
4
|
+
prerelease:
|
5
|
+
version: 3.0.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Florian Hanke
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-16 00:00:00 +10:00
|
14
14
|
default_executable: picky
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 3.0.0
|
35
|
+
version: 3.0.0
|
36
36
|
type: :development
|
37
37
|
version_requirements: *id002
|
38
38
|
description: Fast Ruby semantic text search engine with comfortable single field interface.
|
@@ -288,9 +288,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
288
288
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
289
289
|
none: false
|
290
290
|
requirements:
|
291
|
-
- - "
|
291
|
+
- - ">="
|
292
292
|
- !ruby/object:Gem::Version
|
293
|
-
version:
|
293
|
+
version: "0"
|
294
294
|
requirements: []
|
295
295
|
|
296
296
|
rubyforge_project: http://rubyforge.org/projects/picky
|