카테고리 없음

06장 고급 검색

막이86 2023. 11. 8. 17:29
728x90

엘라스틱서치 실무 가이드 6장을 요약한 내용입니다.

6.1 한글 형태소 분석기 사용하기

  • 한글 문서를 효율적으로 검색하게 하려면 한글 형태소 분석기를 활용해 분석기를 구성해야 한다
  • 한글 형태소 분석기로는 상용 제품도 있고 오픈소스로 공개된 것도 있다

6.1.1 은전한닢 형태소 분석기

  • 자바 인터페이스와 스칼라 인터페이스 두 종류를 제공
  • 엘라스틱서치에서 가장 보편적으로 사용하는 한글 형태소 분석기
  • tokenizer 설정을 통해 은전한닢 플러그인에서 제공하는 seunjeon_tokenizer를 활성화하고 analyzer 설정을 통해 형태소 분석기를 정의하면 사용 준비가 끝난다

사전 추가

  • 검색 엔진에서 “삼성”을 검색하거나 “전자”를 검색했을 때도 문서가 검색되게 하고 싶다면 복합명사를 분리해서 역색인 해야 한다
  • 사용자가 등록하는 사전을 제공
    • setting에 사용자 사전의 경로를 지정
    • user_dict_path
  • 사용자 사전은 텀(Term)과 가중치(Weigth) 형태로 구성
  • 가중치는 값이 작을수록 그에 따른 우선 순위는 높아짐

6.1.2 Nori 형태소 분석기

  • 루씬 프로젝트에서 공식적으로 제공하는 한글 형태소 분석기
    • 엘라스틱서치 6.4 버전에서 공식 릴리즈

6.1.2.1 nori_tokenizer 토크나이저

  • 형태소를 토큰 형태로 분리하는데 사용
    • decompound_mode: 복합명사를 토크나이저가 처리하는 방식
    • user_dictionary: 사용자 사전 정의

decompound_mode

  • 복합명사가 있을 경우 단어를 어떻게 쪼갤지 결정

user_dictionary

  • 사용자가 정의한 명사를 사전에 추가로 등록 가능

6.1.2.2 nori_part_of_speech 토큰 필터

  • 품사 태그 세트와 일치하는 토큰을 찾아 제거하는 토큰 필터

6.2 검색 결과 하이라이트 하기

  • 하이라이트는 문서 검색 결과를 웹상에서 출력할 때 입력한 검색어를 강조하는 기능
  • 데이터를 검색할 때 “highilght” 옵션을 사용
  • // 데이터 생성 PUT /movie_highlighting/_doc/1 { "title": "Harry Potter and Deathly Hallows" } // 하이라이트 검색 POST /movie_highlighting/_search { "query": { "match": { "title": { "query": "harry" } } }, "highlight": { "fields": { "title": {} } } } // 검색결과
  • <em> 태그가 아닌 별도의 태그를 설정
  • POST /movie_highlighting/_search { "query": { "match": { "title": { "query": "harry" } } }, "highlight": { "per_tags": [ "<strong>" ], "post_tags": [ "</strong>" ], "fields": { "title": {} } } } // 검색결과

6.3 스크립팅을 이용해 동적으로 필드 추가하기

  • 스크립트를 이용해 사용자가 특정 로직을 삽입하는 것이 가능
  • 스크립팅 전용 언어인 페인리스가 도입

필드 추가

  • 스크립팅을 이용해 이미 색인된 문서에 필드를 추가
  • // 데이터 추가 PUT /movie_script/_doc/1 { "movieList": { "Death_Wish": 5.5, "About_Time": 7, "Suits": 3.5 } } // 필드 추가 POST /movie_script/_doc/1/_update { "script": "ctx._source.movieList.Black_Panther = 3.7" } // 조회 결과 GET /movie_script/_doc/_search

필드 삭제

  • 기존 필드를 제거하는 것도 스크립트를 이용해 처리 가능
  • // 필드 삭제 POST /movie_script/_doc/1/_update { "script": "ctx._source.movieList.remove(\\"Suits\\")" } // 조회 결과 GET /movie_script/_doc/_search

6.4 검색 템플릿을 이용한 동적 쿼리 제공

  • 검색 템플릿을 사용하면 복잡한 검색 로직을 쉽게 사용 가능
  • 요구사항 변경에 따라 클라이언트를 수정하지 않아도 됨
  • 검색 템플릿은 Mushtache라는 템플릿 엔진을 사용
  • _script API를 사용해 템플릿을 생성
  • POST /_scripts/movie_search_example_template { "script": { "lang": "mustache", "source": { "query": { "match": { "movieNm": "{{ movie_name }}" } } } } }
  • 생성된 템플릿 확인
  • GET /_scripts/movie_search_example_template // 결과
  • 템플릿을 테스트
  • // 인덱스 생성 PUT /movie_template_test/_doc/1 { "movieNm": "titanic" } // 템플릿을 사용한 검색 POST /movie_template_test/_doc/_search/template { "id": "movie_search_example_template", "params": { "movie_name": "titanic" } } // 결과
  • 실무에서는 검색 쿼리 변경하는 일이 자주 일어남
    • 수정 될 때마다 클라이언트 쿼리를 수정 배포는 쉽지 않음
  • 검색 시 직접 쿼리를 수행하지 않고 템플릿을 제공한다면 검색 쿼리의 변경에 유연하게 대처할 수 있을 것이다

6.5 별칭을 이용해 항상 최신 인덱스 유지하기

  • 클러스터를 운영 중에 인덱스 매핑 설정이 변경되거나 인덱스가 깨지면 기존 생성된 인덱스를 삭제하고 다시 생성해야 한다
  • 운영 중인 서비스에서 인덱스를 삭제한다면 클라이언트에서 에러가 발생
    • 운영 중에 인덱스를 다시 생성하는 경우는 생각보다 자주 발생
  • 별칭(Alias)기능을 제공
    • 인덱스 생성할 때 별칭을 사용해 인덱스가 추가되거나 삭제될 경우 새로운 인덱스로 사용자 요청을 이동할 수 있다
  • 인덱스의 별칭을 사용하면 두 개 이상의 인덱스를 검색할 때 한번의 요청으로 모두 검색 가능
    • movie_search, movie_info 두 인덱스를 모두 검색시 movie_search,movie_info/_doc/_search 사용
    • 별칭을 사용하면 하나의 인덱스처럼 호출 할 수 있음
    • // 별칭을 통해 두 인덱스를 movie로 설정 POST /_aliases { "actions": [ { "add": {"index": "movie_search", "alias": "movie"}}, { "add": {"index": "movie_info", "alias": "movie"}}, ] } // 별칭으로 조회 POST /movie/_search
  • 별칭은 색인을 다시 만드는 경우에 더 많이 활용
    • 색인을 삭제하고 다시 만드는 경우가 많다 보니 별칭은 거의 필수
  • 매일 새롭게 생성되는 인덱스에 별칭을 사용 방법
  • POST /_aliases { "actions": [ { "delete": {"index": "movie_search_1544054400", "alias": "movie_search"}}, { "add": {"index": "movie_search_1544140800", "alias": "movie_search"}}, ] }

6.6 스냅숏을 이용한 백업과 복구

  • 클러스터와 인덱스의 데이터가 커질수록 백업의 필요성이 커짐
  • 스냅숏 기능을 이용해 개별 인덱스를 백업
  • 클러스터 전체를 스냅숏으로 만드는 것도 가능
  • 스냅숏을 사용하기 위해서는 물리적인 디렉터리를 생성
  • $ mkdir /home/snapshot/elastic/backup
  • config폴더에 있는 elasticsearch.yml 에 스냅숏 경로를 지정
  • path.repo: ["/home/snapshot/elastic/backup"]
  • 재시작 후 movie_data_backup이라는 리포지토리 생성
    • 스냅숏 설정 시 제공되는 옵션location 스냅숏의 저장 경로를 설정
      compress 스냅숏 생성 시 압축을 수행, 데이터는 압축되지 않으며 메타데이터만 압축 대상이 된다.
      chunk_size 생성되는 파일의 특정 크기로 나눠서 생성, 기본적으로 스냅숏은 하나의 파일로 생성
      max_restore_bytes_per_sec 스냅숏 복원 시 속도를 설정, 기본적으로 초당 40MB의 속도를 낸다
      max_snapshot_bytes_per_sec 스냅숏 복원 시 속도를 설정, 기본적으로 초당 40MB의 속도를 낸다
      readonly 리포지토리를 읽기 전용으로 생성
  • PUT /_snapshot/movie_data_backup { "type": "fs", "settings": { "location": "/home/snapshot/elastic/backup", "compress": true } }
  • 스냅숏 대상이 되는 인덱스는 더 이상 변경이 없는 인덱스여야만 한다
    • 변경이 일어나는 도중에 스냅숏이 생성되면 문제가 발생할 가능성이 높다
  • movie_search_1544054400 인덱스를 스냅숏으로 생성
    • wait_for_completion 스냅숏이 생성이 완료될 때까지 기다릴 수 있다
    PUT /_snapshot/movie_data_backup/movie_snapshot_part1?wait_for_completion=true
    {
    	"indices": "movie_search_1544054400 ",
    	"ignore_unavailable": true,
    	"include_global_state": false
    }
    
  • 스냅숏을 생성할 때 스냅숏 이름은 유일한 값이여야 한다
    • 이미 존재한다면 오류 메세지를 출력
  • 모든 스냅숏에 대한 정보 확인
  • GET /_snapshot/movie_data_backup/_all
  • 데이터를 복구하는 방법
    • 이미 인덱스가 있다면 복구는 실패
    POST /_snapshot/movie_data_backup/movie_snapshot_part1/_restore
    
  • 인덱스가 정상적으로 복구되려면 클러스터 내부에 동일한 이름의 인덱스가 존재해서는 안된다
    • 이미 존재하는 인덱스는 삭제
    DELTE /movie_search_1544054400 
    
  • 백업된 스냅숏을 삭제
  • DELTE /_snapshot/movie_data_backup/movie_snapshot_part1
728x90