검색어 자동완성 그리고 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을 통해 요청 전송
검색어 자동완성 그리고 한글의 자음모음
'a' in 'abcd' = True
'구' in '구공탄 곱창' = True
'ㄱ' in '구공탄 곱창' = 몰?루
'ㄱ' in ['ㄱ', 'ㅜ', 'ㄱ', 'ㅗ', 'ㅇ', 'ㅌ', 'ㅏ', 'ㄴ', ...] = True
• 한글 코드는 한 글자가 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 해주기만 하면 된다.
그래서 이걸 다 구현해야 하나요?
• FE 라이브러리 jQuery의 AutoComplete를 활용하면 조금 더 쉽게 구현할 수 있다.
• 스프링을 이용하여 직접 구현할수도 있지만, 이 경우 DB 설계가 중요하다.
- 이 때 Redis(인메모리 기반의 DB)가 주로 사용된다.
- Redis는 인메모리를 사용하기 때문에 디스크 혹은 클라우드 메모리를 사용할때보다 메모리 Read/Write 속도가 훨씬 빠르므로