From 66f3df24bf005c2681f7e6c5c50229f8fe6bf8bd Mon Sep 17 00:00:00 2001 From: ondal Date: Tue, 17 Jun 2025 13:06:44 +0900 Subject: [PATCH] release --- vector/app/main.py | 28 ++++++--- vector/app/models/vector_models.py | 2 + vector/app/services/vector_service.py | 81 ++++++++++++++++++++++++--- 3 files changed, 95 insertions(+), 16 deletions(-) diff --git a/vector/app/main.py b/vector/app/main.py index 2a7910d..8f311db 100644 --- a/vector/app/main.py +++ b/vector/app/main.py @@ -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)}" ) diff --git a/vector/app/models/vector_models.py b/vector/app/models/vector_models.py index 6b33c94..b694c1b 100644 --- a/vector/app/models/vector_models.py +++ b/vector/app/models/vector_models.py @@ -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 상태 조회 응답""" diff --git a/vector/app/services/vector_service.py b/vector/app/services/vector_service.py index 510151a..c70ae9d 100644 --- a/vector/app/services/vector_service.py +++ b/vector/app/services/vector_service.py @@ -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 \ No newline at end of file + 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 [] \ No newline at end of file