refactor(backend): 21단계 검색 페이징 최적화 - 중복 slice 제거

- services/meilisearch: 내부 SEARCH_LIMIT(1000)과 페이징 파라미터 분리
- services/meilisearch: 기본 limit을 100으로 변경
- routes/schedules: handleSearch에서 중복 slice 제거, 직접 offset/limit 전달

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
caadiq 2026-01-21 16:04:07 +09:00
parent bfdbc08405
commit a62cf7142b
3 changed files with 20 additions and 19 deletions

View file

@ -212,7 +212,7 @@ export default async function schedulesRoutes(fastify) {
* 검색 처리 * 검색 처리
*/ */
async function handleSearch(fastify, query, offset, limit) { async function handleSearch(fastify, query, offset, limit) {
const { db, meilisearch, redis } = fastify; const { db, meilisearch } = fastify;
// 첫 페이지 검색 시에만 검색어 저장 (bi-gram 학습) // 첫 페이지 검색 시에만 검색어 저장 (bi-gram 학습)
if (offset === 0) { if (offset === 0) {
@ -220,18 +220,15 @@ async function handleSearch(fastify, query, offset, limit) {
saveSearchQueryAsync(fastify, query); saveSearchQueryAsync(fastify, query);
} }
// Meilisearch 검색 // Meilisearch 검색 (페이징 포함)
const results = await searchSchedules(meilisearch, db, query, { limit: 1000 }); const results = await searchSchedules(meilisearch, db, query, { offset, limit });
// 페이징 적용
const paginatedHits = results.hits.slice(offset, offset + limit);
return { return {
schedules: paginatedHits, schedules: results.hits,
total: results.total, total: results.total,
offset, offset: results.offset,
limit, limit: results.limit,
hasMore: offset + paginatedHits.length < results.total, hasMore: results.hasMore,
}; };
} }

View file

@ -43,16 +43,18 @@ export async function resolveMemberNames(db, query) {
* @param {object} meilisearch - Meilisearch 클라이언트 * @param {object} meilisearch - Meilisearch 클라이언트
* @param {object} db - DB 연결 * @param {object} db - DB 연결
* @param {string} query - 검색어 * @param {string} query - 검색어
* @param {object} options - 검색 옵션 * @param {object} options - 검색 옵션 (offset, limit for pagination)
*/ */
export async function searchSchedules(meilisearch, db, query, options = {}) { export async function searchSchedules(meilisearch, db, query, options = {}) {
const { limit = 1000, offset = 0 } = options; const { limit = 100, offset = 0 } = options;
// 내부 검색 한도 (여러 검색어 병합 및 유사도 필터링 전 충분한 결과 확보)
const SEARCH_LIMIT = 1000;
try { try {
const index = meilisearch.index(INDEX_NAME); const index = meilisearch.index(INDEX_NAME);
const searchOptions = { const searchOptions = {
limit, limit: SEARCH_LIMIT,
offset: 0, // 내부적으로 전체 검색 후 필터링 offset: 0, // 내부적으로 전체 검색 후 필터링
attributesToRetrieve: ['*'], attributesToRetrieve: ['*'],
showRankingScore: true, showRankingScore: true,

View file

@ -221,12 +221,14 @@
--- ---
### 21단계: 검색 페이징 최적화 🔄 진행 예정 ### 21단계: 검색 페이징 최적화 ✅ 완료
- [ ] Meilisearch 네이티브 페이징 사용 - [x] 라우트에서 중복 slice 제거
- [ ] 클라이언트 slice 제거 - [x] 내부 검색 한도와 페이징 파라미터 분리
- [x] searchSchedules에 offset/limit 직접 전달
**대상 파일:** **수정된 파일:**
- `src/services/meilisearch/index.js` - offset/limit 파라미터 전달 - `src/services/meilisearch/index.js` - SEARCH_LIMIT 분리, 기본 limit 100으로 변경
- `src/routes/schedules/index.js` - handleSearch에서 중복 slice 제거
--- ---
@ -254,7 +256,7 @@
| 18단계 | 이미지 처리 최적화 | ✅ 완료 | | 18단계 | 이미지 처리 최적화 | ✅ 완료 |
| 19단계 | Redis 캐시 확대 | ✅ 완료 | | 19단계 | Redis 캐시 확대 | ✅ 완료 |
| 20단계 | 서비스 레이어 확대 | ✅ 완료 | | 20단계 | 서비스 레이어 확대 | ✅ 완료 |
| 21단계 | 검색 페이징 최적화 | 🔄 진행 예정 | | 21단계 | 검색 페이징 최적화 | ✅ 완료 |
--- ---