Elasticsearch 기본(1) - 인덱스, 도큐먼트, 매핑
29 May 2022Index
- 클러스터에 생성
- 도큐먼트를 저장하는 논리적 구분자
- 하나의 인덱스에 다수의 도큐먼트 포함
- 같은 인덱스에 포함된 도큐먼트는 동일한 스키마를 가짐
- 인덱스 이름
- 영어 소문자
\, /, *, ?, ", <, >, |, #
, 공백, 쉼포 제외한 특수문자 사용 가능- 최대 255바이트
- 스키마에 따라 인덱스 구분
- 기본적으로 용량이나 숫제 제한없이 무한대의 도큐먼트 포함 가능
- 인덱스가 커지면 성능 문제
- 특정 도큐먼트 개수에 도달하거나 용량을 넘어서면 인덱스 분리
- API
- 생성:
PUT {index_name}
(POST도 가능) - 조회:
GET {index_name}
- 삭제:
DELETE {index_name}
- 생성:
Document
- 인덱스 내부에 JSON 형태로 다수의 도큐먼트 존재
- 실제 데이터를 저장하는 단위
- 여러 필드와 값을 가짐
- 매핑으로 필드의 데이터 타입 지정
- 인덱싱(indexing)
- 도큐먼트를 인덱스에 포함시키는 것
- 인덱스를 생성하면서 동시에 도큐먼트를 해당 인덱스에 인덱싱 가능
-
_doc
은 엔드포인트 구분을 위한 예약어, 1은 도큐먼트의 고유 아이디가 됨// PUT index1/_doc/1 { "name": "Tom", "age": 42, "gender": "male" }
- 인덱스를 확인을 통해 설정값과 mappings 확인
-
다이내믹 매핑(dynamic mapping): 도큐먼트의 필드와 값을 보고 자동으로 지정
// GET index1 { "index1": { "alias": { }, "mappings": { "properties": { "age": { "type": "long", ... }, "gender": { "type": "text", ... }, "name": { "type": "text", ... }, ... } } } }
- 데이터 형변환 진행
- 숫자 필드에 문자열이 입력되면 숫자로 변환
- 정수 필드에 소수가 입력되면 소수점 아래 자리 무시
- 도큐먼트 읽기
- 특정 도큐먼트 읽기:
GET {index_name}/_doc/{document_id}
- 모든 도큐먼트 읽기:
GET {index_name}/_search
- 특정 도큐먼트 읽기:
- 도큐먼트 수정
PUT {index_name}/_doc/{document_id}
// PUT index1/_doc1/1 { "name": "Tom", "age": 45, "gender": "male" }
POST {index_name}/_update/{document_id}
// POST index1/_update/1 { "doc" : { "name" : "Mark" } }
- 도큐먼트 수정은 비용이 많이 드는 작업
- 도큐먼트 삭제
DELETE {index_name}/_doc/{document_id}
- 도큐먼트 삭제도 비용이 많이 드는 작업
응답 메세지
코드 | 상태 | 해결 방법 |
---|---|---|
20, 201 | 정상 수행 | |
4xx | 클라이언트 오류 | 클라이언트에서 문제 수정 |
404 | 요청 리소스가 없음 | 인덱스나 도큐먼트가 존재하는지 확인 |
405 | 요청 메소드 지원 안 함 | API 확인 |
429 | 요청 과부화(busy) | 재전송, 노드 추가 |
5xx | 서버 오류 | 엘라스틱서치 로그 확인 |
Mapping
-
RDB의 스키마와 비슷한 역할을 하며 JSON 형태의 데이터를 루씬이 이해할 수 있도록 바꾸는 작업
- 다이나믹 매핑
- 데이터 타입에 맞춰 엘라스틱서치가 자동으로 매핑하는 것
데이터 타입 다이나믹 매핑으로 변환된 데이터 타입 null 필드 추가 X boolean boolean float float integer long object object string 데이터 형태에 따라 date, text/keyword - 명시적 매핑
- 사용자가 직접 정의
- 인덱스 생성할 때 정의하거나 mapping API 사용
// PUT {index_name} { "mappings" : { "properties" : { "age" : {"type" : "long"}, "name" : {"type" : "text"}, ... } } }
- 매핑 타입
형태 | 타입 | 설명 |
---|---|---|
문자열 | text | 전문 검색이 필요한 데이터 텍스트 분석기가 텍스트를 작은 단위로 분리 |
문자열 | keyword | 정렬이나 집계에 사용되는 데이터 분석하지 않고 원문 통째로 인덱싱 |
날짜 | date | 날짜/시간 데이터 |
정수 | byte, short, integer, long | byte: 부호 있는 8비트 데이터(-128~127) short: 부호 있는 16비트 데이터(-32768~32767) integer: 부호 있는 32비트 데이터(-2^31~2^31-1) long: 부호 있는 64비트 데이터(-2^63~2^63-1) |
실수 | scaled_float, half_float, double, float | scaled_float: float 데이터에 특정 값을 곱해 정수형으로 바꾼 데이터 half_float: 16비트 부동소수점 실수 데이터 double: 32비트 부동소수점 실수 데이터 float: 64비트 부동소수점 실수 데이터 |
boolean | boolean | true, false만 값으로 가짐 |
IP 주소 | ip | ipv4, ipv6 타입 IP 주소 |
위치 정보 | geto-point, geo-shape | geo-point: 위도, 경도 값 geo-shape: 하나의 위치 포인트가 아닌 임의의 지형 |
범위 값 | integer_range, long_range, float_range, double_range, ip_range, date_range |
범위를 설정할 수 있는 데이터 integer_range, long_range: 정수형 범위 float_range, double_range: 실수형 범위 ip_range: IP 주소 범위 date_range: 날짜/시간 데이터 범위 |
객체 형 | object | 계층 구조를 갖는 형태 필드 안에 다른 필트가 들어갈 수 있음 |
배열 형 | nested | 배열형 객체 저장 객체를 따로 인덱싱하여 객체가 하나로 합쳐지는(flatten) 것을 막음 배열 내부의 객체에 쿼리로 접근 가능 |
배열 형 | join | 부모/자식 관계 표현 |
- text
- 문장이나 여러 단어가 나열된 문자열은 텍스트 타입으로 지정
- 역인덱스(inverted index): 분석기에 의해 토큰으로 분리된 후 인덱싱됨
- 용어(term): 역인덱스에 저장된 토큰
- 용어는 역인덱스에 저장되어 전문 검색 가능
- 집계나 정렬 지원 X
- keyword
- 범주형 데이터에 주로 사용
- 분석기를 거치지 않고 문자열 전체가 하나의 용어로 인덱싱
- 부분 일치 검색 X
- 완전 일치 검색 사용 가능
- 집계, 정렬 사용 가능
- multi field
- 단일 필드 입력에 대해 여러 하위 필드 정의
fields
매핑 파라미터 사용- 하나의 필드를 여러 용도로 사용 가능
- 아래 예제에서 contensts 필드는 멀티 타입으로 text, keyword 타입을 가짐
// PUT index2 { "mappings": { "properties": { "message": { "type": "text" }, "contents": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } } }
- 사용자가 지정한 명칭인
keyword
를 이용해서 검색 가능
// GET index2/_search { "query" : { "term" : { "contents.keyword" : "hello" } } }
- 키워드 타입은
aggs
이용하여 집계 쿼리 가능
// GET index2/_search { "size": 0, "aggs": { "contents": { "terms": { "field": "contents.keyword" } } } }