6. 데이터 색인과 텍스트 분석
- 풀텍스트 검색을 위해서는 원본 데이터를 검색에 맞게 가공해야 한다.
- 엘라스틱서치는 데이터를 저장하면서 데이터를 가공한다.
6.1 역인덱스
- Full text 검색을 할 때는 역인덱스 구조가 유리하다.
- key는 term으로, value는 해당 term을 저장하고 있는 문서 번호를 저장한다.
- 역인덱스는 데이터가 저장될 때 만들어진다. 따라서 엘라스틱서치에서 데이터를 저장하는 과정을 인덱싱(색인)이라고 한다.
6.2 텍스트 분석
- 텍스트 분석: 원본 데이터로부터 검색어 토큰을 만들어서 저장하는 과정이다.
- 텍스트 분석 결과는 검색에만 사용되지, 원본 데이터는 변경되지 않는다.
- 애널라이저: 텍스트 분석을 담당하는 모듈이다.
- 캐릭터 필터: 전체 문장에서 특정 문자를 제거한다. 애널라이저는 0~3개의 캐릭터 필터로 이루어진다.
- 토크나이저: 문장에 속한 단어들을 텀 단위로 분리한다. 반드시 애널라이저 당 1개만 적용 가능하다.
- 토큰 필터: 분리된 텀들을 가공한다. 0~n개 지정할 수 있으며 순서가 의미 있다.(lowercase, stopword, snowball, synonym 등)
6.3 애널라이저
6.3.1 Analyze API
- GET _analyze API로 분석된 문장을 확인할 수 있다.
GET _analyze
{
"text": "The quick brown fox jumps over the lazy dog",
"tokenizer": "whitespace",
"filter": [
"lowercase",
"stop",
"snowball"
]
}
- 애널라이저는 필터와 토크나이저를 조합해서 만들 수도 있고, 기본 제공 애널라이저를 사용할 수도 있다.
- snowball 애널라이저: whitespace + lowercase, stop, snowball
- 애널라이저를 필드에 매핑하는 방법은 다음과 같다.
PUT my_index2
{
"mappings": {
"properties": {
"message": {
"type": "text",
"analyzer": "snowball"
}
}
}
}
- 토큰 필터는 순서가 중요하다.
- 검색 시에도 검색어도 analyzer를 거친다.
- 이 외 사용 가능한 애널라이저, 필터는 공식 도큐먼트를 확인하자.
6.3.2 Term 쿼리
- term 쿼리는 애널라이저 적용 없이 입력한 검색어 그대로 검색한다.
GET my_index2/_search
{
"query": {
"term": {
"message": "jump"
}
}
}
- 원본 데이터 jumps 는 jump로 저장되므로 term 쿼리 검색어로 jump를 사용해야한다.
6.3.3 사용자 정의 애널라이저
- 캐릭터 필터, 토크나이저, 토큰 필터를 조합해서 사용자 정의 애널라이저를 만들 수 있다.
- 인덱스의 setting-index-analysis-analyzer 안에 정의한다.
- 사용자 정의 토큰 필터
- settings-index-analysis-filter에서 지정한다.
PUT my_index3
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "whitespace",
"filter": [
"lowercase",
"my_stop_filter", ## 커스텀 필터
"snowball"
]
}
},
"filter": {
"my_stop_filter": { ## 커스텀 필터는 analysis-filter에 정의한다.
"type": "stop",
"stopwords": [
"brown"
]
}
}
}
}
}
}
- text 필드마다 애널라이저를 따로 지정할 수 있다.
PUT my_index3
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom", ## custom한 analyzer
"tokenizer": "whitespace",
"filter": [
"lowercase",
"my_stop_filter", ## 사용자 정의 필터를 지정한다.
"snowball"
]
}
},
"filter": {
"my_stop_filter": { ## 사용자 정의 필터
"type": "stop",
"stopwords": [
"brown"
]
}
}
}
}
},
"mappings": {
"properties": {
"message": { ## message라는 필드에
"type": "text",
"analyzer": "my_custom_analyzer" ## 어떤 analyzer를 사용할지.
}
}
}
}
6.3.4 텀 벡터
- 역인덱스 내용을 확일할 때는 _termbvectors API를 활용하면 된다.
GET <인덱스명>/_termvectors/<id>?fields=<필드명>,...
6.4 캐릭터 필터
- 토크나이징 되기 전 전체 문장에 대한 전처리 과정이다.
- 세 종류가 존재한다.
- HTML Strip: Html 문법 용어를 해석하고, 태그들을 제거한다.
- Mapping: 특수문자는 토크나이저나 토큰 필터에 의해 제거되므로 다른 문자로 치환한다.
-
PUT coding { "settings": { "analysis": { "analyzer": { "coding_analyzer": { "char_filter": [ "cpp_char_filter" ## cpp_char_filter라는 커스텀 캐릭터 필터를 적용한다. ], "tokenizer": "whitespace", "filter": [ "lowercase", "stop", "snowball" ] ## snowball 애널라이저 설정 } }, "char_filter": { # custom char_filter를 적용한다. "cpp_char_filter": { "type": "mapping", # type은 매핑 "mappings": [ "+ => _plus_", "- => _minus_" ] # 매핑정보 } } } }, "mappings": { "properties": { "language": { "type": "text", "analyzer": "coding_analyzer" ## language 필드에 커스텀 애널라이저를 적용한다. } } } }
- Pattern Replace: 정규식 패턴을 이용해서 치환한다.
-
PUT camel { "settings": { "analysis": { "analyzer": { "camel_analyzer": { "char_filter": [ "camel_filter" ], "tokenizer": "standard", "filter": [ "lowercase" ] } }, "char_filter": { "camel_filter": { "type": "pattern_replace", ## pattern_replace 타입 "pattern": "(?<=\\p{Lower})(?=\\p{Upper})", "replacement": " " } } } } }
6.5 토크나이저
- 애널라이저는 반드시 한개만 사용하며, tokenizer 항목에 단일값으로 설정한다.
- 여러 종류가 있으며 공식 도큐먼트를 참조하자.
- standard: 공백으로 텀을 구분하면서 따로 떨어져 있거나 끝에 있는 특수문자를 제거한다.
- letter: 알파벳을 제외한 모든 공백, 숫자, 기호들을 기준으로 텀을 분리한다.
- whitespace: 스페이스, 탭, 줄바꿈 같은 공백만을 기준으로 텀을 분리한다.
- 보통 standard를 많이 쓴다.
- uax_url_email: 이메일 주소, 웹 url 경로는 분리하지 않는다.
- pattern: IoT, 머신 데이터인 경우 다른 구분자를 쓰므로 pattern으로 구분한다. 특정 문자나 정규식을 사용할 수 있다.
-
PUT pat_tokenizer { "settings": { "analysis": { "tokenizer": { "my_pat_tokenizer": { "type": "pattern", "pattern": "/" ## "pattern": "(?<=\\p{Lower})(?=\\p{Upper})" } } } } }
- path_hierarchy: 경로를 단계별로 쪼갠다.
- /A/B/C -> /A, /A/B,/A/B/C
- delimiter와 replacement를 지정할 수 있다.
6.6 토큰 필터
- analysis 밑의 filter 항목에 배열로 나열해서 정한다.
- 필터를 설정하는 순서에 유의하자.
- lowercase, uppercase: 거의 모든 곳에서 사용된다.
- stopword
- 불용어를 배열 형태로 지정하거나 _english_와 같이 언어팩을 사용할 수 있다.
- 불용어를 사용하기 위해선 사전에 lowercase 필터가 필요하다.
- stopwords_path로 텍스트 파일을 지정해줄 수 있다.
-
PUT my_stop { "settings": { "analysis": { "filter": { "my_stop_filter": { ## 필터 정의 부분 "type": "stop", "stopwords_path": "user_dic/my_stop_dic.txt" } } } } }
- synonym
- 동의어 필터이다.
- "A,B => C" : A,B 대신 C를 저장한다. A,B로 C를 검색 가능하나 C로 A,B를 검색할 수는 없다.
- "A, B" => A와 B 각 텀이 A, B 두 개의 텀을 저장한다.
- 마찬가지로 "synonyms_path"로 파일을 지정할 수 있다.
-
PUT my_synonym { "settings": { "analysis": { "analyzer": { "my_syn": { "tokenizer": "whitespace", "filter": [ ## 토큰 필터를 배열로 지정 "lowercase", "syn_aws" ] } }, "filter": { "syn_aws": { ## 필터 정의 부분 "type": "synonym", "synonyms_path": "user_dic/my_syn_dic.txt" } } } }, "mappings": { "properties": { "message": { "type": "text", "analyzer": "my_syn" } } } }
- expand 옵션: default는 true, false 시 동의어를 둘다 저장하지 않고 앞의 하나만 저장한다.
- lenient 옵션: default는 false, true 시 synonym의 오류를 무시한다.
- Ngram
- 부분 문자열을 저장한다.
- ex) bigram : house: ho,ou,us,se
- 전체 개수가 많지 않은 데이터 집단에 자동 완성으로 쓴다.
- min_gram, max_gram을 지정할 수 있다.
- Edge NGram: 맨 앞부터 쌓아가며 부분 문자열을 만든다.
- Shingle: 단어 단위로 묶는다.
- Ngram, Shingle은 일반적으로 사용되지 않으나 자동완성, 문법 검색 등 특수한 환경에서 사용된다.
- 부분 문자열을 저장한다.
- unique: 중복되는 term을 하나만 저장한다. 스코어에 영향을 주므로 match를 쓸 때는 쓰지 말자.
6.7 형태소 분석
- 형태소 분석: 어간을 추출하는 과정
- snowball: ~ing, ~s 등을 제거한다. 애널라이저, 토크나이저, 토큰필터 모두 정의되어 있다.
- nori: 한글 형태소 분석기
- nori 플러그인 설치가 필요하다.
- nori_tokenizer : 토크나이저
- user_dictionary, user_dictionary_rules: 사용자 정의 사전을 입력한다.
- decompound_mode: 합성어의 저장 방식을 지정한다.
- none: 완성된 합성어만 저장한다.
- discard(default): 어근만 저장한다.
- mixed: 어근과 합성어 모두 저장한다.
- nori_part_of_speech : 토큰 필터
- 제거할 품사를 지정한다.
- stoptags 값에 배열로 저장한다.
- 보통 명사, 동명사 정도만 검색한다.
- nori_reading_from: 토큰 필터
- 한자를 한글로 바꾼다.
- _analyze API 에서 "explain": true로 형태소의 동사 정보를 볼 수 있다.
'엘라스틱서치' 카테고리의 다른 글
레퍼런스] 엘라스틱서치란 무엇인가? (0) | 2021.09.15 |
---|---|
7. 인덱스 설정과 매핑 (0) | 2021.09.06 |
5. 검색과 쿼리 (0) | 2021.09.05 |
4. 데이터 처리 (0) | 2021.08.31 |
3. 시스템 구조 (0) | 2021.08.31 |