feat(media): media.Store 加向量存储与跨模态检索

media.Item 新增 Vec []float64 和 VecModel 字段,视觉嵌入向量以 JSON
TEXT 存库(为什么不存 BLOB:Go 的 json.Marshal 对 []float64 是自然的,
而 SQLite BLOB 是 []byte 多一层序列化;单条最多 23KB,TEXT 够用)。

initSchema 加 ALTER TABLE 迁移 vec/vec_model 两列(幂等)。scanItem
扩展读回。新增 SetVec 和 QueryMedia 方法。

QueryMedia 对所有已嵌入媒体做余弦相似度检索,维度不一致的项自动跳过
——这是跨模态检索的核心:查询可以是图片也可以是文本,被查的媒体库
里每个 item 也有视觉向量,两者在同一空间比对,谁的相似度更高就召回谁。

配套 5 个单测覆盖:基本相似度排序、无向量项被跳过、维度不匹配过滤、
空查询安全、向量持久化正确性。
This commit is contained in:
JianFeeeee
2026-09-07 22:31:39 +08:00
parent 10dafd5ccb
commit a668e1f732
2 changed files with 137 additions and 1 deletions

View File

@ -276,7 +276,8 @@ func (s *Store) Stat(digest string) (*Item, error) {
defer s.mu.RUnlock()
return s.scanOne(s.db.QueryRow(`
SELECT digest, kind, mime, size, width, height, origin_path, tool,
description, described_by, ref_count, first_seen, last_seen
description, described_by, ref_count, first_seen, last_seen,
vec, vec_model
FROM media WHERE digest = ?`, digest))
}