Files
LittleWhiteBox/modules/story-summary/vector/search-index.js
2026-01-26 01:16:35 +08:00

94 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ═══════════════════════════════════════════════════════════════════════════
// MiniSearch Index Manager
// 全文搜索索引管理
// ═══════════════════════════════════════════════════════════════════════════
import MiniSearch from '../../../libs/minisearch.mjs';
// 索引缓存chatId -> { index, updatedAt }
const indexCache = new Map();
/**
* 获取或创建搜索索引
* @param {string} chatId
* @param {Array} events - L2 事件
* @param {number} storeUpdatedAt - store.updatedAt 时间戳
* @returns {MiniSearch}
*/
export function getSearchIndex(chatId, events, storeUpdatedAt) {
const cached = indexCache.get(chatId);
// 缓存有效
if (cached && cached.updatedAt >= storeUpdatedAt) {
return cached.index;
}
// 重建索引
const index = new MiniSearch({
fields: ['title', 'summary', 'participants'],
storeFields: ['id'],
searchOptions: {
boost: { title: 2, participants: 1.5, summary: 1 },
fuzzy: 0.2,
prefix: true,
},
});
// 索引事件
const docs = events.map(e => ({
id: e.id,
title: e.title || '',
summary: e.summary || '',
participants: (e.participants || []).join(' '),
}));
index.addAll(docs);
// 缓存
indexCache.set(chatId, { index, updatedAt: storeUpdatedAt });
// 限制缓存数量
if (indexCache.size > 5) {
const firstKey = indexCache.keys().next().value;
indexCache.delete(firstKey);
}
return index;
}
/**
* 关键词搜索
* @returns {Map<string, number>} - eventId -> 归一化分数
*/
export function searchByKeywords(index, queryText, limit = 20) {
if (!queryText?.trim()) return new Map();
const results = index.search(queryText, { limit });
if (results.length === 0) return new Map();
// 归一化分数到 0-1
const maxScore = results[0].score;
const scores = new Map();
for (const r of results) {
scores.set(r.id, r.score / maxScore);
}
return scores;
}
/**
* 清除指定聊天的索引缓存
*/
export function invalidateIndex(chatId) {
indexCache.delete(chatId);
}
/**
* 清除所有索引缓存
*/
export function clearAllIndexes() {
indexCache.clear();
}