java 배우기/TIL

Elasticsearch 동의어 필터 적용하기

checkuu 2024. 11. 16. 04:27

elasticsearch를 우리 프로젝트에 잘 적용해서 작동하는것 까지 확인했으니, 이제 왜 이걸 도입했는지 필요한 설정을 해보자.

elasticsearch analyzer 설정이다.

PUT /boards
{
  "settings": {
    "analysis": {
      "tokenizer": {
        "nori_tokenizer": {
          "type": "nori_tokenizer",
          "decompound_mode": "mixed" 
        }
      },
      "filter": {
        "lowercase": {
          "type": "lowercase"
        },
        "remove_whitespace_filter": {
          "type": "pattern_replace", 
          "pattern": "\\s+", 
          "replacement": "" 
        },
        "synonym_filter": {
          "type": "synonym",
          "synonyms": [
            "장미, 자미, 강미, 당미, 로즈, 자미",
            "부레,물야자,수생,불레,브레",
            "히비스커스, 대홍단, 히비스크, 히비스쿠스, hibiscus, 여름꽃"
          ] 
        }
      },
      "analyzer": {
        "custom_nori_analyzer": {
          "type": "custom",
          "tokenizer": "nori_tokenizer",  
          "filter": [
            "lowercase",
            "synonym_filter",
            "remove_whitespace_filter" 
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "custom_nori_analyzer"  
      },
      "content": {
        "type": "text",
        "analyzer": "custom_nori_analyzer"  
      }
    }
  }
}

 

난 위와 같이 설정했다.

내가 원하는건 식물 커뮤니티에서 사람들이 검색할때 식물 이름이 어렵기 때문에 틀릴경우가 잦다고 생각했다.

그래서 유사어 검색이 꼭됐으면 좋겠어서 elasticsearch를 선택한 거였다.

그래서 하나씩 보자면,

"nori_tokenizer" : 한국에서 서비스하기 위해 노리를 깔고 노리 형태소 분석기를 넣었다.

필터들

"lowercase" : 영어 대소문자를 소문자로 바꿔서 저장해준다.

"remove_whitespace_filter" : 띄어쓰기를 불용성 단어로 인지하고 없애준다.

"synonym_filter" : 동의어 필터인데 내가 스프링 쿼리로 검색기능을 만들지 않고 elasticsearch를 사용한 이유이다.

 

해당 필터를 analyzer에 넣고 네이밍해서 원하는 컬럼에 적용시켜 준다.

그전에 테스트로 만든 인덱스가 있어서 우선 인덱스 삭제부터 해줬다.

꽤 중요한 작업이다. elasticsearch는 인덱스 생성된 후에는 analyzer를 변경 할 수 없다.

이유는 인덱스 생성 시점에 설정된 매핑과 분석기가 문서의 텍스트를 어떻게 분해하고 인덱싱할지를 결정하기 때문이다.

그래서 인덱스 설정을 바꾸고싶으면 지웠다가 다시 PUT 해줘야한다.

넣어주고 오른쪽 재생버튼 눌러주면 인덱스가 생성되면서 설정이 저장된다고 보면된다.

동의어 필터 만들때 에러가 자꾸 떴다.
해당 에러는 동의어 설정 부분에서 문제가 발생했다.


https://checkuu.tistory.com/183

 

Elasticsearch 동의어 필터 생성 중 오류

문제elasticsearch에 analyzer 설정하고 인덱스를 설정하는데 아래와 같은 오류가 떴다. 내가 넣은 동의어 필터의 내용이다.이유해당 오류의 의미는 장미꽃이 토큰화될 때 장미라는 단어로 분해되었

checkuu.tistory.com

 

오류는 해결했으니,

간단하게 검색이 되는지와 동의어가 작동하는지 랜덤 더미데이터를 50만개 만들어서 넣어줬다. (추후 성능테스트를 위해 미리 넣어줬다.)

hits가 10000개 됐고 밑에 원하는 결과도 잘나오고있다. (엘라스틱서치는 10000개까지 검색결과를 가져온다.)

저장이 잘되어 조회가 되는것을 확인했으니 동의어가 되는지 확인 해보자.

우선은 기본 장미 이다.

스프링 검색 엔진

 

elasticsearch 검색 엔진

 

hit가 10000개 됐고 밑에도 잘나온다.

 

동의어로 넣은 당미다.


스프링 검색 엔진

스프링 query 에서 like 쓴 검색으로는 결과가 나오지 않는다.

 

elasticsearch 검색 엔진

장미랑 같은 결과가 나온다.

 

부레옥잠에 설정한 다른 동의어 "불레"도 테스트 해보자.

 

스프링 검색 엔진

역시 안나온다.

 

elasticsearch 검색 엔진 

잘나왔다. 

 

히비스커스의 동의어도 검색해보자 

elasticsearch 검색 엔진

 

잘나온다.

원했던 결과가 잘나와서 뿌듯하다.

 

해당 기능이 정삭 작동 하는것으로 지금 진행하는 프로젝트의 목표 중 하나인 이름이 어려워 다외우지 못한 식물이나 단순 오타로 인한 잘못된검색에도 원하는 결과가 나올 수 있게 설정 됐다.

 

analyzer 부분 더 공부해서 이것저것 기능을 활용할 수 있을 것같다.

우선 다음은 50만건 랜덤생성으로 게시글 넣고 검색하는 테스트를 진행해보겠다.