Skip to content

부록. 장소 index 구성

Soap edited this page Dec 4, 2024 · 3 revisions

목차

  1. 현 상황 및 Elasticsearch 도입 계기
  2. 검색 로직 설계
  3. 싱글 노드에 따른 SFP 대처
  4. Fallback 처리시 응답 시간 이슈 해결
  5. RDB와의 동기화

부록

  1. 장소 index 구성
  2. Elasticsearch 로컬환경 구성
  3. Elasticsearch 배포환경 구성

What is an Elasticsearch Index

Elasticsearch에서 Index란?

Elasticsearch 에서 index란 문서 컬렉션을 포함하는 논리적인 개념이다. RDBMS의 테이블과 같은 역할이라고 생각할 수 있다.

결국 Elasticsearch도 하나의 NoSQL이기 때문에, index 내부에 key, value 쌍으로 구성되는 데이터들이 포함된다.

장소 Index 구성

우리 서비스는 장소 검색을 위해 사용할 것이기 때문에 장소 데이터를 저장 할 장소 index가 필요하다. 이를 구성해보기로 했다.

{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "analysis": {
      "analyzer": {
        "nori_with_synonym": {
          "type": "custom",
          "tokenizer": "nori_tokenizer",
          "filter": [
            "lowercase",
            "nori_readingform",
            "synonym_filter"
          ]
        }
      },
      "filter": {
        "synonym_filter": {
          "type": "synonym",
          "synonyms_path": "synonyms.txt"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id": {
        "type": "integer"
      },
      "googlePlaceId": {
        "type": "keyword"
      },
      "name": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        },
        "analyzer": "nori_with_synonym"
      },
      "thumbnailUrl": {
        "type": "text",
        "index": false
      },
      "rating": {
        "type": "scaled_float",
        "scaling_factor": 100
      },
      "location": {
        "type": "geo_point"
      },
      "formattedAddress": {
        "type": "text",
        "analyzer": "nori_with_synonym"
      },
      "category": {
        "type": "keyword",
        "index": true
      },
      "description": {
        "type": "text"
      },
      "detailPageUrl": {
        "type": "text",
        "index": false
      },
      "createdAt": {
        "type": "date",
        "format": "strict_date_optional_time||epoch_millis"
      },
      "updatedAt": {
        "type": "date",
        "format": "strict_date_optional_time||epoch_millis"
      },
      "deletedAt": {
        "type": "date",
        "format": "strict_date_optional_time||epoch_millis",
        "null_value": null
      }
    }
  }
}

기본적으로는 RDBMS에 저장되어 있는 Place의 구조와 똑같이 만들었다. latitude, longitude로 저장되어 있던 값들만 location이라는 key로 만들어줬다.

Analyzer

앞 부분을 보면 커스텀 Analyzer 하나를 구성했다. 현재 서비스의 타켓이 대한민국 사람들인 만큼 한국어 형태소 분석기인 NoriAnalyzer를 사용하기로 결정했다.

https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-nori.html#analysis-nori-remove

물론 다양한 분석기가 있을 것이고 더 적합한 분석기가 있을 테지만, 현재로서는 이 정도로 충분할 것 같다고 생각했다.

filter 된 부분을 보면 synonym_filter 를 추가해줬다. 이는 사용자가 검색했을 때 적용할만한 동의어들을 파일로 적어뒀다.

예를 들어, 서울, 서울시, 서울특별시 등의 대한민국 행정구역 장소들을 동의어로 등록해뒀다.

물론, 실제 다양한 상황이 있을 것이다. 사용자가 "강남역"으로 검색하는 경우, 강남에 있는 장소가 아닌, 서초구에 있는 강남역 주변의 장소를 보여줘야 하는 등의 세부상황도 고려할 것이 너무 많았다. 다만, 서비스 특성 상, 사용자는 상호명으로 검색을 더 할 것이라고 생각했고 당장에는 이 정도로 충분할 것 같았다. 이에 테스트를 더 진행하며 개선할 사항 중 하나라고 생각하고 넘어갔다.

오늘의 길

핵심 경험

장소 검색 기능 개선
마커 클러스터링
테스트 코드
로그 모니터링 시스템
React 컴포넌트로 구글 지도 요소 관리하기
CI/CD 파이프라인
코스 아이템 순서 수정 방식 개선

개발 문서

팀 문화

기록 모음

🌤️ 데일리 스크럼
📑 회의록
🚸 멘토링 일지
🏖️ 그룹 회고
Clone this wiki locally