similar_cases_local.py 1.1 KB

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