분석기(analyzer)는 문서를 색인하거나 검색어를 처리할 때 문장을 검색 단위(토큰)로 나누는 규칙이다. OpenSearch의 기본 분석기는 띄어쓰기로만 나누기 때문에, 조사와 어미가 붙는 한국어에서는 '환불'로 '환불을'을 찾지 못한다. nori는 Lucene의 한국어 형태소 분석기이고, 조사를 떼고 활용된 말을 원래 모양으로 되돌려 토큰을 만든다.
기본 분석기와 nori 비교
_analyze API로 같은 문장을 두 분석기에 넣으면 나뉘는 결과가 다르다. OpenSearch 3.9.0에서 실행한 결과다.
curl localhost:9200/_analyze -H 'Content-Type: application/json' \
-d '{"analyzer":"standard","text":"배송이 늦어서 환불을 요청했습니다"}'| 분석기 | 토큰 |
|---|---|
standard | 배송이, 늦어서, 환불을, 요청했습니다 |
nori | 배송, 늦, 환불, 요청 |
standard는 띄어쓰기 단위로 나눈다. 조사와 어미가 토큰에 그대로 붙어 있다.nori는 조사(이,을)와 어미(어서,했습니다)를 떼고, 활용된 말을 원래 모양으로 돌린다. 다른 문장에서는빨라를빠르로,흐트러졌습니다를흐트러지로 바꾼다.
검색 결과 차이
같은 문서를 두 분석기로 만든 인덱스에 각각 넣고 검색하면 결과가 갈린다.
| 검색어 | standard 인덱스 | nori 인덱스 |
|---|---|---|
환불 | 0건 | 1건 |
배송 | 0건 | 1건 |
환불은 | 0건 | 1건 |
요청 | 0건 | 1건 |
standard 인덱스에는 환불을이라는 토큰만 있어서, 환불로 검색하면 일치하는 토큰이 없다. 조사까지 똑같이 쳐야 찾는다. nori 인덱스는 검색어도 같은 분석기로 나누기 때문에, 환불은으로 검색해도 환불로 바뀌어 문서의 환불과 일치한다.
설치
nori는 OpenSearch 기본 이미지에 들어 있지 않고 플러그인으로 설치한다.
FROM opensearchproject/opensearch:3.9.0
# --batch가 없으면 설치 중 권한 확인 질문에서 멈춤
RUN /usr/share/opensearch/bin/opensearch-plugin install --batch analysis-noriDocker Compose에서는 image: 대신 build:로 이 Dockerfile을 가리킨다. 설치 여부는 curl localhost:9200/_cat/plugins의 analysis-nori 줄로 확인한다.
테스트에서 Testcontainers로 OpenSearch를 띄울 때도 nori가 든 이 이미지를 써야 한다. 공식 이미지를 그대로 쓰면 매핑에 "analyzer": "nori"를 적은 인덱스를 만들 때 분석기를 찾지 못해 실패한다. Testcontainers는 Spring Boot에서 Testcontainers 쓰기에 정리했다.
분석기는 인덱스를 만들 때 정함
분석기는 매핑에서 필드마다 지정한다.
PUT /reviews
{
"mappings": {
"properties": {
"body": { "type": "text", "analyzer": "nori" }
}
}
}플러그인을 설치해도 이미 만든 인덱스의 필드는 원래 분석기 그대로다. 텍스트 필드의 분석기는 이미 색인된 토큰과 맞아야 하므로, 있는 필드의 분석기는 바꿀 수 없다. 분석기를 바꾸려면 새 인덱스를 만들고 문서를 다시 넣는다(재색인).
원본이 DB에 있다면 재색인은 'DB에서 다시 읽어 새 인덱스에 넣기'로 끝난다. 인덱스 이름을 코드에서 직접 쓰지 않고 별칭(alias)으로 가리키게 해 두면, 새 인덱스를 다 채운 뒤 별칭만 옮겨서 검색 중단 없이 바꿀 수 있다.
세부 옵션
nori는 기본값으로도 쓸 만하지만 몇 가지를 조정할 수 있다.
decompound_mode: '환불요청' 같은 복합어를 어떻게 나눌지 정한다.none(나누지 않음),discard(나누고 원래 말은 버림, 기본값),mixed(나눈 것과 원래 말을 모두 남김)가 있다.user_dictionary: 서비스 고유의 용어를 사전에 넣어 한 단어로 다루게 한다.nori_part_of_speech토큰 필터: 조사, 어미처럼 검색에 쓸모없는 품사를 뺀다. 기본nori분석기에 이미 들어 있다.
공식 문서: OpenSearch, Nori analyzer