검색어 자동완성 그리고 AJAX

- 어떻게 엔터를 쳐서 Request를 날리지 않았는데도 연관된 검색어가 뜨는 것일까?
- 사용자가
ㄱ
을 입력하는 순간, 웹브라우저는 자동으로 사용자가 입력한 값ㄱ
을 서버로 전송한다. - 서버에서는
ㄱ
을 받아서ㄱ
으로 시작하는 추천 검색어를 검색해 웹브라우저로 보내주고, 이를 브라우저에서 출력하는 것
- 그러나 매번 페이지 새로고침/리로드가 실행되지는 않는다 :
AJAX
AJAX(Asynchronous JavaScript and XML)(비동기식 자바스크립트와 XML)
- 자바스크립트를 이용해 서버와 브라우저가 비동기 방식으로 데이터를 교환할 수 있는 통신 기능
- 웹페이지를 리로드하지 않고 데이터를 불러오는 방식 =
비동기 방식
- Ajax를 통해 서버에 요청을 한 후 서버가 멈추어 있는 것이 아니라, 서버 프로그램은 계속 돌아간다
- 브라우저가 가지고있는
XMLHttpRequest
객체를 이용해 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드할 수 있다. - 페이지 리로드 하는 경우 전체 리소스를 다시 불러와야 해서 불필요한 리소스 낭비가 생길 수 있지만 비동기식 방식을 사용하면 필요한 부분만 불러와 사용하기 때문에 효율적이다.
AJAX 동작 원리
기본적으로 HTTP 프로토콜은 클라이언트쪽에서 Request
를 보내고 서버쪽에서 Response
를
받으면 이어졌던 연결이 끊어지게 된다. 즉, 화면의 일부 내용만 갱신하고 싶더라도 전체 페이지에 대한 Request
Response
를 보내서 페이지 전체를 갱신해야 함
- AJAX는 페이지의 일부분만 갱신할 수 있도록
HTML 페이지
객체가 아닌,XMLHttpRequest
객체를 통해 서버에Request
를 보낸다.
- 이 경우,
JSON
이나XML
형태로 필요한 데이터만 받아 페이지를 갱신하기 때문에 전체 페이지를 리로드 하지 않고도 페이지 일부분의 업데이트가 가능하다.
AJAX 동작 과정
XMLHttpRequest
Object를 만든다.Request
를 보낼 준비를 브라우저에게 시키는 과정- 이것을 위해서 필요한 메서드를 갖춘
Object
가 필요하다.
- callback 함수를 만든다.
- 서버에서
Response
가 왔을 때 실행되는 함수 : HTML 페이지를 업데이트 한다.
- Open a
Request
- Send the
Request
→ XMLHttpRequest 객체를 생성한 다음 URL을 통해 요청 전송
→ 응답을 받으면 응답 결과에 맞는 함수가 실행되는 구조로 동작한다.
검색어 자동완성 그리고 한글의 자음모음
- 한글 코드는 한 글자가 2바이트이며, 보통
완성형 코드
와조합형 코드
로 나뉜다.
완성형 코드
- 자주 쓰이는 한글 2350자를 골라 가나다 순으로 배치하여 차례대로 코드를 부여한 것
→ 코드 :
0xB0A1
~0xC8FE
(상위 8비트 : 0xB0 ~ 0xC8 / 하위 8비트 : 0xA1~ 0xFE)
- 자음/모음의 구성요소로 분리가 불가능하다.
조합형 코드
사용하는 2바이트(16비트) 중에서 상위 1비트는 아스키 코드와 구분하기 위해 사용하고 다음 5비트/5비트/5비트는 각각 초성/중성/종성에 대한 정보를 저장한다.

- 자음/모음의 구성요소로 분리가 가능하다.
자음과 모음의 분리
- 한글이 조합형 코드로 표현되어 있다면 쉽지만 완성형 코드로 표현되어 있다면 조합형으로 변환이 필요하다.
- OS/라이브러리 등에서 제공하는 인코딩 기술을 사용할 수 있다!
검색어 자동완성 그리고 한글의 복잡성
첫번째 문제 : 복자음, 복모음 문제
- 네이버의 검색창에
오
를 쳐보면 자동완성 리스트에오
로 시작되는 단어도 나오지만,와
로 시작되는와우
같은 단어들도 나오는 것을 확인할 수 있다.
- 하지만 조합형 코드에서
ㅗ
는 13,ㅘ
는 14의 서로 다른 코드 값을 갖는다.
와
= ㅇ + ㅘ (O) / ㅇ + ㅗ + ㅏ (X)
- 이대로라면
오
를 쳤을때와우
는 자동완성 리스트에 등장할 수 없다!
ㅘ
를ㅗ
+ㅏ
로 분리해야 한다.
두번째 문제 : 받침에 오는 자음, 뒤로 갈수도 있어
갑
을 입력했을 때 추천 검색어에는갑상선
이라는 단어도 나오지만,가방
이라는 단어가 나오기도 한다.
갑
을 입력한 후ㅏ
를 입력하면 갑의ㅂ
받침이 다음 음절의 초성으로 넘어갈 수 있기 때문
- 그러나 초성에서의
ㅂ
코드값은 9 이고 종성에서의ㅂ
코드값은 19로, 같은 ㅂ이라도 초성이냐 종성이냐에 따라 그 값이 달라진다.
- 종성에서 나타나는 자음의 코드값을 초성에서 나타나는 자음의 코드값과 같은 값으로 변환해주어야 한다!
- 복자음은 항상 종성에서만 나타나는데 이를 2개의 자음으로 분리한 후 초성의 코드 값으로 변환해야 한다!
- 예) 돓 → 돌하르방
어떻게 저장하고 탐색할 것인가
데이터 구축 방식
- 자동완성 검색어 리스트를 보여줄 때 어떤 순서로 보여줄 것인가?
- 사용자가 입력한 검색어(검색 버튼을 클릭해 검색을 한)
빈도수
필드
- 빈도수가 높은 순서대로 추천 검색어로 출력이 되도록 하는 방법이 대표적
- 최근 일주일 / 최근 한달 등으로 기간을 정하는 방법도 있을 것이다.
B-Tree 알고리즘

- Trie / 캐싱등의 활용
- 여기까지 구현이 완료된 후에는 이제 AJAX를 이용해 웹브라우저로 SHOW 해주기만 하면 된다.
그래서 이걸 다 구현해야 하나요?
- jQuery AutoComplete를 활용하는 방법 (FE)
- 스프링 : 직접 구현, 단 DB 설계가 중요
- Redis : 인메모리 기반의 DB
- 인메모리를 사용하기 때문에 디스크 혹은 클라우드 메모리를 사용할때보다 메모리를 Read/Write 속도가 훨씬 빠르다. 그래서 자주 사용되는 것!
나눈 이야기
- 웹서버 위에서?
- 파일에 csv 형태로 저장 (형태소 분석)
- apache 모듈이 찾아주는 방식
- WAS 까지 안가도 된다.
- 스프링에 국한되어 생각하지 말기!
- 서버도 생각하기
- WAS만 보지 말고 WEB Server의 용도도 잘 생각하는것이 좋다.
- Apache Lucene / ElasticSearch 의 도입도 가능하다.
- 정리 : 여러가지 방식으로 생각해보자!