"""/api/v1/search/* — 搜索建议(autocomplete,纯 keyword 续接词)。 - GET /api/v1/search/suggestions?q=prefix 返回:{"query", "keywords": [...]} - keywords: 词频续接词(按 weight DESC),输入"美国"→ ["美国", "美国政府", "美国签证", ...] - 冷启动:search_keywords 表空时自动 fallback 到实时 ts_stat - 鉴权:跟 articles 一致(需要登录) 性能:prefix_keys @> ARRAY['美'] 走 GIN 数组索引,亚毫秒。 """ from __future__ import annotations from fastapi import APIRouter, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession from app.core.deps import get_current_user from app.database import get_session from app.models.user import User from app.schemas.search import SearchKeywordItem, SearchSuggestionsResponse from app.services.search import SearchService router = APIRouter(prefix="/search", tags=["search"]) @router.get("/suggestions", response_model=SearchSuggestionsResponse) async def get_suggestions( q: str = Query(..., min_length=1, max_length=20, description="搜索前缀"), limit: int = Query(10, ge=1, le=20, description="最多返回多少"), _user: User = Depends(get_current_user), # 需要登录,跟 articles 一致 session: AsyncSession = Depends(get_session), ): """搜索建议:输入 prefix,返回高频词续接。 用法:前端搜索框 onChange 时调用,debounce 250ms。 选词 → 自动填入 q + 触发搜索。 """ svc = SearchService(session) raw = await svc.suggestions(q=q, limit=limit) return SearchSuggestionsResponse( query=raw["query"], keywords=[SearchKeywordItem(**k) for k in raw["keywords"]], )