InvertedIndex(역색인)로 저장을 해두는 ElasticSearch는 전문검색(Full-Text)에서 속도가 하나씩 모두 찾는 SQL의 LIKE 검색보다 월등하게 빠릅니다.
Elasticsearch는 검색어 Term을 저장하기 위해 Text Analysis라는 과정을 거치고, 이러한 과정을 처리하는 기능을 Analyzer라고 합니다. Analyzer는 0~3개의 Character Filter, 1개의 Tokenizer, 그리고 0~n개의 Token Filter로 이루어집니다.
캐릭터 필터는 텍스트 분석 중 가장 먼저 처리되는 과정으로, Tokenizer에 의해 색인된 Text가 Term으로 분리되기 전에 전체 Text에 대해 적용되는 전처리 도구입니다.
Elasticsearch 7.0 기준으로 HTML_Strip, Mapping, Pattern Replace 총 3개가 존재합니다.
- HTML Strip
입력된 텍스트가 HTML 인 경우 HTML 태그들을 제거하여 일반 텍스트로 만듭니다. <>로 된 태그를 제거할 뿐 아니라 같은 HTML 문법 용어들도 해석합니다- Mapping
Mapping 캐릭터 필터를 이용하면 지정한 단어를 다른 단어로 치환이 가능합니다. 특수문자 등을 포함하는 검색 기능을 구현하려는 경우 반드시 적용해야 해서 실제로 캐릭터 필터 중에는 가장 많이 쓰입니다.- Pattern Replace
Pattern Replace 캐릭터 필터는 정규식(Regular Expression)을 이용해서 좀더 복잡한 패턴들을 치환할 수 있는 캐릭터 필터입니다.
Tokenizer는 Character Filter로 전처리된 Text에 속한 단어를 Term 단위로 하나씩 분리해 처리하는 과정을 담당합니다. 데이터 분석 과정에서 Tokenizer는 반드시 한 개만 사용이 가능합니다.
- Standard Tokenizer
Standard Tokenizer는 공백으로 Term을 구분하면서 "@"과 같은 일부 특수문자를 제거합니다. "jumped!"의 느낌표, "meters."의 마침표 처럼 단어 끝에 있는 특수문자는 제거되지만 "quick.brown_FOx" 또는 "3.5" 처럼 중간에 있는 마침표나 밑줄 등은 제거되거나 분리되지 않습니다.- Letter Tokenizer
Letter Tokenizer는 알파벳을 제외한 모든 공백, 숫자, 기호들을 기준으로 Term을 분리합니다. "quick.brown_FOx" 같은 단어도 "quick", "brown", "FOx" 처럼 모두 분리됩니다.- White Tokenizer
Whitespace Tokenizer는 스페이스, 탭, 그리고 줄바꿈 같은 공백만을 기준으로 텀을 분리합니다. 특수문자 "@" 그리고 "meters." 의 마지막에 있는 마침표도 사라지지 않고 그대로 남아있습니다.
Tokenizer로 Term을 분리해준 이후, 분리된 각각의 Term을 지정한 규칙에 따라 처리해줍니다. filter 항목에 배열 형태로 나열해서 지정해야 하며, 나열한 순서대로 적용되기 때문에 순서를 잘 고려해야합니다.
- Lowercase, Uppercase
영어같은 경우 검색을 할때 대소문자를 구분하지 않고 검색할 수 있도록 처리해주어야 합니다. 보통은 Term을 모두 소문자로 변경하여 저장하는데, 이를 처리하는 Token Filter가 Lowercase 입니다.- Stop
블로그나 뉴스 같은 글은 검색에서 큰 의미가 없는 조사나 전치사를 많이 포함하고 있습니다. 이렇게 검색할 때 쓰이지 않는 단어를 불용어(stopword)라 하여 Stop Token Filter를 적용해 불용어에 해당되는 Term을 제거할 수 있습니다.
Elasticsearch Index의 Settings는 쉽게 말해 Index 정보 설정을 확인할 수 있는 단위입니다. 처음 인덱스를 정의하면 Shard, Replica(복제본)의 수 같은 정보가 자동으로 생성됩니다. 어떤 설정은 운영 도중에도 변경할 수 있지만 대부분의 설정들은 생성시 한번 지정되면 변경되지 않습니다.
Full-Text Search를 하기 위하여 Analyzer를 사용해 데이터를 역색인합니다. 상단에서 살펴본 Analyzer, Tokenizer, Filter 역시 Index의 Settings에서 정의해줍니다!
"analysis"
내부에서analyzer
,char_filter
,tokenizer
,token_filter
를 생성하고 정의하여 사용합니다.
처음 볼 때는 복잡해 보이지만1.char_filter
,tokenizer
,filter
내부에 사용자가 정의한 기능들을 작성하고2. 작성한 사용자 정의 기능을analyzer
에서 적용하여 사용하는 구조 입니다.
한 번 적용된analysis
내용은 변경이 불가능하고, 이미 만들어진 Index에 Analyzer를 변경하거나 추가하기 위해서 Index를_close
한 후에 변경하고 다시_open
해주어야 합니다.
Settings에서 Index가 사용할 수 있는 analyzer를 정의해주었을 뿐, 아직 Data 역색인 과정에서 적용하지는 않았습니다. 사용할 수 있는 도구를 등록했으니, Mappings에서 사용해보도록 하겠습니다.
Elasticsearch는 Dynamic Mapping을 지원하기 때문에, 미리 정의하지 않아도 Index를 추가하면 자동으로 Mapping이 정의됩니다.
Index Mapping의 Field는 Property 항목 아래 지정됩니다.
이미 만들어진 mapping에 필드를 추가하는 것은 가능하지만, 필드를 삭제하거나 변경하는 것은 불가능합니다. 따라서 필드 변경이 필요한 경우 인덱스를 새로 정의하고 재색인해주어야 합니다.