iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 13
0

Day 13 Mapping


前言

這幾天我們陸續將,cluster、index、document,做一些簡單的介紹,以及實際操作。今天我們要來提到一個也是非常重要的概念-Mapping,這部份大家可以想像成是data type的感覺,因此這個會跟index以及document有關。

What is Mapping

首先我們參考一下Elasticsearch官網文件中對於mapping的定義:

Mapping is the process of defining how a document, and the fields it contains, are stored and indexed. For instance, use mappings to define:

  • which string fields should be treated as full text fields.
  • which fields contain numbers, dates, or geolocations.
  • the format of date values.
  • custom rules to control the mapping for dynamically added fields.

可以看得出來,其實mapping,就是在協助index資料裡面,_source中json不同field的類型,協助index field裡面會出現的資料。

Mapping與data type關係?

大家可以想像mapping其實就是將data type對應到field的方式,假設今天有一個index-test,裡面大致上是存放人的資料,包含name、age、job......

我們可以先設定一些固定欄位的mapping,例如將name設為text,age設為integer,這樣當我把document餵進index時,他就會自動去mapping這些field。

這時候你一定會想說,如果有一些欄位我沒定義過,那有辦法把他加入index中嗎?答案是可以的,他有支援dynamic mapping,因此若從來沒出現的field,他會自動先加入固定的mapping data type。

接著我們來查看一下之前建立的demo-index中mapping的設定

GET /demo-index/_mapping
response:
{
    "demo-index": {
        "mappings": {
            "properties": {
                "age": {
                    "type": "long"
                },
                "email": {
                    "type": "keyword"
                },
                "field1": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "field2": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "job": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "s": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
}

可以看到當初沒有特別設置mapping,新增資料時,這些欄位被加入datatype:keyword。

這邊複習一下,如果在建構index時,想要加入mapping設定,可以透過以下指令:

PUT /demo-index
{
  "mappings": {
    "properties": {
      "age":    { "type": "integer" },  
      "email":  { "type": "keyword"  }, 
      "name":   { "type": "text"  }     
    }
  }
}

另外也可以針對既有的index,加入新的mapping:

PUT /demo-index/_mapping
{
  "properties": {
    "employee-id": {
      "type": "keyword",
      "index": false
    }
  }
}

當然若所有的新field,都被自動加入預設mapping,這可能會導致記憶體不足,所以可以透過設置讓index的mapping有上限。

index.mapping.total_fields.limit

補充一下,如果是要看特定field的mapping,可以透過以下指令:

GET /demo-index/_mapping/field/email

關於data type,影響後面的查詢以及視覺化,可以參考我負責講述視覺化隊友的:
Day[-27] 在開始ELK之前我想分享一下Elasticsearch Data Type
及其他的文章

另外關於Datatype,可以參考:

Elasticsearch Datatype

不同的Datatype會影響查詢,以及欄位上的一些設定

Dynamic field mapping

擷取Elasticsearch中,對於dynamic field mapping的說明:

By default, when a previously unseen field is found in a document, Elasticsearch will add the new field to the type mapping. This behaviour can be disabled, both at the document and at the object level, by setting the dynamic parameter to false (to ignore new fields) or to strict (to throw an exception if an unknown field is encountered).

除了會自動幫新的沒看過欄位,增加預設的datatype外,dynamic field mapping,還會針對這些field的document值去偵測,看他可能屬於什麼datatype,例如如果是日期格式,或是數字,他就可能會給他date, integer

這邊做一個測試,我們在demo-index中加入隨便一個document,其中包含新的欄位, date_time,接著我們再檢視他的mapping。

PUT demo-index/_doc/5
{
  "date_time": "2015/09/02"
}

GET demo-index/_mapping 
{
    "demo-index": {
        "mappings": {
            "properties": {
                "age": {
                    "type": "long"
                },
                "date_time": {
                    "type": "date",
                    "format": "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
                },
                "email": {
                    "type": "keyword"
                },
                "field1": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "field2": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "job": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "s": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
}

當然也可以把這個功能關掉,避免自動去偵測datatype

PUT demo-index
{
  "mappings": {
    "date_detection": false
  }
}

也可以客製化dynamic mapping的format

PUT demo-index
{
  "mappings": {
    "dynamic_date_formats": ["MM/dd/yyyy"]
  }
}

上一篇
Day 12 Bulk upload document
下一篇
Day 14 Index Template And DataStream
系列文
親愛的,我把ElasticSearch上雲了30

尚未有邦友留言

立即登入留言