Replacing fuzzy search with fuse.js
parent
41fb82b9d2
commit
6510f06e0e
|
@ -57,7 +57,7 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
|
|||
delete pageMeta[key];
|
||||
}
|
||||
}
|
||||
console.log("Extracted page meta data", pageMeta);
|
||||
// console.log("Extracted page meta data", pageMeta);
|
||||
await index.set(name, "meta:", pageMeta);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { buildHandebarOptions } from "./util.ts";
|
|||
import type { PageMeta } from "../../web/types.ts";
|
||||
|
||||
export async function queryComplete(completeEvent: CompleteEvent) {
|
||||
const match = /#query ([\w\-_]+)*$/.exec(completeEvent.linePrefix);
|
||||
const match = /#query ([\w\-_]*)$/.exec(completeEvent.linePrefix);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -9,11 +9,7 @@ import { FilterOption } from "../types.ts";
|
|||
import { FunctionalComponent } from "https://esm.sh/v99/preact@10.11.3/src/index";
|
||||
import { FeatherProps } from "https://esm.sh/v99/preact-feather@4.2.1/dist/types";
|
||||
import { MiniEditor } from "./mini_editor.tsx";
|
||||
import { fuzzySearchAndSort } from "./fuzzy_search.ts";
|
||||
|
||||
type FilterResult = FilterOption & {
|
||||
result?: any;
|
||||
};
|
||||
import { fuzzySearchAndSort } from "./fuse_search.ts";
|
||||
|
||||
export function FilterList({
|
||||
placeholder,
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import { FilterOption } from "../types.ts";
|
||||
import { assertEquals } from "../../test_deps.ts";
|
||||
import { fuzzySearchAndSort } from "./fuse_search.ts";
|
||||
|
||||
Deno.test("testFuzzyFilter", () => {
|
||||
const array: FilterOption[] = [
|
||||
{ name: "My Company/Hank", orderId: 2 },
|
||||
{ name: "My Company/Hane", orderId: 1 },
|
||||
{ name: "My Company/Steve Co" },
|
||||
{ name: "Other/Steve" },
|
||||
{ name: "Steve" },
|
||||
];
|
||||
|
||||
// Prioritize match in last path part
|
||||
let results = fuzzySearchAndSort(array, "");
|
||||
assertEquals(results.length, array.length);
|
||||
results = fuzzySearchAndSort(array, "Steve");
|
||||
assertEquals(results.length, 3);
|
||||
results = fuzzySearchAndSort(array, "Co");
|
||||
// Match in last path part
|
||||
assertEquals(results[0].name, "My Company/Steve Co");
|
||||
// Due to orderId
|
||||
assertEquals(results[1].name, "My Company/Hane");
|
||||
assertEquals(results[2].name, "My Company/Hank");
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
// @deno-types="https://deno.land/x/fuse@v6.4.1/dist/fuse.d.ts"
|
||||
import Fuse from "https://deno.land/x/fuse@v6.4.1/dist/fuse.esm.min.js";
|
||||
import { FilterOption } from "../types.ts";
|
||||
|
||||
type FuseOption = FilterOption & {
|
||||
baseName: string;
|
||||
};
|
||||
|
||||
export const fuzzySearchAndSort = (
|
||||
arr: FilterOption[],
|
||||
searchPhrase: string,
|
||||
): FilterOption[] => {
|
||||
if (!searchPhrase) {
|
||||
return arr.sort((a, b) => (a.orderId || 0) - (b.orderId || 0));
|
||||
}
|
||||
const enrichedArr: FuseOption[] = arr.map((item) => {
|
||||
return { ...item, baseName: item.name.split("/").pop()! };
|
||||
});
|
||||
const fuse = new Fuse(enrichedArr, {
|
||||
keys: [{
|
||||
name: "name",
|
||||
weight: 0.3,
|
||||
}, {
|
||||
name: "baseName",
|
||||
weight: 0.7,
|
||||
}],
|
||||
includeScore: true,
|
||||
shouldSort: true,
|
||||
isCaseSensitive: false,
|
||||
threshold: 0.6,
|
||||
sortFn: (a, b): number => {
|
||||
// console.log(a, b);
|
||||
if (a.score === b.score) {
|
||||
const aOrder = enrichedArr[a.idx].orderId || 0;
|
||||
const bOrder = enrichedArr[b.idx].orderId || 0;
|
||||
if (aOrder !== bOrder) {
|
||||
return aOrder - bOrder;
|
||||
}
|
||||
}
|
||||
return a.score - b.score;
|
||||
},
|
||||
});
|
||||
|
||||
const results = fuse.search(searchPhrase);
|
||||
// console.log("results", results);
|
||||
return results.map((r) => r.item);
|
||||
};
|
Loading…
Reference in New Issue