5c028d7952
包含 FastAPI 后端、React 前端、队列/OCR/标签/待办等完整功能。 Co-authored-by: Cursor <cursoragent@cursor.com>
68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
"""截图列表搜索:FTS + 子串模糊(兼容中文标签/标题)。"""
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import or_, select, text
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.meta import ScreenshotMeta
|
|
from app.models.screenshot import Screenshot
|
|
from app.models.tag import Tag
|
|
|
|
|
|
def fts_query_string(raw: str) -> str:
|
|
"""把用户输入处理成 FTS5 查询串(中英文均支持前缀匹配)。"""
|
|
parts = [p for p in raw.replace("\n", " ").split() if p]
|
|
if not parts:
|
|
return raw
|
|
cleaned: list[str] = []
|
|
for p in parts:
|
|
p = p.replace('"', "").strip()
|
|
if not p:
|
|
continue
|
|
cleaned.append(f'"{p}"*')
|
|
return " ".join(cleaned)
|
|
|
|
|
|
def collect_search_ids(session: Session, q: str, *, limit: int = 5000) -> set[int]:
|
|
"""联合 FTS5 与 LIKE 子串搜索,返回匹配的 screenshot id 集合。"""
|
|
q = q.strip()
|
|
if not q:
|
|
return set()
|
|
|
|
ids: set[int] = set()
|
|
like = f"%{q}%"
|
|
|
|
# 1) FTS5 全文索引
|
|
try:
|
|
fts_sql = text(
|
|
"SELECT rowid FROM screenshots_fts WHERE screenshots_fts MATCH :q LIMIT :lim"
|
|
)
|
|
rows = session.execute(fts_sql, {"q": fts_query_string(q), "lim": limit}).fetchall()
|
|
ids.update(int(row[0]) for row in rows)
|
|
except Exception:
|
|
pass
|
|
|
|
# 2) 子串模糊:OCR/AI 文本(解决「三花」匹配「三花猫」)
|
|
meta_ids = session.scalars(
|
|
select(ScreenshotMeta.screenshot_id).where(
|
|
or_(
|
|
ScreenshotMeta.ocr_text.ilike(like),
|
|
ScreenshotMeta.ai_title.ilike(like),
|
|
ScreenshotMeta.ai_summary.ilike(like),
|
|
ScreenshotMeta.ai_suggestion.ilike(like),
|
|
)
|
|
).limit(limit)
|
|
).all()
|
|
ids.update(int(i) for i in meta_ids)
|
|
|
|
# 3) 标签名子串匹配
|
|
tag_ids = session.scalars(
|
|
select(Screenshot.id)
|
|
.join(Screenshot.tags)
|
|
.where(Tag.name.ilike(like))
|
|
.limit(limit)
|
|
).all()
|
|
ids.update(int(i) for i in tag_ids)
|
|
|
|
return ids
|