This commit is contained in:
ondal 2025-06-17 13:06:44 +09:00
parent 8b9663a5a9
commit 66f3df24bf
3 changed files with 95 additions and 16 deletions

View File

@ -30,7 +30,7 @@ from contextlib import asynccontextmanager
from datetime import datetime
from typing import Optional
import asyncio
from fastapi import FastAPI, HTTPException, Depends, Path
from fastapi import FastAPI, HTTPException, Depends, Path, Query
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
@ -623,25 +623,36 @@ async def action_recommendation_simple(
"/vector-status",
response_model=VectorDBStatusResponse,
summary="Vector DB 상태 조회",
description="Vector DB의 현재 상태 조회합니다."
description="Vector DB의 현재 상태와 수집된 매장 ID 목록을 조회합니다."
)
async def get_vector_status(vector_service: VectorService = Depends(get_vector_service)):
"""Vector DB 상태를 조회합니다."""
async def get_vector_status(
include_store_ids: bool = Query(True, description="매장 ID 목록 포함 여부"),
store_limit: int = Query(200, description="매장 ID 목록 최대 개수", ge=1, le=1000),
vector_service: VectorService = Depends(get_vector_service)
):
"""Vector DB 상태와 수집된 매장 ID 목록을 조회합니다."""
try:
db_status = vector_service.get_db_status()
# store_id 목록 포함 여부와 제한 개수 전달
db_status = vector_service.get_db_status(
include_store_ids=include_store_ids,
store_limit=store_limit
)
status = VectorDBStatus(
collection_name=db_status['collection_name'],
total_documents=db_status['total_documents'],
total_stores=db_status['total_stores'],
db_path=db_status['db_path'],
last_updated=db_status.get('last_updated')
last_updated=db_status.get('last_updated'),
# 새로 추가되는 정보
store_ids=db_status.get('store_ids', [])
)
store_count = len(db_status.get('store_ids', []))
return VectorDBStatusResponse(
success=True,
status=status,
message="Vector DB 상태 조회 성공"
message=f"Vector DB 상태 조회 성공 - {store_count}개 매장 ID 포함"
)
except Exception as e:
@ -652,7 +663,8 @@ async def get_vector_status(vector_service: VectorService = Depends(get_vector_s
collection_name="unknown",
total_documents=0,
total_stores=0,
db_path="unknown"
db_path="unknown",
store_ids=[]
),
message=f"상태 조회 실패: {str(e)}"
)

View File

@ -96,6 +96,7 @@ class VectorStoreDocument(BaseModel):
review_summary: Dict[str, Any] = Field(description="리뷰 요약 정보")
last_updated: str = Field(description="마지막 업데이트 시간")
class VectorDBStatus(BaseModel):
"""Vector DB 상태 정보"""
collection_name: str = Field(description="컬렉션명")
@ -103,6 +104,7 @@ class VectorDBStatus(BaseModel):
total_stores: int = Field(description="총 가게 수")
db_path: str = Field(description="DB 경로")
last_updated: Optional[str] = Field(None, description="마지막 업데이트 시간")
store_ids: List[str] = Field(default=[], description="수집된 매장 ID 목록")
class VectorDBStatusResponse(BaseModel):
"""Vector DB 상태 조회 응답"""

View File

@ -892,8 +892,14 @@ class VectorService:
return recommendations
def get_db_status(self) -> Dict[str, Any]:
"""DB 상태 정보 반환"""
def get_db_status(self, include_store_ids: bool = True, store_limit: int = 200) -> Dict[str, Any]:
"""
DB 상태 정보 반환 - store_id 목록 포함
Args:
include_store_ids: store_id 목록 포함 여부
store_limit: store_id 목록 최대 개수
"""
try:
if not self.is_ready():
return {
@ -902,19 +908,27 @@ class VectorService:
'total_stores': 0,
'db_path': self.db_path,
'status': 'not_ready',
'error': self.initialization_error
'error': self.initialization_error,
'store_ids': []
}
# 컬렉션 정보 조회
# 기본 컬렉션 정보 조회
count = self.collection.count()
# store_id 목록 조회 (옵션)
store_ids = []
if include_store_ids:
store_ids = self.get_all_store_ids(limit=store_limit)
return {
'collection_name': self.collection_name,
'total_documents': count,
'total_stores': count, # 각 문서가 하나의 가게를 나타냄
'total_stores': len(store_ids) if include_store_ids else count,
'db_path': self.db_path,
'status': 'ready',
'last_updated': datetime.now().isoformat()
'last_updated': datetime.now().isoformat(),
# 새로 추가되는 정보
'store_ids': store_ids
}
except Exception as e:
@ -925,7 +939,8 @@ class VectorService:
'total_stores': 0,
'db_path': self.db_path,
'status': 'error',
'error': str(e)
'error': str(e),
'store_ids': []
}
def get_existing_store_data(self, region: str = None, food_category: str = None) -> Dict[str, Dict[str, Any]]:
@ -1238,4 +1253,54 @@ class VectorService:
except Exception as e:
logger.error(f"❌ 매장 정보 조회 실패: store_id={store_id}, error={e}")
return None
return None
def get_all_store_ids(self, limit: int = 200) -> List[str]:
"""
Vector DB에 저장된 모든 store_id 목록을 조회합니다.
Args:
limit: 반환할 최대 store_id (기본값: 200)
Returns:
store_id 문자열 리스트
"""
try:
if not self.is_ready():
logger.warning("⚠️ VectorService가 준비되지 않음")
return []
logger.info(f"🏪 전체 store_id 목록 조회 시작 (최대 {limit}개)")
# Vector DB에서 모든 메타데이터 조회
results = self.collection.get(
include=['metadatas'],
limit=limit # 성능을 위한 제한
)
if not results or not results.get('metadatas'):
logger.info("📊 Vector DB에 저장된 매장이 없습니다")
return []
# store_id만 추출 및 중복 제거
store_ids = []
seen_ids = set()
for metadata in results['metadatas']:
if not metadata:
continue
store_id = metadata.get('store_id', '')
if store_id and store_id not in seen_ids:
store_ids.append(store_id)
seen_ids.add(store_id)
# store_id로 정렬 (숫자 순서)
store_ids.sort()
logger.info(f"✅ store_id 목록 조회 완료: {len(store_ids)}")
return store_ids
except Exception as e:
logger.error(f"❌ store_id 목록 조회 실패: {e}")
return []