아래의 Workshop을 학습과정에서 Mapping을 변경을 수행하고 이를 정리한 것으로, 해당 Workshop와 동일한 데이터를 이용했다.
Workshop Studio
catalog.us-east-1.prod.workshops.aws
Opensearch는 따로 매핑을 정의해 놓지 않으면 데이터가 입력되면서 자동으로 매핑이 생성된다.
(사실, 위의 워크샵을 그대로 잘 따라가면 데이터 저장 전데매핑을 먼저 생성하는데.. 유튜브를 같이 보면서 따라하다가 놓쳐버렸다;;)
아래는 데이터를 저장하니 자동으로 생성된 매핑이다.
GET /aws-blog/_mapping
{
"aws-blog": {
"mappings": {
"properties": {
"author": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"body": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"category": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"date": {
"type": "date"
},
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"url": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
이 상태에서 "author" 필드를 기준으로 aggregation을 수행하려고 하면 아래와 같은 에러가 발생한다.
⚠️ 에러 코드: Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [author] in order to load field data by uninverting the inverted index. Note that this can use significant memory
생성된 매핑을 확인해 보면, author 필드가 “text”로 설정되어 있다. text 타입은 aggregation, sorting은 default로 disable 되어있다. 따라서 author 필드를 keyword로 변경하거나 역색인된 구조를 다시 되돌리도록 fielddata=true 설정을 해야한다.
그러나 fielddata=true 설정은 메모리 사용량이 많아지므로 권장되지 않는다.
이를 해결하기 위해서 인덱스 매핑을 설정하는 방법을 알아보았다!
신규 인덱스의 매핑을 데이터 저장 전에 먼저 입력할 경우
아래 명령을 실행하여 저장 될 데이터의 필드별 타입을 지정해준다.
PUT /aws-blog
{
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"author": {
"type": "keyword"
},
"body": {
"type": "text"
},
"category": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"date": {
"type": "date"
},
"url": {
"type": "keyword"
}
}
}
}
인덱스에 이미 데이터가 존재하는 경우
아래 공식문서에 설명되어 있듯이, 이미 데이터가 있는경우에는 매핑을 변경할 수 없고 새롭게 인덱스를 생성해야 한다.
You can’t use this operation to update mappings that already map to existing data in the index. You must first create a new index with your desired mappings, and then use the reindex API operation to map all the documents from your old index to the new index. If you don’t want any downtime while you re-index your indexes, you can use aliases.
Create or update mappings
Create or update mappings Introduced 1.0
opensearch.org
1. 새로운 인덱스를 생성한다.
위의 인덱스 매핑과 동일하게 PUT 명령을 이용하면 된다. 이때 인덱스의 이름은 변경해준다.
PUT /aws-blog-v2
{
"mappings": {
"properties": {
...(생략)
"author": {
"type": "keyword"
},
...(생략)
}
}
}
2. reindex
reindex 명령을 이용하여 새로 생성된 인덱스에 기존 인덱스의 데이터를 재인덱싱 해준다.
POST _reindex
{
"source":{
"index":"aws-blog"
},
"dest":{
"index":"aws-blog-v2"
}
}
이렇게 되면 새롭게 생성된 "aws-blog-v2" 인덱스는 내가 원하는 필드 타입을 갖게 된다.
하지만, 새로운 인덱스를 쓰게 된다면 기존에 해당 인덱스를 사용하던 어플리케이션에서 변경이 일어나야 한다.
기존의 인덱스명을 유지하기 위해 기존 인덱스를 삭제하고 다시 만들어서 또 다시 reindex 하여 사용 하면 된다...;;
이번 Workshop에서는 데이터가 많지 않고 연습이었으므로 위의 복잡한 방법으로 일단 단계를 넘어갔지만...!
공식 문서에서는 서비스 중단없이 인덱스 매핑을 변경하기 위해서는 aliases(별칭)을 사용하라고 안내한다.
별칭 사용은 유용하게 사용될 것 같고 어렵지 않은 것 같으니 다음에 사용해 보려고 한다!
참고: https://www.elastic.co/kr/blog/changing-mapping-with-zero-downtime