Elastic Search

Ch07. 한글 검색 확장 기능 - Suggest API 소개

webmaster 2025. 9. 28. 02:01
728x90

사용자가 키워드를 잘못 입력하였거나, 검색한 키워드가 없을 경우 어떻게 해야 할까? 검색 결과의 만족도를 높이긴 위해서는 도큐먼트 내에 존재하는 단어를 대상으로 비슷한 키워드를 변경해서 제시하는 교정 기능을 제공해야 한다.

엘라스틱서치에서 제공하는 Suggest API를 이용하면 텀과 정확히 일치하지 않는 단어도 자동으로 인식해서 처리할 수 있으며 좀 더 사용자 친화적인 검색 서비스를 제공할 수 있다. 단어의 철자를 수정해서 다른 단어를 제안하거나, 제안된 내용을 보여주는 맞춤법 검사기 기능을 사용하면 된다.

 

SuggestAPI의 4가지 기능

  • Term Suggest API:추천 단어 제안(한글에서는 잘 동작하지 않는다.)
  • Completion Suggest API: 자동 완성 제안(한글에서는 잘 동작하지 않는다.)
  • Phrase Suggest API: 추천 문장 제안
  • Context Suggest API:추천 문맥 제안

Term Suggest

Term Suggest는 편집거리를 사용해 비슷한 단어를 제안한다. 편집거리 척도란 어떤 문자열이 다른 문자열과 얼마나 비슷한가를 편집거리를 사용해 알아볼 수 있으며, 두 문자열 사이의 편집 거리는 하나의 문자열을 바꾸는데 필요한 편집 횟수를 의미한다.

편집 거리를 측정하는 방식으로 대부분 각 단어를 삽입, 삭제, 치환하는 연산을 포함하며, 이러한 연산을 조합해 척도를 측정한다.

측정 과정을 진행할 때 한 문자열을 다른 문자열로 바꾸는데 필요한 삽입, 삭제, 치환 연산의 총 수행 회수의 합계를 편집 거리라고 한다.

참고
엘라스틱서치에서의 편집 거리 계산은 리벤슈타인 편집 거리 측정 방식 혹은 자로-윙클러 편집 거리 측정 방식을 기본으로 사용한다.
- 리벤슈타인 편집 거리 측정: https://en.wikipedia.org/wiki/Levenshtein_distance 
- 윙클러 편집 거리 측정:https://en.wikipedia.org/wiki/Jaro–Winkler_distance

 

Request

POST movie_term_suggest/_search
{
  "suggest": {
    "spell-suggestion": {
      "text": "lave",
      "term": {
        "field": "movieNm"
      }
    }
  }
}

Response

{
  "spell-suggestion": [
    {
      "text": "lave",
      "offset": 0,
      "length": 4,
      "options": [
        {
          "text": "love",
          "score": 0.75,
          "freq": 1
        },
        {
          "text": "lover",
          "score": 0.5,
          "freq": 1
        }
      ]
    }
  ]
}
  • lave와 일치하는 텀이 존재하지 않기 때문에 가장 유사한 단어를 추출해서 반환한다.
  • 필드 분석
    • text: 제안한 문자를 나타냄
    • score: 제안하고자 하는 텍스트가 원본과 얼마나 가까운지
    • freq: 전체 문서에서 해당 텀의 빈도수
  • 한글 같은 경우에는 Term Suggest를 이용해도 데이터가 추천되지 않음(한글 유니코드 체계가 복잡하기 때문)
    • 한글의 자소를 분해해서 문서를 처리한 후 색인할 경우에는 영문과 동일하게 추천 기능을 구현하는 것이 가능해진다(자바카페 플러그인 사용, ICU 분석기를 이용)

Completion Suggest API

엘라스틱서치에서는 자동완성을 위해 Completion Suggest API를 제공하며, 자동 완성은 글자가 입력될 때마다 검색 결과를 보여줘야 하기 때문에 응답 속도가 매우 중요하다. Completion Suggest API를 사용하면 내부적으로 FST를 사용하며, FST는 검색어가 모두 메모리에 로드되어 서비스되는 구조로 리소스 측면에서는 많은 비용이 한꺼번에 발생하기 때문에 성능 최적화를 위해 색인 중에 FST를 작성하게 된다.

 

인덱스 생성

PUT movie_term_completion
{
  "mappings": {
    "_doc": {
      "properties": {
        "movieNmEnComple": {
          "type": "completion"
        }
      }
    }
  }
}
  • 자동완성 기능을 사용하기 위해서는 데이터 타입을 Completion으로 설정해서 인덱스를 생성해야 한다.

자동완성 테스트

POST movie_term_completion/_search
{
  "suggest": {
    "movie_completion": {
      "prefix": "I",
      "completion": {
        "field": "movieNmEnComple"
      }
    }
  }
}

Response

{
  "suggest": {
    "movie_completion": [
      {
        "text": "I",
        "offset": 0,
        "length": 1,
        "options": [
          {
            "text": "Love for a mother",
            "_index": "movie_term_completion",
            "_type": "_doc",
            "_id": "3",
            "_score": 1.0,
            "_source": {
              "movieNmEnComple": "Love for a mother"
            }
          },
          {
            "text": "Lover",
            "_index": "movie_term_completion",
            "_type": "_doc",
            "_id": "2",
            "_score": 1.0,
            "_source": {
              "movieNmEnComple": "Lover"
            }
          }
        ]
      }
    ]
  }
}
  • L로 시작하는 모든 영화 제목 검색
    • 검색 시, suggest 옵션을 사용해야 하며, prefix로 검색할 키워드, completion에 검색에 사용할 필드를 지정해야 한다.
  • Prefix로 L로 지정 시, L로 시작하는 단어만 검색되게 된다.
  • Comletion을 사용하려면 필드에 데이터를 넣을 때 검색이 가능해지는 형태로 거공해서 넣어야 한다.(부분 일치를 원하면 부분을 분리해서 배열 형태로 만들어서 넣어주어야 한다)

부분 검색 허용을 위해 부분 일치 Input 넣기

  • Completion Suggest API는 전방일치 방식밖에 지원하지 않기 때문에 색인 시, 데이터를 가공해야 한다
    • 단어 단위로 잘라 배열 형태로 넣어 Prefix에 의한 전방 일치에 의해 검색이 이뤄짐
  • 한글의 경우도 자소를 분해해서 사용하여 자동완성을 만들 수 있다. 
    • 단, 영문처럼 한 단어가 아닌 복합 명사 또는 두 단어 이상의 단어를 처리해야 하기 때문에 별도의 플러그인을 이용해 처리해야 한다.
728x90