我正在尝试在基于Node.js的项目中实现某种“模糊搜索”。
模糊搜索是一种即使字符串不完全匹配也会返回结果的搜索。
我在另一个stackoverflow thread中找到了这段代码。代码如下。
这很好,但问题是 - 它是同步的当它搜索大型数组时,它会减慢整个程序的速度。
欢迎使用ES6方法。只需要在最新的Chrome中使用,因此任何JS方法都可以使用。
是否有任何新的JS方法可以优化此功能?
我做错了什么让它更慢?
我可以将此函数转换为返回promise的异步函数吗?它会在搜索过程中停止冻结应用程序吗?
你知道有没有更好的“模糊搜索”实现? (我找到了一个名为fuzzysort的模块,不能说它是否好得多,如果你输入"folder test"
(错误的顺序)它就不会返回"test folder"
所以它不是那么好)
调用搜索功能
searchArray 是其搜索的路径数组,例如:["C:\\test", "C:\\file.txt"...]
(0.5-5百万路径)
searchQuery 是一个没有空格的字符串,例如:filetxt
search () {
const fuzzySearch = this.fuzzySearch(this.searchQuery.toLowerCase(), this.searchArray)
let result = fuzzySearch.filter(element => element.relevance >= 0.3)
// sort by relevance
var sortedResults = result.sort((a, b) => parseFloat(b.relevance) - parseFloat(a.relevance)).map(item => item.name);
this.searchResults = sortedResults
},
模糊搜索功能
fuzzySearch (searchQuery, searchArray) {
const get_bigrams = function(string) {
const s = string.toLowerCase();
const v = new Array(s.length - 1);
for (let i = 0, end = v.length; i <= end; i++) {
v[i] = s.slice(i, i + 2);
}
return v;
};
const string_similarity = function(str1, str2) {
if ((str1.length > 0) && (str2.length > 0)) {
const pairs1 = get_bigrams(str1);
const pairs2 = get_bigrams(str2);
const union = pairs1.length + pairs2.length;
let hit_count = 0;
for (let x of Array.from(pairs1)) {
for (let y of Array.from(pairs2)) {
if (x === y) {
hit_count++;
}
}
}
if (hit_count > 0) {
return ((2.0 * hit_count) / union);
}
}
return 0.0;
};
let results = [];
for (let name of searchArray) {
// I added .match to use only the base filename (name+ext) not the whole path, and removed all characters
let filteredPath = name.match(/[^\\\/]+$/)[0].replace(/[^A-Za-z0-9.]+/g, '')
const relevance = string_similarity(searchQuery, filteredPath);
const obj = {name, relevance};
results.push(obj);
}
return results
},