ximate 0.0.2 → 0.1.0
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/ext/fuzzy_search.c +1 -1
- data/lib/ximate/search.rb +34 -17
- data/lib/ximate/version.rb +1 -1
- metadata +1 -1
data/ext/fuzzy_search.c
CHANGED
@@ -82,7 +82,7 @@ fuzzy_equal (VALUE self, VALUE text, VALUE pattern, VALUE errors_percent)
|
|
82
82
|
int distance = levenshtein_distance (t, p);
|
83
83
|
// printf ("Allowed errors: %d - Levenshtein's distance: %d\n", errors, distance);
|
84
84
|
if (distance <= errors)
|
85
|
-
return
|
85
|
+
return INT2NUM (errors - distance);
|
86
86
|
return Qfalse;
|
87
87
|
}
|
88
88
|
|
data/lib/ximate/search.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
module Ximate
|
2
2
|
|
3
3
|
DATA = {}
|
4
|
-
OPTIONS = {:order_by_rank => true,
|
4
|
+
OPTIONS = {:order_by_rank => true,
|
5
|
+
:match_error_percent => 20,
|
6
|
+
:ignore_word_short_than => 2,
|
7
|
+
:logger => true,
|
8
|
+
:debug => false}
|
5
9
|
|
6
10
|
def self.included(base)
|
7
11
|
base.extend(Search)
|
@@ -23,7 +27,7 @@ module Ximate
|
|
23
27
|
self.to_s.classify.constantize.all.each do |p|
|
24
28
|
p.update_index(locale, &block)
|
25
29
|
end
|
26
|
-
|
30
|
+
puts "\b\b=> Build XIMATE hash data for '#{table}' in #{Time.now - now}." if OPTIONS[:logger]
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
@@ -32,12 +36,22 @@ module Ximate
|
|
32
36
|
|
33
37
|
def asearch(pattern)
|
34
38
|
table = self.to_s.underscore.pluralize.to_sym
|
35
|
-
matches = {}
|
39
|
+
matches = {} # {id => rank, id => rank}
|
40
|
+
lastsearch = {} # Save last 'e' search for every word in pattern to avoid multi-search of the same word
|
41
|
+
pattern.split(' ').each { |w| lastsearch[w] = -1 }
|
36
42
|
DATA[I18n.locale] ||= {}
|
37
43
|
DATA[I18n.locale][table] ||= {}
|
38
|
-
DATA[I18n.locale][table].each do |word,
|
39
|
-
|
40
|
-
|
44
|
+
DATA[I18n.locale][table].each do |word, ids_ranks|
|
45
|
+
pattern.split(' ').each do |w|
|
46
|
+
if w.size > OPTIONS[:ignore_word_short_than]
|
47
|
+
if e = Fuzzy.equal(word, w.downcase, OPTIONS[:match_error_percent])
|
48
|
+
if e > lastsearch[w]
|
49
|
+
lastsearch[w] = e
|
50
|
+
Rails.logger.debug("XIMATE asearch: '#{word}' match with '#{w}' (e = #{e})") if OPTIONS[:debug]
|
51
|
+
ids_ranks.each { |id, rank| matches[id] = matches[id].to_i + (e**rank) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
41
55
|
end
|
42
56
|
end
|
43
57
|
return where('1 = 0') if matches.empty?
|
@@ -45,33 +59,36 @@ module Ximate
|
|
45
59
|
rel.ranks = matches if OPTIONS[:order_by_rank]
|
46
60
|
rel.where("#{table}.id IN (#{matches.keys.join(',')})")
|
47
61
|
end
|
62
|
+
|
48
63
|
end
|
49
64
|
|
50
65
|
|
51
66
|
module InstanceMethods
|
52
67
|
|
53
|
-
def add_text(text)
|
54
|
-
@words ||=
|
55
|
-
@words
|
68
|
+
def add_text(text, priority = 1)
|
69
|
+
@words ||= {}
|
70
|
+
@words[priority] ||= []
|
71
|
+
@words[priority] += text.to_s.gsub(/<[^>]*>/i, ' ').gsub(/[\.,'":;!\?\(\)]/, ' ').split(' ').map{|word| word.downcase}.uniq
|
56
72
|
end
|
57
73
|
|
58
74
|
def update_index(locale = I18n.default_locale, &block)
|
59
75
|
table = self.class.to_s.underscore.pluralize.to_sym
|
60
76
|
remove_index(locale)
|
61
77
|
instance_eval(&block)
|
62
|
-
@words.each do |
|
63
|
-
|
64
|
-
|
65
|
-
|
78
|
+
@words.each do |priority, words|
|
79
|
+
words.each do |word|
|
80
|
+
ids_ranks = (DATA[locale.to_sym][table][word] ||= {})
|
81
|
+
ids_ranks[self.id] = ids_ranks[self.id].to_i + priority
|
82
|
+
end
|
66
83
|
end
|
67
84
|
end
|
68
85
|
|
69
86
|
def remove_index(locale)
|
70
87
|
table = self.class.to_s.underscore.pluralize.to_sym
|
71
|
-
@words =
|
72
|
-
DATA[locale.to_sym][table].each do |word,
|
73
|
-
|
74
|
-
DATA[locale.to_sym][table].delete(word) if
|
88
|
+
@words = {}
|
89
|
+
DATA[locale.to_sym][table].each do |word, ids_ranks|
|
90
|
+
ids_ranks.delete(self.id)
|
91
|
+
DATA[locale.to_sym][table].delete(word) if ids_ranks.empty?
|
75
92
|
end
|
76
93
|
end
|
77
94
|
|
data/lib/ximate/version.rb
CHANGED