2.X/1. Getting Started

1-10-06. Types and Mappings

drscg 2017. 9. 30. 17:16

type in Elasticsearch represents a class of similar documents. A type consists of a name—such as user or blogpost—and a mapping. The mapping, like a database schema, describes the fields or properties that documents of that type may have, the datatype of each field—such as string,integer, or date—and how those fields should be indexed and stored by Lucene.

Elasticsearch에서 type 은 유사한 document의 집합이다. type은 user 나 blogpost 같은 name 과, mapping 으로 구성되어 있다. database schema처럼, mapping은 해당 type이 가지고 있는, document의 field나 property각 field의 데이터 type(stringintegerdate 등) 그리고, 해당 field가 Lucene에 색인 되고 저장되는 방법을 나타낸다.

Types can be useful abstractions for partitioning similar-but-not-identical data. But due to how Lucene operates they come with some restrictions.

type은 동일하지는 않지만 유사한 데이터를 구분하기 위한 추상화에 유용할 수 있다. 그러나, Lucene의 동작 방식으로 인해 몇 가지 제한 사항을 가진다.

How Lucene Sees Documentsedit

A document in Lucene consists of a simple list of field-value pairs. A field must have at least one value, but any field can contain multiple values. Similarly, a single string value may be converted into multiple values by the analysis process. Lucene doesn’t care if the values are strings or numbers or dates—all values are just treated as opaque bytes.

Lucene에서 document는 field-value 쌍의 단순한 목록으로 구성되어 있다. field는 최소한 하나 이상의 값을 가져야 하나, 어떤 field는 다중 값도 포함할 수 있다. 유사하게, 단일 문자열 값은 분석 과정에서, 다중 값으로 바뀔 수 있다. Lucene은 값이 string이든 number이든 date이든 관계없이, 모든 값을 이해하기 힘든(opaque) byte 로만 다룬다.

When we index a document in Lucene, the values for each field are added to the inverted index for the associated field. Optionally, the original values may also be stored unchanged so that they can be retrieved later.

Lucene에 document를 색인할 때, 각 field의 값은, 관련된 field에 대해, inverted index에 추가된다. 선택적으로, 원래의 값을 나중에 가져올 수 있도록, 그대로 저장될 수도 있다.

How Types Are Implementededit

Elasticsearch types are implemented on top of this simple foundation. An index may have several types, and documents of any of these types may be stored in the same index.

Elasticsearch의 type은 이러한 간단한 기반 위에 구현된다. index는 여러 가지 type을 가질 수 있고, 해당 type의 모든 document는 동일한 index에 저장된다.

Because Lucene has no concept of document types, the type name of each document is stored with the document in a metadata field called _type. When we search for documents of a particular type, Elasticsearch simply uses a filter on the _type field to restrict results to documents of that type.

Lucene은 document의 type에 대한 개념이 없기 때문에, 각 document의 type 이름은, _type 이라는 metadata field에, document와 함께 저장된다. 특정 type의 document를 검색할 때, Elasticsearch는, 해당 type의 document로 결과를 제한하기 위해, _type field에 대해 단순하게 filter를 사용한다.

Lucene also has no concept of mappings. Mappings are the layer that Elasticsearch uses to mapcomplex JSON documents into the simple flat documents that Lucene expects to receive.

Lucene은 또한 mapping의 개념이 없다. mapping은, Elasticsearch가 복잡한 JSON document를 Lucene이 받을 수 있는, 단순한 평면 document로 mappting하기 위해, 사용하는 계층이다.

For instance, the mapping for the name field in the user type may declare that the field is a stringfield, and that its value should be analyzed by the whitespace analyzer before being indexed into the inverted index called name:

예를 들면, user type에 name field를 mapping하는 것은, field가 string field이고, name 이라는 inverted index에 색인되기 전에, whitespace analyzer로 field의 값을 분석한다는 것을 선언하는 것이다.

"name": {
    "type":     "string",
    "analyzer": "whitespace"
}

Avoiding Type Gotchasedit

This leads to an interesting thought experiment: what happens if you have two different types, each with an identically named field but mapped differently (e.g. one is a string, the other is a number)?

이것은 흥미로운 의문을 가지게 한다. 2개의 다른 type을 가지고 있는데 각각이 동일한 이름을 가진 field가 다르게 mapping되어 있다면(예: 하나는 string, 다른 것은 number) 어떤 일이 발생할까?

Well, the short answer is that bad things happen and Elasticsearch won’t allow you to define this mapping at all. You’d receive an exception when attempting to configure the mapping.

간단히 대답해 보면, elasticsearch는 이런 mapping을 허용하지 않는다는 것이다. 이 mapping을 설정하려 하면 exception이 발생할 것이다.

The longer answer is that each Lucene index contains a single, flat schema for all fields. A particular field is either mapped as a string, or a number, but not both. And because types are a mechanism added by Elasticsearch on top of Lucene (in the form of a metadata _type field), all types in Elasticsearch ultimately share the same mapping.

자세히 대답해 보면, 각 Lucene의 index는 모든 field에 대해 하나의 평평한(flat) schema를 가진다는 것이다. 특정 field는 string이나 number이거나 둘다 아니다. 그리고, type은 Lucene 위에 elasticsearch에 의해 추가된 메커니즘(메타데이터 type field의 형태로)이기 때문에, elasticsearch의 모든 type은 궁극적으로 동일한 mapping을 공유한다.

Take for example this mapping of two types in the data index:

data index에 2가지 type의 mapping의 예를 살펴보자.

{
   "data": {
      "mappings": {
         "people": {
            "properties": {
               "name": {
                  "type": "string",
               },
               "address": {
                  "type": "string"
               }
            }
         },
         "transactions": {
            "properties": {
               "timestamp": {
                  "type": "date",
                  "format": "strict_date_optional_time"
               },
               "message": {
                  "type": "string"
               }
            }
         }
      }
   }
}

Each type defines two fields ("name"/"address" and "timestamp"/"message" respectively). It may look like they are independent, but under the covers Lucene will create a single mapping which would look something like this:

각 type은 2개의 field를 정의한다(각각 "name"/"address" 와 "timestamp"/"message") 그것들은 독립적인 것처럼 보이지만, Lucene 내부에서는 아래에 보이는 것처럼 단일 mapping으로 생성될 것이다.

{
   "data": {
      "mappings": {
        "_type": {
          "type": "string",
          "index": "not_analyzed"
        },
        "name": {
          "type": "string"
        }
        "address": {
          "type": "string"
        }
        "timestamp": {
          "type": "long"
        }
        "message": {
          "type": "string"
        }
      }
   }
}
Note

This is not actually valid mapping syntax, just used for demonstration

이것은 실제로 올바른 mapping 문법이 아니다. 단지 테스트를 위해 사용했다.

The mappings are essentially flattened into a single, global schema for the entire index. And that’s why two types cannot define conflicting fields: Lucene wouldn’t know what to do when the mappings are flattened together.

mapping은 기본적으로 전체 index에 대해 하나의 전역적인 schema로 평평하다(flat). 그리고, 그것이 2개의 type이 충돌이 나는 field를 정의할 수 없는 이유이다. mapping이 모두 평평한 경우 lucene이 어떻게 동작할지 알 수 없다.

Type Takeawaysedit

So what’s the takeaway from this discussion? Technically, multiple types may live in the same index as long as their fields do not conflict (either because the fields are mutually exclusive, or because they share identical fields).

그렇다면, 이 토론의 핵심은 무엇인가? 기술적으로, 다수의 type은 그들의 field가 충돌하지 않는 한 동일한 index에 존재할 수 있다.(field가 상호 배타적이거나 동일한 field를 공유하기 때문에)

Practically though, the important lesson is this: types are useful when you need to discriminate between different segments of a single collection. The overall "shape" of the data is identical (or nearly so) between the different segments.

실질적으로 중요한 것은 이것이다. type은 단일 collection의 다른 segment를 구분해야 하는 경우 유용하다. 다른 segment간에 데이터의 전체적인 "형태" 는 (거의) 동일하다.

Types are not as well suited for entirely different types of data. If your two types have mutually exclusive sets of fields, that means half your index is going to contain "empty" values (the fields will be sparse), which will eventually cause performance problems. In these cases, it’s much better to utilize two independent indices.

type은 전혀 다른 형태의 데이터 에는 적합하지 않다. 상호 배터적인 field 집합을 가진 2개의 type이 있다는 것은, index의 절반이 "빈(empty)" 값을 가진다는 것을 의미한다(field는 드물다). 결국 성능 문제가 발생할 것이다. 이 경우에는, 2개의 독립적인 inddex를 활용하는 것이 훨씬 더 났다.

In summary:

  • Good: kitchen and lawn-care types inside the products index, because the two types are essentially the same schema.

    products index내의 kitchen 과 lawn-care type, 2 type이 본질적으로 동일한 schema이기 때문에,

  • Bad: products and logs types inside the data index, because the two types are mutually exclusive. Separate these into their own indices.

    data index내의 products 와 logs type, 2 type이 상호배타적이기 때문에, 그들 자신의 index를 가지도록 분리한다.


'2.X > 1. Getting Started' 카테고리의 다른 글

1-10-04. Configuring Analyzers  (0) 2017.09.30
1-10-05. Custom Analyzers  (0) 2017.09.30
1-10-07. The Root Object  (0) 2017.09.30
1-10-08. Dynamic Mapping  (0) 2017.09.30
1-10-09. Customizing Dynamic Mapping  (0) 2017.09.30