30 lines
1.2 KiB
Python
30 lines
1.2 KiB
Python
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import or_, text
|
|
from app.db.session import get_db
|
|
from app.pipeline.enricher import Enricher
|
|
|
|
router = APIRouter(prefix="/api")
|
|
enricher = Enricher()
|
|
|
|
@router.get("/search")
|
|
def search(q: str = "", category: str = None, person: str = None,
|
|
date: str = None, page: int = None, job_id: int = None, semantic: bool = False, db=Depends(get_db)):
|
|
from app.db.models import Article
|
|
query = db.query(Article)
|
|
if category: query = query.filter(Article.category == category)
|
|
if date: query = query.filter(Article.date == date)
|
|
if page: query = query.filter(Article.page == page)
|
|
if job_id: query = query.filter(Article.upload_job_id == job_id)
|
|
if person: query = query.filter(Article.persons.any(person))
|
|
if q and not semantic:
|
|
query = query.filter(or_(Article.headline.ilike(f"%{q}%"),
|
|
Article.text.ilike(f"%{q}%")))
|
|
return query.limit(50).all()
|
|
if semantic and q:
|
|
vec = enricher.embed(q)
|
|
# pgvector cosine distance
|
|
return db.execute(text("""
|
|
SELECT * FROM articles ORDER BY embedding <=> :v LIMIT 30
|
|
"""), {"v": str(vec)}).fetchall()
|
|
return query.limit(50).all()
|