class GraphedFuzzySearch::Collection
Attributes
attributes[R]
different_token_weight[R]
normal_weight[R]
objects[R]
token_regex[R]
Public Class Methods
new(objects, attributes: [:to_s], token_regex: DEFAULT_TOKEN_REGEX, normal_weight: 1, different_token_weight: 5)
click to toggle source
# File lib/graphed_fuzzy_search.rb, line 11 def initialize(objects, attributes: [:to_s], token_regex: DEFAULT_TOKEN_REGEX, normal_weight: 1, different_token_weight: 5) @objects = objects @attributes = attributes @token_regex = token_regex @normal_weight = normal_weight @different_token_weight = different_token_weight trees end
Public Instance Methods
inspect()
click to toggle source
# File lib/graphed_fuzzy_search.rb, line 20 def inspect "#<#{self.class.name}>" end
items()
click to toggle source
# File lib/graphed_fuzzy_search.rb, line 52 def items @items ||= objects.map do |obj| attrs = attributes.flat_map do |k| [*obj.send(k)] end tokens = attrs.flat_map do |attr| attr.to_s.downcase.scan(token_regex) end tokens.push(*attrs) tokens.reject!(&:empty?) Item.new(obj, attrs[0], tokens.uniq) end end
query(*args, **kwargs)
click to toggle source
# File lib/graphed_fuzzy_search.rb, line 27 def query(*args, **kwargs) query_raw(*args, **kwargs).map{ |(node, _)| node.item.object } end
query_raw(str, max_scan: str.size)
click to toggle source
# File lib/graphed_fuzzy_search.rb, line 31 def query_raw(str, max_scan: str.size) str = str.downcase chars = str.chars i = 0 needles = trees.map { |root| [root, 0] } while i < chars.size && i < max_scan && !needles.empty? char = chars[i] needles.map! { |(node, weight)| [node[char], weight] } needles.select!(&:first) needles.map! { |(conn, weight)| [conn.node, weight + conn.weight] } i += 1 end needles.map! { |(conn, weight)| if conn.item.key.start_with?(str) weight *= 0.7 end [conn, weight] } needles.sort_by(&:last) end
trees()
click to toggle source
# File lib/graphed_fuzzy_search.rb, line 66 def trees @trees ||= items.map do |item| root = Node.new(nil, [], item) token_and_heads = item.tokens.map do |token| root.mine(normal_weight, token) [token, root[token[0]].node] end token_and_heads.each do |(_, ah)| token_and_heads.each do |(bt, _)| root.walk(bt.each_char) do |n| n.connect(different_token_weight, ah) end end end root end end