""" Qdrant Vector Database Service — NiBiS RAG Search for Klausurkorrektur. """ from typing import List, Dict, Optional from qdrant_client.models import Filter, FieldCondition, MatchValue from qdrant_core import get_qdrant_client async def search_nibis_eh( query_embedding: List[float], year: Optional[int] = None, subject: Optional[str] = None, niveau: Optional[str] = None, limit: int = 5 ) -> List[Dict]: """ Search in NiBiS Erwartungshorizonte (public, pre-indexed data). Unlike search_eh(), this searches in the public NiBiS collection and returns plaintext (not encrypted). Args: query_embedding: Query vector year: Optional year filter (2016, 2017, 2024, 2025) subject: Optional subject filter niveau: Optional niveau filter (eA, gA) limit: Max results Returns: List of matching chunks with metadata """ client = get_qdrant_client() collection = "bp_nibis_eh" # Build filter must_conditions = [] if year: must_conditions.append( FieldCondition(key="year", match=MatchValue(value=year)) ) if subject: must_conditions.append( FieldCondition(key="subject", match=MatchValue(value=subject)) ) if niveau: must_conditions.append( FieldCondition(key="niveau", match=MatchValue(value=niveau)) ) query_filter = Filter(must=must_conditions) if must_conditions else None try: results = client.search( collection_name=collection, query_vector=query_embedding, query_filter=query_filter, limit=limit ) return [ { "id": str(r.id), "score": r.score, "text": r.payload.get("text", ""), "year": r.payload.get("year"), "subject": r.payload.get("subject"), "niveau": r.payload.get("niveau"), "task_number": r.payload.get("task_number"), "doc_type": r.payload.get("doc_type"), "variant": r.payload.get("variant"), } for r in results ] except Exception as e: print(f"NiBiS search error: {e}") return []