ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Elasticsearch] 핵심 개념 - 매핑 타입이 사라지면서 멀티 타입 인덱스를 싱글 타입 인덱스로 마이그래이션
    IT 발자취.../Elastic Stack 2020. 4. 9. 01:26

    https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html#_migrating_multi_type_indices_to_single_type

     

    Removal of mapping types | Elasticsearch Reference [7.6] | Elastic

    Indices created in Elasticsearch 7.0.0 or later no longer accept a _default_ mapping. Indices created in 6.x will continue to function as before in Elasticsearch 6.x. Types are deprecated in APIs in 7.0, with breaking changes to the index creation, put map

    www.elastic.co

    직역을 하여 ... 본문을 보는게 더 도움이 될 수도 있습니다.

    Migrating multi-type indices to single-type

     

    ReindexAPI는 멀티 타입 인덱스에서 싱글타입 인덱스로 변환할 경우 사용된다.

    아래는 Elasticsearch 5.6 또는 Elasticsearch 6.x 버전의 예시이다.

    6.x 버전에는 index.mapping.single_type 을 기본으로 명시할 필요가 없다.

     

    도큐먼트 타입 별 인덱스

    첫째 예제는 twitter 인덱스를 tweets인덱스와 users 인덱스로  나눔

    1. 첫번째 예시

    더보기

    5.6 버전 이전의 twitter 인덱스

    ## 5.6 버전 이전의 twitter 인덱스
    PUT twitter
    {
      "mappings": {
        "user": {
          "properties": {
            "name": { "type": "text" },
            "user_name": {"type":"keyword"},
            "email" : {"type":"keyworkd"}
          }
        },
        "tweet": {
          "properties": {
            "content" : {"type":"text"},
            "user_name" : {"type":"keyword"},
            "twetted_at" : {"type":"date"},
          }
        }
      }
    }
      
    PUT twitter/user/kimchy
    {
      "name" : "Shay Banon",
      "user_name" : "kimchy",
      "email": "shay@kimchy.com"
    }
      
    PUT twitter/tweet/1
    {
      "user_name": "kimchy",
      "tweeted_at" : "2017-10-24T09:00:00Z",
      "content":"Types are going away"
    }

    변경 후 인덱스

    ## 변경 후 인덱스
    PUT users
    {
      "settings": {
        "index.mapping.single_type": true
      },
      "mappings": {
      "_doc": {
        "properties": {
          "name": {
            "type": "text"
            },
            "user_name": {
              "type": "keyword"
            },
            "email": {
              "type": "keyword"
            }
          }
        }
      }
    }
     
    PUT tweets
    {
      "settings": {
        "index.mapping.single_type": true
      },
      "mappings": {
        "_doc": {
          "properties": {
            "content": {
              "type": "text"
            },
            "user_name": {
              "type": "keyword"
            },
            "tweeted_at": {
              "type": "date"
            }
          }
        }
      }
    }
     
    POST _reindex
    {
      "source": {
        "index": "twitter",
        "type": "user"
      },
      "dest": {
        "index": "users",
        "type": "_doc"
      }
    }
     
    POST _reindex
    {
      "source": {
        "index": "twitter",
        "type": "tweet"
      },
      "dest": {
        "index": "tweets",
        "type": "_doc"
      }
    }

     

    Custom type field

    두번째 예시는 custom type field를 추가하고 원래의 _type 값에 설정해준다.

    ID 충돌이 있는 다른 타입의 어느 도큐먼트가 있는 경우 _id 에 타입을 추가해준다.

    더보기

    custom type

    PUT new_twitter
    {
      "mappings": {
        "_doc": {
          "properties": {
            "type": {
              "type": "keyword"
            },
            "name": {
              "type": "text"
            },
            "user_name": {
              "type": "keyword"
            },
            "email": {
              "type": "keyword"
            },
            "content": {
              "type": "text"
            },
            "tweeted_at": {
              "type": "date
            }
          }
        }
      }
    }
    POST _reindex
    {
      "source": {
        "index": "twitter"
      },
      "dest": {
        "index": "new_twitter"
      },
      "script": {
        "source": """
          ctx._source.type = ctx._type;
          ctx._id = ctx._type + '-' + ctx._id;
          ctx._type = '_doc";
      }
    }

    7.0 에서 Typeless APIs

    Elasticsearch 7.0에서 각 API는 typeless 요청을 지원하고, 타입을 명시하는것에 deprecation warning을 제공한다.

    Typeless APIs는 타겟 인덱스가 커스텀 필드를 포함하더라도 동작한다.

    예를 들면, 만약 인덱스가 my_type 이라는 커스텀 타입명을 가진다.

    typeless index 콜을 이용하여 도큐먼트를 추가할 수 있고, typeless get 콜을 이용하여 도큐먼트를 불러올수 있다. 

     

    Index APIs

    인덱스 생성, 인덱스 탬플릿, 그리고 패밍 APIs는 request와 reponse가 타입명을 반드시 포함해야만 하는지 여부를 명시하는 새로운 include_type_name URI 파라미터를 지원한다.

    파라미터는 기본적으로 6.8버전 부터 매핑에 타입명을 사용하는 7 초기 버전까지는 true이다.

    7.0에서는 include_type_name의 기본값이  false이고 8.0버전에서는 사라진다.

     

    7.0 버전으로 업그레이드를 위하여 6.8 버전에서 이 값을 명시적으로 나타내었다.

    6.8 버전에서 deprecation warning을 피하기위해서는 true 또는 false값으로 설정해야만다.

    7.0에서 include_type_name 설정을 하면 deprecation warning 메시지가 뜬다.

     

    엘라스틱서치와 이 옵션 false로 설정했을 때 상호작용에 대한 예제를 보자.

    include_type_name

    PUT index?include_type_name=false
    {
      "mappings": {
        "properties": {
          "foo": {
            "type": "keyword"
          }
        }
      }
    }

    - 4번째 라인에서, 타입명이 없이, mappings key 아래에 직접적으로 매핑은 포함된다.

     

     

    include_type_name

    PUT index/_mappings?include_type_name=false
    {
      "properties": {
        "bar": {
          "type": "text"
        }
      }
    }

    - 3번 라인에서, 타입명이 없이 mappings key 아래에 직접적으로 매핑이 포함된다.

     

    GET index/_mappings?include_type_name=false
    {
      "index": {
        "mappings": {
          "properties: {
            "foo": {
              "type": "keyword"
            },
            "bar": {
              "type": "text"
            }
          }
        }
      }
    }

    - 4번째 라인을 보면 타입명이 없이 mappings key 아래에 직접적으로 매핑이 포함된다.

     

    Document API

    7.0에서 인덱스 APIs는 _id 자동 생성을 위한 {index}/_doc 경로와 명시적인 ID를 가진 {index}/_doc/{id}와 함께 호출을 해야만 한다.

    PUT index/_doc/1
    {
      "foo": "baz"
    }
    GET index/_doc/1
    {
      "_index": "index",
      "_id": "1",
      "_type": "_doc",
      "_version": 1,
      "result": "created",
      "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
      },
      "_seq_no": 0,
      "_primary_term": 1
    }

    - 비슷하게, get과 delete API도 \{index}/_doc/\{id} 경로를 사용한다.

     

    7.0 버전에서 _doc는 도큐먼트 타입 대신 엔드 포인트명을 표시한다.

    _doc 컴포넌트는 앞으로 도큐먼트 index, get, delete APIs 경로의 영구적인 부분이며 8.0에서도 제거되지 않았다.

     

    타입과 _update와 같은 엔드포인트 명, 둘 다 가진 API 경로에서는 7.0 버전에서 엔드포인트가 index 명 다음에 바로 나타난다.

     

    POST index/_update/1
    {
      "doc": {
        "foo": "qux"
      }
    }
     
    GET /index/_source/1

    타입은 요청의 body에 더이상 존재하면 안된다. 다음의 대량 색인 생성 예제는 URL과 개별 대량 명령 모두에서 타입이 생략된다.

     

    BUILK 예제

    POST _bulk
    { "index" : { "_index" : "index", "_id" : "3" }}
    { "foo" : "baz" }
    { "index" : { "_index" : "index", "_id" : "4" }}
    { "foo" : "qux" }

    검색 API

    _search, _msearch, _explain과 같은 검색 API를 사용할 때, 타입이 URL에 포함되어서는 안된다.

    추가적으로, _type 필드는 쿼리, 집계 또는 스크립트에서 사용해서는 안된다.

    응답에서 타입

    도큐먼트와 검색 APIs는 응답에서 응답 파싱의 깨짐을 방지하기 위하여 _type키를 계속해서 반환할 것이다. 

    하지만 타입 키는 더 이상 사용하지 않는것으로 간주되고, 더 이상 참조되지 않는다.

    8.0 버전의 응답에서는 타입이 완전히 삭제 되었다.

    더 이상 deprecated typed API가 사용된다면, 인덱스의 매핑 타입은 평소와 같게 반환을 할 것이다.

    하지만, typeless APIs를 사용한다면, 응답에 더미 타입인 _doc을 반환할 것이다.

    예를 들면, 아래 typeless get 호출은 항상 타입값으로 _doc을 반환한다. 

    또한 매핑이 my_type과 같은 커스텀 타입 명을 가지더라도 _doc을 반환한다.

    PUT index/my_type/1
    {
      "foo": "baz"
    }
     
    GET index/_doc/1
    {
      "_index" : "index",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 1,
      "_seq_no" : 0,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {
        "foo" : "baz"
      }
    }

    인덱스 템플릿

    include_type_name을 false로 설정하여 인덱스 템플릿을 다시 추가하여 익덱스 템플릿을 typeless로 만다는 것을 추천한다.

    아무도 모르게 (under the hood) typeless 템플릿은 인덱스를 만들 때 더미 타입 _doc을 사용한다.

    댓글

Designed by Gintire