Elasticsearch 的映射 (mapping)
有別於其他DB, elasticsearch 在使用時不用預先定義每個欄位的資料型態.
使用上雖然方便, 但也不是每次都那麼準確. 請看下面例子.
curl -XPOST "http://127.0.0.1:9200/myindex/doc?pretty" -d '{
"name": "John",
"age": 30
}'
{
"_index" : "myindex",
"_type" : "doc",
"_id" : "AWMcg0UmWZXbD_Pu65Ay",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
curl "http://127.0.0.1:9200/myindex/_mapping?pretty"
{
"myindex" : {
"mappings" : {
"doc" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
}
上面的示範中, 我們新增一筆資料
{ "name": "John", "age": 30 }
其中name, 被識別為text
, 並且自帶出一個keyword
欄位
age 被識別為long
, 到目前為止, 都還算是妥妥的.
上面映射帶給你的效果
-
text
: 可以用作通配符搜索
curl "127.0.0.1:9200/myindex/_search?q=name:Joh*"
-
keyword
: 一定要完全匹配才算命中 -
long
: 可以做數字的聚合搜索, 或是範圍搜索
curl -g '127.0.0.1:9200/myindex/_search?q=age:[20+TO+40]' | jq .
不過當如果遇到資料映射錯誤會發生什麼事呢?
輕則無法做聚合查詢, 搜尋不到; 重則資料無法寫入!
換句話說; 我們就可以明白, 當今天想搜尋3x歲的人的時候, 使用3x
這種
搜尋是行不通的哦~
那我要怎麼定義自己的資料型態?
從上面的範例可以看到, 查詢映射的指令是 _mapping
, 不過其實你下
curl 127.0.0.1:9200/myindex
也是看的到映射, 如下:
curl "127.0.0.1:9200/myindex?pretty"
{
"myindex" : {
"aliases" : { },
"mappings" : {
"doc" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
},
"settings" : {
"index" : {
"creation_date" : "1525191754938",
"number_of_shards" : "5",
"number_of_replicas" : "1",
"uuid" : "lPPTXdLPQAaS-rCTfdVMJA",
"version" : {
"created" : "5020299"
},
"provided_name" : "myindex"
}
}
}
}
所以我們就知道一個索引(index)是由alias
, mappings
, settings
組成的.
有點偏題了.. 下面就介紹自定義映射的方式吧~
定義映射有兩種方式:
(一) 直接對個別的索引配置映射:
這種方式又有兩種方式可以達成..
- 在創建索引的時候直接配置
curl -XPUT http://127.0.0.1:9200/myindex -d '{
"mappings" : {
"doc" : {
"properties" : {
"ip_addr" : { "type" : "ip" }
}
}
}
}'
- 索引創建後, 在加上配置 (可用於update現有配置)
curl -XPUT http://127.0.0.1:9200/myindex/_mapping/doc -d '{
"properties" : {
"ip_addr" : { "type" : "ip" }
}
}'
可以看到兩者的差別, 僅是在一個url比較短, 一個比較長而已 (誤...
兩個可以達到一樣的效果, 但是如果你使用上面第一種, elasticsearch裡面就不能
有你指定的index, 否則...!!
他就會回你index已經存在 Σ(・ω・ノ)ノ ┴─┴
(二) 使用樣板映射(template):
這是我們最常使用的方式哦, 為什麼呢?
因為如果我們的索引是用天來區隔的, myindex-YYYY-MM-dd
也就是比如你配置了今天的映射, 明天又有一個全新的他出現了
就算你定義一個他, 還會有千千萬萬個他!!
ㄜ.. 言歸正傳, 開始吧.
所謂樣板, 就是說今天只要索引的名子, 有匹配到你預先定義的名字, 就會去自行配置
你的設定. 我們看看示範吧.
放入一個名子叫做mytemplate
的模板, 匹配的對象是myindex*
效果就是id
這個欄位要變成text
curl -XPUT http://127.0.0.1:9200/_template/mytemplate -d '{
"template": "myindex*",
"mappings": {
"doc": {
"properties": {
"id": {
"type": "text"
}
}
}
}
}'
查看樣板可以用下面兩種方式(步驟): 這兩個方式都是可以看樣板, 第一個是可以看目前有哪些樣板, 第二種就是看詳細的內容啦~
先看目前有哪些:
curl "http://127.0.0.1:9200/_cat/templates?v"
name template order version
mytemplate myindex* 0
name
: 樣板名字
template
: 匹配規則
order
: 優先級別, 如果兩個樣板重複匹配到的話, 級別高的優先選擇
version
: 版本號
再看詳細內容:
curl "http://127.0.0.1:9200/_template/mytemplate?pretty"
{
"mytemplate" : {
"order" : 0,
"template" : "myindex*",
"settings" : { },
"mappings" : {
"doc" : {
"properties" : {
"id" : {
"type" : "text"
}
}
}
},
"aliases" : { }
}
}
來驗證吧!
# 首先創建兩個新的索引
# 我應該要命中
curl -XPOST 127.0.0.1:9200/myindex123/doc -d '{
"id": 22567789
}'
# 我是來亂的
curl -XPOST 127.0.0.1:9200/my123index/doc -d '{
"id": 33457789
}'
# 然後看一下兩個索引的映射狀態
# 看一下, 我真的成功映射到了
curl "127.0.0.1:9200/myindex123/_mapping?pretty"
{
"myindex123" : {
"mappings" : {
"doc" : {
"properties" : {
"id" : {
"type" : "text"
}
}
}
}
}
}
# 看一下, 果然是來亂的..
curl "127.0.0.1:9200/my123index/_mapping?pretty"
{
"my123index" : {
"mappings" : {
"doc" : {
"properties" : {
"id" : {
"type" : "long"
}
}
}
}
}
}
資料映射大致講到這邊囉~
有兩點需要特別注意的:
- 一個索引裡面已存在的欄位 , 是不允許修改映射的
- 一個索引去響應模板的配置 , 只有在新創建的時候