🌿매핑 (Mapping)
PUT <인덱스명>
{
"mapping": {
"properties": {
"<필드명>": {
"type": "<필드 타입>",
<추가설정>
}
}
}
}
위의 방법으로 인덱스에 대한 매핑을 적용할 수 있다. 이때, 한 번 만들어진 매핑은 수정이 불가능하다.
필드명을 중복하면 똑같은 이름의 컬럼을 만드는 것이 되기 때문에 중복될 수 없다.
매핑 정보를 수정해야 한다면 인덱스를 삭제하고 다시 인덱스를 생성하는 것을 권장한다.
기본 설정
$ sudo systemctl start 패키지명
$ sudo systemctl stop 패키지명
$ sudo systemctl status 패키지명
$ sudo systemctl restart 패키지명
- http://localhost:9200 > elasticsearch
- http://localhost:5601 > kibana
ubuntu를 실행하여 elasticsearch와 kibana를 실행하도록 하자.
elasticsearch kibana를 사용하기 위한 기본 설정은 위 글을 참고한다.
데이터 색인 (Index)
- 직접 매핑
- 동적 매핑(비권장)
인덱스에 매핑(스키마, 저장 구조(규칙))을 하는 작업을 하게 된다고 했다.
mapping 확인하기
GET address/_mapping
어떤 형태로 매핑되어 있는지 확인할 때에는 mapping을 사용한다.
이때 properties 안에 있는 것들이 DB로 치면 컬럼 하나를 의미한다.
- 숫자 > long
- 문자형 > text, keyword
동적 매핑은 첫 도큐먼트를 생성할 때 실제 데이터에 따라서 자료형을 '적당히' 적용한다. 그래서 숫자 데이터가 들어간다고 판단이 되면 대부분 long형으로, 문자형 데이터가 들어가면 text, keyword로 설정된다.
🌿엘라스틱서치 자료형
앞서 엘라스틱서치는 자바로 만들었다고 했다. 그래서 JDK, JRE가 돌아가는 프로그램이다.
그러다 보니까 엘라스틱서치의 자료형은 자바와 거의 동일하다.
문자열
string- text
- keyword
문자열 자료형으로 string은 폐기되었고, text와 keyword를 사용한다.
text
- ex) "배고픈 아이작" > "배고픈", "아이작"
풀 텍스트 검색을 할 대상을 text 자료형으로 선언한다.
입력된 데이터를 텀 단위로 쪼개서 역 색인 구조를 만들게 된다.
엘라스틱서치는 토크나이저가 공백으로 데이터를 조각내서 저장을 하는데, text 자료형은 어디 도큐먼트에 들어가 있는지 저장하는 구조인 역 색인 구조로 저장한다.
무조건 색인 구조로 만드는 게 엘라스틱서치의 업무가 아니고, 일부 자료형이 하는 업무이다. 따라서 검색에 대한 혜택을 받고 싶다면 text 자료형으로 생성해야 한다.
동적 매핑을 하면 text로 저장된다.
# 동적 매핑
PUT my_type1
GET my_type1/_mapping
PUT my_type1/_doc/1
{
"txt1": "배고픈 아이작",
"txt2": "배부른 소피아"
}
동적 매핑은 첫 도큐먼트가 삽입될 때 생성된다. 이때 데이터가 문자열인 경우 text로 매핑된다.
keyword
- ex) "배부른 소피아" > "배부른 소피아"
입력된 데이터를 쪼개지 않고, 통째로 하나의 토큰으로 저장한다.
일반적인 문자열이 아닌 고정적인 문자열에 대해 적용된다.
짧던 길던 하나의 데이터로 생각하고 통째로 저장하고 검색할 때도 통째로 검색해야 하는 구조이다.
쪼개서 검색하지 않을 때, 예로 들어 고객센터에서의 사람 이름을 검색하는 경우에는 keyword를 사용한다. keyword는 검색에 별도의 처리를 하지 않기 때문에 훨씬 빠르다.
keyword는 검색 용도로 사용되지 않는다.
# 직접 매핑
PUT my_type2
{
"mappings": {
"properties": {
"txt1": {
"type": "text"
},
"txt2": {
"type": "keyword"
}
}
}
}
GET my_type2/_mapping
PUT my_type2/_doc/1
{
"txt1": "배고픈 아이작",
"txt2": "배부른 소피아"
}
GET my_type2/_search
{
"query": {
"match": {
"txt1": "배부른"
}
}
}
데이터를 넣기도 전에 어떤 데이터가 들어갈지 구성해 놓고, 그 구성에 맞게 데이터가 들어가도록 직접 매핑을 했다.
"배고픈 아이작"은 text로 저장되고, "배부른 소피아"는 keyword로 저장된다. 이 결과는 검색할 때 드러난다.
"배부른" 또는 "소피아"로 검색하면 검색이 되지 않는다. 따라서 keyword는 검색용으로 저장하는 타입이 아니며, 통계 자료를 만들어서 집계 결과를 낼 때 사용한다.
결론적으로 일반적인 검색을 할 때에는 text를 사용하며, 아주 가끔씩 group by를 해야 할 때 keyword를 사용하게 된다.
숫자형
- long
- integer
- short
- byte
- double
- float (32bit)
- half_float (16bit)
자료형의 특성은 자바와 완전히 똑같다.
추가적으로 32bit인 float에서 파생된 16bit인 half_float가 있다.
동적 매핑에 주의할 점
PUT my_type3
PUT my_type3/_doc/1
{
"name": "Isaac",
"height": "171",
"weight": 58
}
GET my_type3/_mapping
키는 문자열 표현으로, 몸무게는 숫자형 표현으로 데이터를 넣었다.
이후 매핑 정보를 확인해 보면 height는 text, weight는 long으로 데이터가 들어간 것을 확인할 수 있다.
숫자는 범위 비교를 하게 되는데, 문자열은 숫자 비교를 할 수 없으므로 문제가 된다.
눈에 보이는 데이터는 제대로 들어갔다고 생각되는데, 실제로는 그렇지 않는 경우가 있기 때문에 조심해야 한다!
실수형으로 데이터 저장
PUT my_type3/_doc/2
{
"name": "Curry",
"height": "195",
"weight": 81,
"age": 27.5
}
GET my_type3/_mapping
만약 실수형으로 데이터를 저장하는 경우 float로 매핑이 된다.
큰따옴표에 현혹되지 않는다.
PUT my_type4/_doc/1
{
"name": "Isaac",
"age": "24",
"height": "171.1"
}
PUT my_type4/_doc/2
{
"name": "Curry",
"age": "27",
"height": "195.3"
}
GET my_type4/_search
정적 매핑으로 데이터를 넣으면 문자열로 데이터를 넣더라도 알아서 데이터가 매핑 데이터에 따라서 데이터가 저장된다.
또한 search로 검색 결과를 출력할 때 큰따옴표("") 안에 있어서 문자열로 오해하는 경우도 있는데, 이미 매핑 구조를 생성한 상태이기 때문에 큰따옴표는 없다고 생각하면 된다.
날짜
- date
- ISO8601 형식으로 표현
- 2023-12-25
- 2023-12-25T09:47:46
- 2023-12-25T09:47:46+09:00
ISO8601 표기법은 "2023-12-25T09:47:46"라고 표기하는 국제 표기법이다. 이때 T는 Time을 의미한다.
이외에도 "2023-12-25", "2023-12-25T09:47:46+09:00"와 같이 표기하는 표기법도 있다.
ISO8601과 동일한 방식으로 저장
PUT my_type5/_doc/1
{
"regdate": "2023-12-25"
}
PUT my_type5/_doc/1
{
"regdate": "2023/12/25"
}
PUT my_type5/_doc/1
{
"regdate": "2023.12.25"
}
GET my_type5/_doc/1
GET my_type5/_mapping
동적 매핑을 했을 때 표현이 우연히 ISO8601과 동일하여 date로 저장되었다. slash로 저장하더라도 date로 매핑되도록 설정되어 있다.
하지만 '.'으로 구분하여 저장했을 때에는 문자열 keyword로 저장되므로, 데이터를 넣을 때에는 반드시 매핑 정보를 확인하도록 한다.
format 옵션
PUT my_type6
{
"mappings": {
"properties": {
"regdate": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy/MM/dd||epoch_millis||yyyy년MM월dd일"
}
}
}
}
PUT my_type6/_doc/1
{
"regdate": "2023-12-25 09:00:00"
}
PUT my_type6/_doc/2
{
"regdate": "2023/12/25"
}
PUT my_type6/_doc/3
{
"regdate": 1703466606
}
PUT my_type6/_doc/4
{
"regdate": "2023년12월25일"
}
GET my_type6/_search
추가옵션으로 format을 지정하여 어떤 형태로 데이터를 저장할지 지정할 수 있다.
여기에 OR 연산자를 이용하여 다양하게 넣을 수 있으며, epoch_millis값으로도 넣을 수 있다.
엘라스틱 서치는 어떤 형식으로 저장하던지 내부적으로는 무조건 epock_millis 형식으로 저장한다.
🍃비교 연산자
- > : gt
- < : lt
- > : gte
- < : lte
GET my_type6/_search
{
"query": {
"range": {
"regdate": {
"gte": "2023-12-24 12:00:00",
"lte": "2023-12-26 23:30:50"
}
}
}
}
GET member/_search
{
"query": {
"range": {
"age": {
"gte": 40
}
}
}
}
비교 검색을 할 때에 비교 연산자는 위와 같이 문자와 대치하여 사용한다.
Geo Point
Geo Point는 위도, 경도를 저장하는 자료형이다.
geo_point
PUT my_type7/_doc/1
{
"location": {
"lat": 32.12,
"lon": 132.13
}
}
GET my_type7/_mapping
DELETE my_type7
PUT my_type7
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
GET my_type7/_mapping
동적 매핑을 하면 실수형으로 저장되기 때문에 반드시 geo_point 자료형으로 정적 매핑을 해야 한다.
🌿키바나 시각화 작업
Stack Management
Index Management
Index Pattern
키바나와 연동할 인덱스 이름을 적어준다.
Timestamp field는 시간 데이터가 있을 때 해당 필드를 기준점으로 할 수 있다.
이제 키바나로 시각화 작업을 할 수 있다.
Discover
기본적으로 Discover는 데이터를 보여주는 그림이라고 생각하면 된다.
Filter for value
필드를 필터로 추가하여 검색을 상세하게 할 수 있다.
Visualize Library
차트의 종류를 선택해야 한다.
지도 차트를 만들 것이므로 Maps를 클릭한다.
Add layer
무조건 표현이 되는 건 아니고, 레이어 형식으로 추가를 하게 된다.
Documents를 클릭하고, 등록한 address를 클릭한다.
그런데 지도 표현을 할 수 있는 포인트 좌표가 없다는 오류가 발생한다. 이는 address의 매핑을 geo point로 하지 않고 float로 했기 때문에 발생하는 문제이다.
좌표는 반드시 geo point로 저장해야 하기 때문에 실수형으로 저장하면 사용할 수가 없다. 또한, 한 번 만든 매핑 정보는 수정할 수 없기 때문에 address를 지우고 매핑을 한 다음에 다시 데이터를 넣어야 한다.
서울시 역사마스터 정보
파일 저장
CSV 내려받기로 데이터를 받아온다.
파일 추가
인코딩 설정을 UTF-8로 변경해 준 뒤에 upload a file로 파일을 추가해준다.
파일 Import
하지만 현재 데이터로는 geo data로 인식하지 못하기 때문에 인덱스 매핑을 해 주어야 한다.
인덱스 매핑
DELETE subway
PUT subway
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"name": {
"type": "keyword"
},
"line": {
"type": "keyword"
},
"location": {
"type": "geo_point"
}
}
}
}
override settings
lat과 lon은 예약어이므로 이름만 지정해 주면 엘라스틱서치에서 좌표값으로 인식한다.
lat, lon => location 메시지가 뜬다.
이제 Import를 하고 Maps로 간다.
Fill color
색상을 By value로 line으로 지정해 주면 호선에 따라서 색이 바뀐다.
Label
Label을 By value로 line으로 하면 호선이 적힌다.
Add Filter
Filter를 추가하여 동적으로 차트를 생성할 수 있다.