MCPcopy Create free account
hub / github.com/MemTensor/MemOS / ftsSearch

Method ftsSearch

packages/memos-core/src/storage/sqlite.ts:1244–1277  ·  view source on GitHub ↗
(query: string, limit: number, ownerFilter?: string[])

Source from the content-addressed store, hash-verified

1242 // ─── FTS Search ───
1243
1244 ftsSearch(query: string, limit: number, ownerFilter?: string[]): Array<{ chunkId: string; score: number }> {
1245 const sanitized = sanitizeFtsQuery(query);
1246 if (!sanitized) return [];
1247
1248 try {
1249 let sql = `
1250 SELECT c.id as chunk_id, rank
1251 FROM chunks_fts f
1252 JOIN chunks c ON c.rowid = f.rowid
1253 WHERE chunks_fts MATCH ? AND c.dedup_status = 'active'`;
1254 const params: any[] = [sanitized];
1255
1256 if (ownerFilter && ownerFilter.length > 0) {
1257 const placeholders = ownerFilter.map(() => "?").join(",");
1258 sql += ` AND c.owner IN (${placeholders})`;
1259 params.push(...ownerFilter);
1260 }
1261
1262 sql += ` ORDER BY rank LIMIT ?`;
1263 params.push(limit);
1264
1265 const rows = this.db.prepare(sql).all(...params) as Array<{ chunk_id: string; rank: number }>;
1266
1267 if (rows.length === 0) return [];
1268 const maxAbsRank = Math.max(...rows.map((r) => Math.abs(r.rank)));
1269 return rows.map((r) => ({
1270 chunkId: r.chunk_id,
1271 score: maxAbsRank > 0 ? Math.abs(r.rank) / maxAbsRank : 0,
1272 }));
1273 } catch {
1274 this.log.warn(`FTS query failed for: "${sanitized}", returning empty`);
1275 return [];
1276 }
1277 }
1278
1279 // ─── Pattern Search (LIKE-based, for CJK text where FTS tokenization is weak) ───
1280

Callers 1

searchMethod · 0.45

Calls 6

mapMethod · 0.80
allMethod · 0.80
prepareMethod · 0.80
sanitizeFtsQueryFunction · 0.70
warnMethod · 0.65
joinMethod · 0.45

Tested by

no test coverage detected