728x90
ElasticSearch 와 AWS OpenSearch 의 settings, mappings 작성 방법은 크게 다르지 않지만,
- ElasticSearch Settings, Mapping 설정: https://yonikim.tistory.com/26
OpenSearch 의 경우 플러그인 커스텀이 안되기 때문에 nori 가 지원되지 않는다.
- AWS OpenSearch 에서 사용 가능한 플러그인: https://docs.aws.amazon.com/ko_kr/opensearch-service/latest/developerguide/supported-plugins.html
nori 의 조상님인 은전한닢 을 사용하여 만든 settings 는 아래와 같다.
▷ Settings
`index.mapping.ignore_malformed: true` 를 설정해준 까닭은 Mappings 에서 설정해준 해당 필드의 DataType 과 실제로 Insert 한 데이터의 DataType 이 같지 않은 경우, 해당 Document 는 에러를 내뱉으며 Insert 하지 않는다. 즉, 데이터의 누락이 발생한다.
물론 필드들의 DataType 을 설정해주고 그에 맞춰 넣을 수 있다면 더할나위 없이 좋겠지만, 그렇지 못할 가능성이 크기 때문에 데이터의 누락을 방지하기 위해 설정해주는 것이 좋다.
(나의 예시로, updatedDate 의 DataType 을 date 를 설정해줬지만 신규 생한 데이터의 경우 null 이기 때문에 DataType 이 매칭되지 않아서 오류가 나며 해당 데이터가 Insert 되지 못했다)
{
"settings": {
"index.mapping.ignore_malformed": true,
"index.search.slowlog.threshold.query.warn": "10s",
"index": {
"analysis": {
"analyzer": {
"standard": {
"type": "custom",
"tokenizer": "standard",
"char_filter": ["remove_special_char", "remove_number"],
"filter": ["lowercase", "trim", "synonyms", "stopwords"]
},
"seunjeon": {
"type": "custom",
"tokenizer": "seunjeon_tokenizer",
"filter": ["lowercase", "trim", "synonyms", "stopwords"]
},
"ngram": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"filter": ["lowercase", "trim"]
},
"ngram_all": {
"type": "custom",
"tokenizer": "ngram_all_tokenizer",
"filter": ["lowercase", "trim"]
},
"autocomplete_analyzer": {
"tokenizer": "standard",
"filter": ["lowercase", "trim", "autocomplete"]
},
"remove_html": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"char_filter": ["html_strip"],
"dictionary_filter": ["stopwords"],
"filter": ["lowercase", "trim"]
},
"remove_special_char": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"char_filter": ["remove_whitespace", "remove_special_char"],
"dictionary_filter": ["stopwords"],
"filter": ["lowercase", "trim"]
}
},
"tokenizer": {
"seunjeon_tokenizer": {
"type": "seunjeon_tokenizer",
"user_dict_path": "${사용자사전 패키지 ID}",
"index_poses": [
"UNK",
"I",
"M",
"N",
"S",
"SL",
"SH",
"SN",
"V",
"VCP",
"XP",
"XS",
"XR"
],
"index_eojeol": false,
"decompound": true,
"pos_tagging": false
},
"ngram_tokenizer": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10,
"token_chars": ["letter", "digit"]
},
"ngram_all_tokenizer": {
"type": "ngram",
"token_chars": ["letter", "digit"]
}
},
"filter": {
"autocomplete": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20,
"token_chars": ["letter", "digit", "whitespace"]
},
"synonyms": {
"type": "synonym",
"synonyms_path": "${동의어 패키지 ID}",
"lenient": true
},
"stopwords": {
"type": "stop",
"synonyms_path": "${금칙어 패키지 ID}",
"updateable": true
}
},
"dictionary_filter": {
"synonyms": {
"type": "synonym",
"synonyms_path": "${동의어 패키지 ID}",
"lenient": true
},
"stopwords": {
"type": "stop",
"synonyms_path": "${금칙어 패키지 ID}",
"updateable": true
}
},
"char_filter": {
"remove_special_char": {
"pattern": "[^ㄱ-ㅎ|가-힣|A-Z|a-z|0-9]",
"type": "pattern_replace",
"replacement": " "
},
"remove_number": {
"pattern": "(?<=[가-힣|ㄱ-ㅎ])(?:[0-9]+)",
"type": "pattern_replace",
"replacement": ""
},
"remove_whitespace": {
"type": "pattern_replace",
"pattern": " ",
"replacement": ""
}
}
}
}
}
}
▷ Mappings
{
"mappings": {
"properties": {
"ranking": {
"type": "nested"
},
"name": {
"type": "keyword",
"fields": {
"raw": {
"type": "text",
"analyzer": "standard"
},
"seunjeon": {
"type": "text",
"analyzer": "seunjeon"
},
"ngram": {
"type": "text",
"analyzer": "ngram"
},
"autocomplete": {
"type": "text",
"analyzer": "autocomplete_analyzer",
"search_analyzer": "autocomplete_analyzer"
}
}
},
"description": {
"type": "keyword",
"ignore_above": 10000,
"fields": {
"raw": {
"type": "text",
"analyzer": "remove_html",
"search_analyzer": "standard"
},
"seunjeon": {
"type": "text",
"analyzer": "seunjeon"
},
"ngram": {
"type": "text",
"analyzer": "ngram"
}
}
}
"createdDate": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"updatedDate": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
예시로 구현한 형태소 분석기와 관련하여 설명을 덧붙이자면 아래와 같다.
- $.raw: 필드명에서 한글, 영문, 숫자 제외한 문자 제거 + 한글&숫자 조합의 경우 숫자 제거 + 대문자 -> 소문자 + 스페이스 별로 분리
- ex) [디플랫]포켓 밍크 베스트 F03DVT001 → 디플랫 / 포켓 / 밍크 / 베스트 / f03dvt001
- ex) QA_쿠폰7 → qa / 쿠폰
- $. ngram: 스페이스 별로 분리 + 대문자 -> 소문자 + 필드명 앞글자부터 2~10 자리수까지 분리
- ex) [디플랫]포켓 밍크 베스트 F03DVT001 → 디플 / 디플랫 / 포켓 / 밍크 / 베스 / 베스트 / f0 / f03 / f03d / f03dv / f03dvt / f03dvt0 / f03dvt00 / f03dvt001
- $.keyword: 필드명 그대로 사용
- ex) [디플랫]포켓 밍크 베스트 F03DVT001 → [디플랫]포켓 밍크 베스트 F03DVT001
- $.seunjeon: OpenSearch 에서 제공하는 은전한닢 형태소 분석기 사용
※ Kibana Dashboard 설정 방법
DELETE ${INDEX명}
PUT ${INDEX명}
{
"settings": {
"index.mapping.ignore_malformed": true,
"index.search.slowlog.threshold.query.warn": "10s",
"index": {
"analysis": {
"analyzer": {
"standard": {
"type": "custom",
"tokenizer": "standard"
},
"seunjeon": {
"type": "custom",
"tokenizer": "seunjeon_tokenizer",
"dictionary_filter": ["synonyms", "stopwords"],
"filter": ["lowercase", "trim"]
},
"ngram": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"filter": ["lowercase", "trim"]
},
"autocomplete_analyzer": {
"tokenizer": "standard",
"filter": ["lowercase", "trim", "autocomplete"]
},
"remove_html": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"char_filter": ["html_strip"],
"dictionary_filter": ["stopwords"],
"filter": ["lowercase", "trim"]
},
"remove_special_char": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"char_filter": ["remove_whitespace", "remove_special_char"],
"dictionary_filter": ["stopwords"],
"filter": ["lowercase", "trim"]
}
},
"tokenizer": {
"seunjeon_tokenizer": {
"type": "seunjeon_tokenizer",
"user_dictionary": "analyzers/F175892661",
"index_poses": [
"UNK",
"I",
"M",
"N",
"S",
"SL",
"SH",
"SN",
"V",
"VCP",
"XP",
"XS",
"XR"
],
"index_eojeol": false,
"decompound": true,
"pos_tagging": false
},
"ngram_tokenizer": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10,
"token_chars": ["letter", "digit"]
}
},
"filter": {
"autocomplete": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20,
"token_chars": ["letter", "digit", "whitespace"]
}
},
"dictionary_filter": {
"synonyms": {
"type": "synonym",
"synonyms_path": "analyzers/F217095579",
"updateable": true
},
"stopwords": {
"type": "stop",
"synonyms_path": "analyzers/F13804164",
"updateable": true
}
},
"char_filter": {
"remove_special_char": {
"pattern": "[^A-Za-z0-9]",
"type": "pattern_replace",
"replacement": ""
},
"remove_whitespace": {
"type": "pattern_replace",
"pattern": " ",
"replacement": ""
}
}
}
}
}
}
728x90
'ElasticSearch & OpenSearch' 카테고리의 다른 글
[ElasticSearch] _cat API 를 이용한 ES 모니터링 (0) | 2022.12.19 |
---|---|
[ElasticSearch] _script 를 사용한 sort (0) | 2022.05.05 |
[ElasticSearch] Settings, Mapping 설정하기 (0) | 2021.05.06 |
[ElasticSearch] 한글 형태소 분석기 설치하기 (0) | 2021.05.03 |
[Filebeat] docker-filebeat 세팅하고 띄우기 (0) | 2021.04.29 |