MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / fuzzy_match

Function fuzzy_match

nodedb-fts/src/fuzzy.rs:75–114  ·  view source on GitHub ↗

Find terms in the index that fuzzy-match the query term. Returns `(matched_term, edit_distance)` pairs for all terms within the adaptive distance threshold. Results are sorted by distance (closest matches first).

(
    query_term: &str,
    index_terms: impl Iterator<Item = &'a str>,
)

Source from the content-addressed store, hash-verified

73/// the adaptive distance threshold. Results are sorted by distance
74/// (closest matches first).
75pub fn fuzzy_match<'a>(
76 query_term: &str,
77 index_terms: impl Iterator<Item = &'a str>,
78) -> Vec<(&'a str, usize)> {
79 let q_char_len = query_term.chars().count();
80 let max_dist = max_distance_for_length(q_char_len);
81 if max_dist == 0 {
82 return Vec::new();
83 }
84
85 // Length-bucket prefilter: group candidates by character length, then
86 // visit only buckets within the distance window. Edit distance is at
87 // least |len(a) - len(b)|, so terms outside [q-d .. q+d] cannot match.
88 // This bounds the number of expensive O(L²) levenshtein calls to the
89 // candidates in the relevant buckets, avoiding whole-dictionary scans
90 // on large term indexes.
91 use std::collections::HashMap;
92 let mut buckets: HashMap<usize, Vec<&'a str>> = HashMap::new();
93 for term in index_terms {
94 buckets.entry(term.chars().count()).or_default().push(term);
95 }
96
97 let low = q_char_len.saturating_sub(max_dist);
98 let high = q_char_len.saturating_add(max_dist);
99 let mut matches: Vec<(&'a str, usize)> = Vec::new();
100 for len in low..=high {
101 let Some(bucket) = buckets.get(&len) else {
102 continue;
103 };
104 for term in bucket {
105 let dist = levenshtein(query_term, term);
106 if dist > 0 && dist <= max_dist {
107 matches.push((*term, dist));
108 }
109 }
110 }
111
112 matches.sort_by_key(|&(_, d)| d);
113 matches
114}
115
116/// Score discount for fuzzy matches based on edit distance.
117///

Callers 4

fuzzy_match_finds_typosFunction · 0.85
fuzzy_lookupMethod · 0.85

Calls 6

max_distance_for_lengthFunction · 0.85
levenshteinFunction · 0.85
entryMethod · 0.80
countMethod · 0.45
pushMethod · 0.45
getMethod · 0.45