Full text search improvements
parent
02dd2f17c7
commit
9164b57a3e
|
@ -8,6 +8,17 @@ export function fullTextDelete(key: string) {
|
||||||
return syscall("fulltext.delete", key);
|
return syscall("fulltext.delete", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fullTextSearch(phrase: string, limit = 100) {
|
export type FullTextSearchOptions = {
|
||||||
return syscall("fulltext.search", phrase, limit);
|
limit?: number;
|
||||||
|
highlightPrefix?: string;
|
||||||
|
highlightPostfix?: string;
|
||||||
|
highlightEllipsis?: string;
|
||||||
|
summaryMaxLength?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function fullTextSearch(
|
||||||
|
phrase: string,
|
||||||
|
options: FullTextSearchOptions = {},
|
||||||
|
) {
|
||||||
|
return syscall("fulltext.search", phrase, options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ async function bundleRun(
|
||||||
console.error(`Error building ${manifestPath}:`, e);
|
console.error(`Error building ${manifestPath}:`, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("Done.");
|
console.log("Done building plugs.");
|
||||||
building = false;
|
building = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { FullTextSearchOptions } from "../../plug-api/plugos-syscall/fulltext.ts";
|
||||||
import { AsyncSQLite } from "../../plugos/sqlite/async_sqlite.ts";
|
import { AsyncSQLite } from "../../plugos/sqlite/async_sqlite.ts";
|
||||||
import { SysCallMapping } from "../system.ts";
|
import { SysCallMapping } from "../system.ts";
|
||||||
|
|
||||||
|
@ -34,15 +35,30 @@ export function fullTextSearchSyscalls(
|
||||||
"fulltext.delete": async (_ctx, key: string) => {
|
"fulltext.delete": async (_ctx, key: string) => {
|
||||||
await db.execute(`DELETE FROM ${tableName} WHERE key = ?`, key);
|
await db.execute(`DELETE FROM ${tableName} WHERE key = ?`, key);
|
||||||
},
|
},
|
||||||
"fulltext.search": async (_ctx, phrase: string, limit: number) => {
|
"fulltext.search": async (
|
||||||
console.log("Got search query", phrase);
|
_ctx,
|
||||||
|
phrase: string,
|
||||||
|
options: FullTextSearchOptions,
|
||||||
|
) => {
|
||||||
return (
|
return (
|
||||||
await db.query(
|
await db.query(
|
||||||
`SELECT key, rank FROM ${tableName} WHERE value MATCH ? ORDER BY key, rank LIMIT ?`,
|
`SELECT key, bm25(fts) AS score, snippet(fts, 1, ?, ?, ?, ?) as snippet
|
||||||
|
FROM ${tableName}
|
||||||
|
WHERE value
|
||||||
|
MATCH ?
|
||||||
|
ORDER BY score LIMIT ?`,
|
||||||
|
options.highlightPrefix || "",
|
||||||
|
options.highlightPostfix || "",
|
||||||
|
options.highlightEllipsis || "...",
|
||||||
|
options.summaryMaxLength || 50,
|
||||||
phrase,
|
phrase,
|
||||||
limit,
|
options.limit || 20,
|
||||||
)
|
)
|
||||||
).map((item) => ({ name: item.key, rank: item.rank }));
|
).map((item) => ({
|
||||||
|
name: item.key,
|
||||||
|
score: item.score,
|
||||||
|
snippet: item.snippet,
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { fulltext } from "$sb/plugos-syscall/mod.ts";
|
import { fulltext } from "$sb/plugos-syscall/mod.ts";
|
||||||
import { renderToText } from "$sb/lib/tree.ts";
|
import { renderToText } from "$sb/lib/tree.ts";
|
||||||
import type { FileMeta, PageMeta } from "../../common/types.ts";
|
import type { FileMeta } from "../../common/types.ts";
|
||||||
import { editor, index } from "$sb/silverbullet-syscall/mod.ts";
|
import { editor, index } from "$sb/silverbullet-syscall/mod.ts";
|
||||||
import { IndexTreeEvent, QueryProviderEvent } from "$sb/app_event.ts";
|
import { IndexTreeEvent, QueryProviderEvent } from "$sb/app_event.ts";
|
||||||
import { applyQuery, removeQueries } from "$sb/lib/query.ts";
|
import { applyQuery, removeQueries } from "$sb/lib/query.ts";
|
||||||
|
@ -29,7 +29,10 @@ export async function queryProvider({
|
||||||
if (!phraseFilter) {
|
if (!phraseFilter) {
|
||||||
throw Error("No 'phrase' filter specified, this is mandatory");
|
throw Error("No 'phrase' filter specified, this is mandatory");
|
||||||
}
|
}
|
||||||
let results = await fulltext.fullTextSearch(phraseFilter.value, 100);
|
let results = await fulltext.fullTextSearch(phraseFilter.value, {
|
||||||
|
highlightEllipsis: "...",
|
||||||
|
limit: 100,
|
||||||
|
});
|
||||||
|
|
||||||
const allPageMap: Map<string, any> = new Map(
|
const allPageMap: Map<string, any> = new Map(
|
||||||
results.map((r: any) => [r.name, r]),
|
results.map((r: any) => [r.name, r]),
|
||||||
|
@ -65,11 +68,20 @@ export async function readFileSearch(
|
||||||
searchPrefix.length,
|
searchPrefix.length,
|
||||||
name.length - ".md".length,
|
name.length - ".md".length,
|
||||||
);
|
);
|
||||||
const results = await fulltext.fullTextSearch(phrase, 100);
|
console.log("Here");
|
||||||
|
const results = await fulltext.fullTextSearch(phrase, {
|
||||||
|
highlightEllipsis: "...",
|
||||||
|
highlightPostfix: "==",
|
||||||
|
highlightPrefix: "==",
|
||||||
|
summaryMaxLength: 30,
|
||||||
|
limit: 100,
|
||||||
|
});
|
||||||
const text = `# Search results for "${phrase}"\n${
|
const text = `# Search results for "${phrase}"\n${
|
||||||
results
|
results
|
||||||
.map((r: any) => `* [[${r.name}]] (score: ${r.rank})`)
|
.map((r: any) =>
|
||||||
.join("\n")
|
`[[${r.name}]]:\n> ${r.snippet.split("\n").join("\n> ")}`
|
||||||
|
)
|
||||||
|
.join("\n\n")
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ export async function updateMaterializedQueriesOnPage(
|
||||||
let newText = await updateTemplateInstantiations(text, pageName);
|
let newText = await updateTemplateInstantiations(text, pageName);
|
||||||
const tree = await markdown.parseMarkdown(newText);
|
const tree = await markdown.parseMarkdown(newText);
|
||||||
const metaData = extractMeta(tree, ["$disableDirectives"]);
|
const metaData = extractMeta(tree, ["$disableDirectives"]);
|
||||||
console.log("Meta data", pageName, metaData);
|
// console.log("Meta data", pageName, metaData);
|
||||||
if (metaData.$disableDirectives) {
|
if (metaData.$disableDirectives) {
|
||||||
console.log("Directives disabled, skipping");
|
console.log("Directives disabled, skipping");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -278,7 +278,8 @@ export class Editor {
|
||||||
this.saveTimeout = setTimeout(
|
this.saveTimeout = setTimeout(
|
||||||
() => {
|
() => {
|
||||||
if (this.currentPage) {
|
if (this.currentPage) {
|
||||||
if (!this.viewState.unsavedChanges) {
|
if (!this.viewState.unsavedChanges || this.viewState.forcedROMode) {
|
||||||
|
// No unsaved changes, or read-only mode, not gonna save
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
console.log("Saving page", this.currentPage);
|
console.log("Saving page", this.currentPage);
|
||||||
|
|
Loading…
Reference in New Issue