2.X/1. Getting Started

1-06-4. Mapping

drscg 2017. 9. 30. 20:35

In order to be able to treat date fields as dates, numeric fields as numbers, and string fields as full-text or exact-value strings, Elasticsearch needs to know what type of data each field contains. This information is contained in the mapping.

date field를 날짜로, 숫자 field를 숫자로, string field를 full-text나 exact-value 문자열로 처리하기 위해서는, Elasticsearch는 각 field가 가지고 있는 데이터의 type을 알아야 한다. 이 정보는 mapping에 있다.

As explained in Data In, Data Out, each document in an index has a type. Every type has its own mapping, or schema definition. A mapping defines the fields within a type, the datatype for each field, and how the field should be handled by Elasticsearch. A mapping is also used to configure metadata associated with the type.

Data In, Data Out에서 설명했듯이, index에 있는 각 document는 type 을 가지고 있다. 모든 type은 자신만의 mapping 이나 schema definition 을 가지고 있다. mapping은 type 내의 field, 각 field의 데이터 type, Elasticsearch가 그 field를 처리하는 방법을 정의한다. 또한, mapping은 type에 관련된 metadata를 설정하는데 사용된다.

We discuss mappings in detail in Types and Mappings. In this section, we’re going to look at just enough to get you started.

Types and Mappings에서, mapping에 대해 자세히 이야기할 것이다. 여기에서는 기본적인 부분만 살펴보자.

Core Simple Field Typesedit

Elasticsearch supports the following simple field types:

Elasticsearch는 아래의 데이터 type을 지원한다.

  • String: string
  • Whole number: byteshortintegerlong
  • Floating-point: floatdouble
  • Boolean: boolean
  • Date: date

When you index a document that contains a new field—one previously not seen—Elasticsearch will use dynamic mapping to try to guess the field type from the basic datatypes available in JSON, using the following rules:

이전에 발견된 적이 없는, 새로운 field를 가지고 있는 document를 색인할 때, Elasticsearch는 아래의 규칙을 사용해, JSON에서 이용할 수 있는 기본 데이터 type에서, field type을 추측하기 위해 dynamic mapping을 사용한다.

JSON type

Field type

Boolean: true or false

boolean

Whole number: 123

long

Floating point: 123.45

double

String, valid date: 2014-09-15

date

String: foo bar

string

Note

This means that if you index a number in quotes ("123"), it will be mapped as type string, not type long. However, if the field is already mapped as type long, then Elasticsearch will try to convert the string into a long, and throw an exception if it can’t.

따옴표로 둘러싸인 숫자("123")를 색인하면, long type이 아닌 string type이 된다. 그러나, 그 field가 이미 long type으로 mapping 되어 있다면, Elasticsearch는 string을 long으로 변경하려 한다. 바꾸지 못하면 exception이 발생한다.

Viewing the Mappingedit

We can view the mapping that Elasticsearch has for one or more types in one or more indices by using the /_mapping endpoint. At the start of this chapter, we already retrieved the mapping for type tweet in index gb:

마지막에 /_mapping 을 사용하여, Elasticsearch가 가지고 있는 하나 이상의 indices의, 하나 이상의 type의 mapping을 볼 수 있다. 이 장의 초반에서, gb index의 tweet type의 mapping을 가져온 적이 있었다.

GET /gb/_mapping/tweet

This shows us the mapping for the fields (called properties) that Elasticsearch generated dynamically from the documents that we indexed:

색인된 document에서, Elasticsearch가 동적으로 생성한 field(properties 라 불리는)의 mapping을 볼 수 있다.

{
   "gb": {
      "mappings": {
         "tweet": {
            "properties": {
               "date": {
                  "type": "date",
                  "format": "strict_date_optional_time||epoch_millis"
               },
               "name": {
                  "type": "string"
               },
               "tweet": {
                  "type": "string"
               },
               "user_id": {
                  "type": "long"
               }
            }
         }
      }
   }
}
Tip

Incorrect mappings, such as having an age field mapped as type string instead of integer, can produce confusing results to your queries.

integer 가 아닌 string type으로 mapping된 age field처럼, 올바르지 않은 mapping은 query 결과에 혼동을 가져올 수 있다.

Instead of assuming that your mapping is correct, check it!

mapping이 올바르다고 추측하지 말고, 확인하자!

Customizing Field Mappingsedit

While the basic field datatypes are sufficient for many cases, you will often need to customize the mapping for individual fields, especially string fields. Custom mappings allow you to do the following:

대부분, 기본 field 데이터 type으로 충분하지만, 가끔은 개별 field에 대한 mapping을 사용자 정의해야 한다. 특히, string field에 대해서는. 다음과 같은 경우에 사용자 정의 mapping이 필요하다.

  • Distinguish between full-text string fields and exact value string fields

    full-text string field와 exact value string field를 구분해야 하는 경우

  • Use language-specific analyzers

    language-specific analyzer를 사용하는 경우

  • Optimize a field for partial matching

    부분 일치를 위해, field를 최적화하는 경우

  • Specify custom date formats

    사용자 정의 date 형식을 지정하는 경우

  • And much more

    기타

The most important attribute of a field is the type. For fields other than string fields, you will seldom need to map anything other than type:

field의 가장 중요한 속성은 type 이다. string field가 아닌 다른 field의 경우, type 이 아닌 다른 것을 mapping할 필요가 거의 없다.

{
    "number_of_clicks": {
        "type": "integer"
    }
}

Fields of type string are, by default, considered to contain full text. That is, their value will be passed through an analyzer before being indexed, and a full-text query on the field will pass the query string through an analyzer before searching.

기본적으로 string type의 field는 full-text를 포함하고 있다고 가정한다. 즉, 그 값은 색인되기 전에analyzer로 전달되고, 해당 field에 대한 full-text query는 검색하기 전에 query string을 analyzer로 전달한다.

The two most important mapping attributes for string fields are index and analyzer.

string field에서 가장 중요한 mapping 속성 두 가지는 index 와 analyzer 이다.

indexedit

The index attribute controls how the string will be indexed. It can contain one of three values:

index 속성은 string을 색인하는 방법을 제어한다. 3가지 값 중 하나를 포함할 수 있다.

analyzed

First analyze the string and then index it. In other words, index this field as full text.

먼저 string을 분석한다. 그리고 색인한다. 다시 말하면, 이 field를 full-text로 색인한다.

not_analyzed

Index this field, so it is searchable, but index the value exactly as specified. Do not analyze it.

이 field를 색인한다, 따라서 검색 가능하다. 그러나, 지정한 대로 정확한 값을 색인한다. 분석하지 않는다.

no

Don’t index this field at all. This field will not be searchable.

이 field를 색인하지 않는다. 이 field는 검색할 수 없다.

The default value of index for a string field is analyzed. If we want to map the field as an exact value, we need to set it to not_analyzed:

string field의 기본 index 값은 analyzed 이다. field를 exact value로 mapping하려면, not_analyzed 로 설정해야 한다.

{
    "tag": {
        "type":     "string",
        "index":    "not_analyzed"
    }
}
Note

The other simple types (such as longdoubledate etc) also accept the indexparameter, but the only relevant values are no and not_analyzed, as their values are never analyzed.

longdoubledate 같은, 기본 type도 index 매개변수가 있다. 그러나 적절한 값은 절대 분석되지 않는 no 와 not_analyzed 이다.

analyzeredit

For analyzed string fields, use the analyzer attribute to specify which analyzer to apply both at search time and at index time. By default, Elasticsearch uses the standard analyzer, but you can change this by specifying one of the built-in analyzers, such as whitespacesimple, or english:

analyzed string field에서, 검색 시와 색인 시에 적용할 analyzer를 지정하기 위해, analyzer 속성을 사용한다. 기본적으로 Elasticsearch는 standard analyzer를 사용한다. 그러나, whitespacesimpleenglish같은 내장된 analyzer 중의 하나를 지정하여, analyzer를 변경할 수 있다.

{
    "tweet": {
        "type":     "string",
        "analyzer": "english"
    }
}

In Custom Analyzers, we show you how to define and use custom analyzers as well.

Custom Analyzers에서, 사용자 정의 analyzer를 잘 정의하고, 사용하는 방법에 대해 이야기 할 것이다.

Updating a Mappingedit

You can specify the mapping for a type when you first create an index. Alternatively, you can add the mapping for a new type (or update the mapping for an existing type) later, using the /_mappingendpoint.

index를 처음 생성할 때, type에 대한 mapping을 지정할 수 있다. 그렇지 않으면, 마지막에 /_mapping 을 사용하여, 새로운 type에 대한 mapping을 추가 (또는, 기존의 type에 대한 mapping을 업데이트)할 수 있다.

Note

Although you can add to an existing mapping, you can’t change existing field mappings. If a mapping already exists for a field, data from that field has probably been indexed. If you were to change the field mapping, the indexed data would be wrong and would not be properly searchable.

기존의 mapping에 추가 할 수는 있지만, 변경 할 수는 없다. 즉, field에 이미 mapping이 존재한다면, 아마도 해당 field에 데이터가 이미 색인 되었다고 볼 수 있다. field mapping을 변경하면, 이미 색인된 데이터는 오류가 날 것이고, 올바르게 검색할 수 없게 될 것이다.

We can update a mapping to add a new field, but we can’t change an existing field from analyzed to not_analyzed.

새로운 field를 추가할 때, mapping을 업데이트할 수 있다. 그러나 기존 field를 analyzed 에서 not_analyzed 로 변경할 수는 없다.

To demonstrate both ways of specifying mappings, let’s first delete the gb index:

mapping을 지정하는 두 가지 방식을 보여주기 위해, 먼저 gb index를 지우자.

DELETE /gb

Then create a new index, specifying that the tweet field should use the english analyzer:

그리고, 새로운 index를 생성하고, tweet field가 english analyzer를 사용하도록 지정하자.

PUT /gb 
{
  "mappings": {
    "tweet" : {
      "properties" : {
        "tweet" : {
          "type" :    "string",
          "analyzer": "english"
        },
        "date" : {
          "type" :   "date"
        },
        "name" : {
          "type" :   "string"
        },
        "user_id" : {
          "type" :   "long"
        }
      }
    }
  }
}

body에 지정된 mapping 을 가지고, index를 생성한다.

Later on, we decide to add a new not_analyzed text field called tag to the tweet mapping, using the _mapping endpoint:

나중에, 마지막에 _mapping 을 사용하여, tweet mapping에 tag 라는 not_analyzed 텍스트 field를 추가하기로 하였다.

PUT /gb/_mapping/tweet
{
  "properties" : {
    "tag" : {
      "type" :    "string",
      "index":    "not_analyzed"
    }
  }
}

Note that we didn’t need to list all of the existing fields again, as we can’t change them anyway. Our new field has been merged into the existing mapping.

기존의 field는 변경하지 않기 때문에, 기존의 field를 모두 다시 열거할 필요는 없다는 점을 유심히 보자. 새로운 field는 기존의 mapping에 병합된다.

Testing the Mappingedit

You can use the analyze API to test the mapping for string fields by name. Compare the output of these two requests:

string field의 이름으로 mapping을 테스트하기 위해, analyze API를 사용할 수 있다. 아래 두 request의 출력을 비교해 보자.

GET /gb/_analyze
{
  "field": "tweet",
  "text": "Black-cats" 
}

GET /gb/_analyze
{
  "field": "tag",
  "text": "Black-cats" 
}

 

분석하려는 텍스트는 body로 넘겨진다.

The tweet field produces the two terms black and cat, while the tag field produces the single term Black-cats. In other words, our mapping is working correctly.

tweet field는 두 개의 단어 blackcat 을 만들어낸다. 반면에 tag field는 하나의 단어 Black-cat 을 만들어낸다. 다시 말하면, mapping은 정상 작동 중이다.


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

1-06-2. Inverted Index  (0) 2017.09.30
1-06-3. Analysis and Analyzers  (0) 2017.09.30
1-06-5. Complex Core Field Types  (0) 2017.09.30
1-07. Full-Body Search  (0) 2017.09.30
1-07-1. Empty Search  (0) 2017.09.30