diff --git a/backend/src/services/meilisearch/index.js b/backend/src/services/meilisearch/index.js index f75fd6e..655e210 100644 --- a/backend/src/services/meilisearch/index.js +++ b/backend/src/services/meilisearch/index.js @@ -15,6 +15,9 @@ const logger = createLogger('Meilisearch'); const INDEX_NAME = 'schedules'; const MIN_SCORE = config.meilisearch.minScore; +// 캐시된 현재 활동 멤버 수 (동기화 시 갱신) +let cachedActiveMemberCount = null; + /** * 영문 자판으로 입력된 검색어인지 확인 */ @@ -39,6 +42,19 @@ export async function resolveMemberNames(db, query) { return members.map(m => m.name); } +/** + * 현재 활동 멤버 수 조회 및 캐시 + */ +async function getActiveMemberCount(db) { + if (cachedActiveMemberCount === null) { + const [[{ count }]] = await db.query( + 'SELECT COUNT(*) as count FROM members WHERE is_former = 0' + ); + cachedActiveMemberCount = count; + } + return cachedActiveMemberCount; +} + /** * 일정 검색 * @param {object} meilisearch - Meilisearch 클라이언트 @@ -52,6 +68,8 @@ export async function searchSchedules(meilisearch, db, query, options = {}) { const SEARCH_LIMIT = 1000; try { + // 현재 활동 멤버 수 캐시 (formatScheduleResponse에서 사용) + await getActiveMemberCount(db); const index = meilisearch.index(INDEX_NAME); const searchOptions = { @@ -128,10 +146,15 @@ export async function searchSchedules(meilisearch, db, query, options = {}) { */ function formatScheduleResponse(hit) { // member_names를 배열로 변환 - const members = hit.member_names + let members = hit.member_names ? hit.member_names.split(',').map(name => name.trim()).filter(Boolean) : []; + // 전체 멤버인 경우 "프로미스나인"으로 대체 + if (cachedActiveMemberCount && members.length === cachedActiveMemberCount) { + members = ['프로미스나인']; + } + // source 객체 구성 (Meilisearch에는 URL 없음) let source = null; if (hit.category_id === CATEGORY_IDS.YOUTUBE && hit.source_name) { @@ -199,7 +222,13 @@ export async function deleteSchedule(meilisearch, scheduleId) { */ export async function syncAllSchedules(meilisearch, db) { try { - // DB에서 모든 일정 조회 + // 현재 활동 멤버 수 캐시 갱신 + const [[{ count }]] = await db.query( + 'SELECT COUNT(*) as count FROM members WHERE is_former = 0' + ); + cachedActiveMemberCount = count; + + // DB에서 모든 일정 조회 (탈퇴 멤버 제외) const [schedules] = await db.query(` SELECT s.id, @@ -216,7 +245,7 @@ export async function syncAllSchedules(meilisearch, db) { LEFT JOIN schedule_categories c ON s.category_id = c.id LEFT JOIN schedule_youtube sy ON s.id = sy.schedule_id LEFT JOIN schedule_members sm ON s.id = sm.schedule_id - LEFT JOIN members m ON sm.member_id = m.id + LEFT JOIN members m ON sm.member_id = m.id AND m.is_former = 0 GROUP BY s.id `);