-
Notifications
You must be signed in to change notification settings - Fork 1
한글 입력 방식의 유연성을 높인 검색 시스템 구현하기
dannysir edited this page Dec 5, 2024
·
1 revision
검색 시스템을 개발할 때 가장 중요한 것 중 하나는 사용자의 다양한 입력 방식을 얼마나 잘 커버할 수 있느냐입니다. 특히 한글의 경우, 두 가지 주요 입력 방식(한글/영문)이 존재하기 때문에 이를 적절히 처리하는 것이 중요합니다. 이번 글에서는 hangul-js를 활용하여 검색 시스템의 유연성을 높인 구현 방법을 소개하고자 합니다.
사용자들은 한글을 입력할 때 다음과 같은 두 가지 방식을 사용할 수 있습니다
- 한글 모드로 직접 입력: "안녕하세요"
- 영문 모드로 입력: "dkssudgktpdy"
대부분의 검색 시스템은 이 중 한 가지 방식만을 지원하거나, 두 가지를 별도로 처리해야 했습니다. 이는 사용자 경험을 저하시키는 요인이 되었죠.
우리는 이 문제를 다음과 같은 방식으로 해결했습니다
먼저, 영문자를 한글 자모음으로 변환하는 매핑 시스템을 구현했습니다
class SimpleKoreanConverter {
private charMap: CharacterMap;
constructor() {
this.charMap = {
r: 'ㄱ',
R: 'ㄲ',
s: 'ㄴ',
// ... 기타 매핑
};
}
public convert(input: string): string[] {
return Array.from(input).map((char) => this.charMap[char] || char);
}
}사용자가 입력한 검색어에 대해 두 가지 방식으로 검색을 시도합니다:
- 원본 검색어로 먼저 검색
- 결과가 없는 경우, 변환된 검색어로 재검색
const {
data: originalData,
isLoading: isOriginalLoading,
} = useQuery({
queryKey: ['search', debounceValue],
queryFn: () => getSearchResults(formatNoSpecialChar(debounceValue)),
enabled: !!debounceValue && !isDebouncing,
});
const convertedSearch = debounceValue
? Hangul.assemble(converter.convert(debounceValue))
: '';
const {
data: convertedData,
isLoading: isConvertedLoading,
} = useQuery({
queryKey: ['search', convertedSearch],
queryFn: () => getSearchResults(formatNoSpecialChar(convertedSearch)),
enabled: !isOriginalLoading && !!convertedSearch && originalData?.length === 0,
});검색 성능 향상을 위해 다음과 같은 최적화를 적용했습니다:
- debounce를 통한 API 호출 최적화
- 캐싱 전략 적용 (staleTime: 10000, cacheTime: 1000 * 60)
- 불필요한 API 호출 방지 (2글자 미만 검색어 제외)
-
향상된 사용자 경험
- 사용자가 어떤 입력 모드로 검색하든 원하는 결과를 얻을 수 있습니다
- 입력 모드 전환 없이도 검색이 가능합니다
-
효율적인 리소스 사용
- 첫 번째 검색에서 결과가 있으면 추가 검색을 하지 않습니다
- 캐싱을 통해 서버 부하를 줄입니다
-
유지보수 용이성
- 명확한 코드 구조로 추후 수정이 용이합니다
- 타입스크립트를 활용한 타입 안정성 확보
-
더 많은 입력 패턴 지원
- 자음만 입력한 경우의 처리
- 오타 교정 기능 추가
-
성능 최적화
- 서버 사이드 검색 로직 개선
- 클라이언트 캐싱 전략 세분화
hangul-js를 활용한 유연한 검색 시스템 구현을 통해, 우리는 사용자 경험을 크게 개선할 수 있었습니다. 특히 한글의 특성을 고려한 이중 검색 전략은 검색의 정확도와 편의성을 모두 향상시켰습니다. 앞으로도 지속적인 개선을 통해 더 나은 검색 경험을 제공할 수 있도록 노력하겠습니다.
- [FE] 프론트엔드 기술스택
- [FE] 라이브러리 없이 차트 구현 이유
- [FE] Canvas API 사용방법
- [FE] 네비게이션 바 애니메이션 구현
- [FE] Socket.io 사용방법
- [FE] Tanstack Router에 대하여...
- [FE] Intl(Internationalization) API
- [FE] React Suspense 적용
- [FE] 한글 입력 방식의 유연성을 높인 검색 시스템 구현하기
- [BE] 백엔드 기술 스택
- [BE] SSE vs Socket.io
- [BE] Redis를 도입하게 된 계기
- [BE] ACG Rule을 활용한 Secure CI CD 파이프라인 구현
- [BE] Nginx 로드밸런싱을 통해 한국 투자 API 소켓 제한 극복
- [BE] 주가 지수 기능 개발 과정
- [BE] 매수 및 매도 기능 개발 과정
- [BE] 실시간 자산 조회 기능 개발 과정
- [BE] 단위 테스트
- [BE] redis를 이용한 한국투자 Open API 세션 관리
- [BE] 데이터베이스 인덱싱
- [FE] React에서의 DOM 요소 접근 (useRef vs getElementById)
- [FE] Outlet을 활용한 공통 레이아웃 관리
- [FE] react hooks가 특정 조건에서 실행되면 안되는 이유 & useQuery에 query function 매개변수가 undefined일 수도 있을 때 어떻게 해결할까
- [FE] cross‐domain 로컬 환경에서 cookie로 인증 처리하기 with vite proxy
- [FE] 크롬&사파리 Composition 차이
- [FE] useEffect 의존성 배열
- [BE] Naver Cloud Platform HTTPS 무응답 현상
- [BE] 한국투자 Open API에서 access token을 발급받지 못하는 문제
- [BE] 한국투자 Open API와 웹소켓 연결이 되지 않던 문제
- [BE] 한국투자 Open API 웹소켓 연결이 중단되는 문제
- [BE] 같은 주식 주문이 동시에 여러 번 체결되는 문제
- [BE] 한국투자 Open API Websocket 세션을 두 개에서 한 개로 변경하기
- [BE] Nginx 로드 밸런싱 중 Socket bad Request 발생하는 현상
- [BE] 매수/매도 체결 로직에 의해 redis pub/sub이 정상적으로 동작하지 않는 문제