| 1234567891011121314151617181920212223242526272829303132333435363738 |
- import re
- from sqlalchemy.orm import Session
- from app.models import CaseRecord
- def _tokens(text: str) -> set[str]:
- if not text:
- return set()
- chunk = text[:8000]
- return set(re.findall(r"[\w\u4e00-\u9fff]+", chunk))
- def _jaccard(a: set[str], b: set[str]) -> float:
- if not a or not b:
- return 0.0
- inter = len(a & b)
- union = len(a | b)
- return inter / union if union else 0.0
- def find_similar(db: Session, exclude_case_id: int, query_text: str, limit: int = 5) -> list[dict]:
- """
- 不依赖向量库:用词集合 Jaccard 与库里历史案件粗排相似度(适合毕业设计演示)。
- """
- q = _tokens(query_text)
- rows = db.query(CaseRecord).filter(CaseRecord.id != exclude_case_id).all()
- scored: list[tuple[float, CaseRecord]] = []
- for row in rows:
- s = _jaccard(q, _tokens(row.raw_text or ""))
- scored.append((s, row))
- scored.sort(key=lambda x: x[0], reverse=True)
- return [
- {"score": float(s), "case_id": row.id, "case_name": row.case_name}
- for s, row in scored[:limit]
- if s > 0
- ]
|