Class: GraphedFuzzySearch::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/graphed_fuzzy_search.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(objects, attributes: [:to_s], token_regex: DEFAULT_TOKEN_REGEX, normal_weight: 1, different_token_weight: 5) ⇒ Collection

Returns a new instance of Collection.



11
12
13
14
15
16
17
18
# 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

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



24
25
26
# File 'lib/graphed_fuzzy_search.rb', line 24

def attributes
  @attributes
end

#different_token_weightObject (readonly)

Returns the value of attribute different_token_weight.



25
26
27
# File 'lib/graphed_fuzzy_search.rb', line 25

def different_token_weight
  @different_token_weight
end

#normal_weightObject (readonly)

Returns the value of attribute normal_weight.



25
26
27
# File 'lib/graphed_fuzzy_search.rb', line 25

def normal_weight
  @normal_weight
end

#objectsObject (readonly)

Returns the value of attribute objects.



24
25
26
# File 'lib/graphed_fuzzy_search.rb', line 24

def objects
  @objects
end

#token_regexObject (readonly)

Returns the value of attribute token_regex.



24
25
26
# File 'lib/graphed_fuzzy_search.rb', line 24

def token_regex
  @token_regex
end

Instance Method Details

#inspectObject



20
21
22
# File 'lib/graphed_fuzzy_search.rb', line 20

def inspect
  "#<#{self.class.name}>"
end

#itemsObject



52
53
54
55
56
57
58
59
60
61
62
63
# 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)
    Item.new(obj, attrs[0], tokens)
  end
end

#query(*args, **kwargs) ⇒ Object



27
28
29
# 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) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 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

#treesObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/graphed_fuzzy_search.rb', line 65

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