溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Elasticsearch常用操作:映射篇

發(fā)布時(shí)間:2020-05-25 05:17:01 來(lái)源:網(wǎng)絡(luò) 閱讀:3503 作者:xpleaf 欄目:大數(shù)據(jù)

[TOC]


其實(shí)就是es的字段類型是由es來(lái)做自動(dòng)檢測(cè)還是由我們自己來(lái)指定,因此會(huì)分為動(dòng)態(tài)映射和靜態(tài)映射。

1 動(dòng)態(tài)映射

1.1 映射規(guī)則

JSON格式的數(shù)據(jù) 自動(dòng)推測(cè)的字段類型
null 沒(méi)有字段被添加
true or false boolean類型
浮點(diǎn)類型數(shù)字 float類型
數(shù)字 long類型
JSON對(duì)象 object類型
數(shù)組 由數(shù)組中第一個(gè)非空值決定
string 有可能是date類型(開(kāi)啟日期檢測(cè))、double或long類型、text類型、keyword類型

1.2 日期檢測(cè)

默認(rèn)是開(kāi)啟的(es5.4),測(cè)試案例如下:

PUT myblog

GET myblog/_mapping

PUT myblog/article/1
{
  "id":1,
  "postdate":"2018-10-27"
}

GET myblog/_mapping
{
  "myblog": {
    "mappings": {
      "article": {
        "properties": {
          "id": {
            "type": "long"
          },
          "postdate": {
            "type": "date"
          }
        }
      }
    }
  }
}

關(guān)閉日期檢測(cè)后,則不會(huì)檢測(cè)為日期,如下:

PUT myblog
{
  "mappings": {
    "article": {
      "date_detection": false
    }
  }
}

GET myblog/_mapping

PUT myblog/article/1
{
  "id":1,
  "postdate":"2018-10-27"
}

GET myblog/_mapping
{
  "myblog": {
    "mappings": {
      "article": {
        "date_detection": false,
        "properties": {
          "id": {
            "type": "long"
          },
          "postdate": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

2 靜態(tài)映射

2.1 基本案例

PUT myblog
{
  "mappings": {
    "article": {
      "properties": {
        "id":{"type": "long"},
        "title":{"type": "text"},
        "postdate":{"type": "date"}
      }
    }
  }
}

GET myblog/_mapping

PUT myblog/article/1
{
  "id":1,
  "title":"elasticsearch is wonderful!",
  "postdate":"2018-10-27"
}

GET myblog/_mapping
{
  "myblog": {
    "mappings": {
      "article": {
        "properties": {
          "id": {
            "type": "long"
          },
          "postdate": {
            "type": "date"
          },
          "title": {
            "type": "text"
          }
        }
      }
    }
  }
}

2.2 dynamic屬性

默認(rèn)情況下,當(dāng)添加一份文檔時(shí),如果出現(xiàn)新的字段,es也會(huì)添加進(jìn)去,不過(guò)這個(gè)是可以進(jìn)行控制的,通過(guò)dynamic來(lái)進(jìn)行設(shè)置:

dynamic值 說(shuō)明
true 默認(rèn)值為true,自動(dòng)添加字段
false 忽略新的字段
strict 嚴(yán)格模式,發(fā)現(xiàn)新的字段拋出異常
PUT myblog
{
  "mappings": {
    "article": {
      "dynamic":"strict",
      "properties": {
        "id":{"type": "long"},
        "title":{"type": "text"},
        "postdate":{"type": "date"}
      }
    }
  }
}

GET myblog/_mapping

PUT myblog/article/1
{
  "id":1,
  "title":"elasticsearch is wonderful!",
  "content":"a long text",
  "postdate":"2018-10-27"
}

{
  "error": {
    "root_cause": [
      {
        "type": "strict_dynamic_mapping_exception",
        "reason": "mapping set to strict, dynamic introduction of [content] within [article] is not allowed"
      }
    ],
    "type": "strict_dynamic_mapping_exception",
    "reason": "mapping set to strict, dynamic introduction of [content] within [article] is not allowed"
  },
  "status": 400
}

3 字段類型

3.1 普通字段類型

一級(jí)分類 二級(jí)分類 具體類型
核心類型 字符串類型 string、text、keyword
數(shù)字類型 long、intger、short、byte、double、float、half_float、scaled_float
日期類型 date
布爾類型 boolean
二進(jìn)制類型 binary
范圍類型 range
復(fù)合類型 數(shù)組類型 array
對(duì)象類型 object
嵌套類型 nested
地理類型 地理坐標(biāo) geo_point
地理圖形 geo_shape
特殊類型 IP類型 ip
范圍類型 completion
令牌計(jì)數(shù)類型 token_count
附件類型 attachment
抽取類型 percolator

下面只會(huì)列出一些在個(gè)人工作中常用的,詳細(xì)的可以參考官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping.html。

3.1.1 string

ex 5.x之后不支持,但仍可以添加,由text或keyword替代。

3.1.2 text

用于做全文搜索的字段,其字段內(nèi)容會(huì)被分詞器分析,在生成倒排索引前,字符串會(huì)被分詞器分成一個(gè)個(gè)的詞項(xiàng)。

實(shí)際應(yīng)用中,text多用在長(zhǎng)文本的字段中,如article的content,顯然,這樣的字段用于排序和聚合都是沒(méi)有太大意義的。

3.1.3 keyword

只能通過(guò)精確值搜索到,區(qū)別于text類型。

其索引的詞項(xiàng)都是字段內(nèi)容本身,因此在實(shí)際應(yīng)用中,會(huì)用來(lái)比較、排序、聚合等操作。

3.1.4 數(shù)字類型

具體注意的細(xì)節(jié)問(wèn)題可以考慮官方文檔,一般的使用都能滿足需求。

3.1.5 date

json中沒(méi)有日期類型,所以默認(rèn)情況es的時(shí)間的形式可以為:

  • 1."yyyy-MM-dd"或"yyyy-MM-ddTHH:mm:ssZ"
    • 也就是說(shuō)"yyyy-MM-dd HH:mm:ss"需要寫(xiě)成:"2018-10-22T23:12:22Z"的形式,其實(shí)就是加了時(shí)區(qū);
  • 2.表示毫秒的timestamp的長(zhǎng)整型數(shù)
  • 3.表示秒的timestamp的整型數(shù)

es內(nèi)部存儲(chǔ)的是毫秒計(jì)時(shí)的長(zhǎng)整型數(shù)。

當(dāng)然上面只是默認(rèn)情況下的,在設(shè)置字段的類型時(shí),我們也可以設(shè)置自己定義的時(shí)間格式:

PUT myblog
{
  "mappings": {
    "article": {
      "properties": {
        "postdate":{
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        }
      }
    }
  }
}

format也可以指定多個(gè)日期格式,使用"||"分隔開(kāi):

"format": "yyyy-MM-dd HH:mm:ss||yyyy/MM/dd HH:mm:ss"

之后就可以寫(xiě)入定義的時(shí)間格式的數(shù)據(jù)了:

PUT myblog/article/1
{
  "postdate":"2017-09-23 23:12:22"
}

在我的工作場(chǎng)景中,如果需要存入的為時(shí)間,很多時(shí)候會(huì)先把其處理為毫秒值的timestamp,然后再存入es中,取出顯示時(shí)再處理為時(shí)間字符串。

3.1.6 boolean

設(shè)置字段類型為boolean后,可以填入的值為:true、false、"true"、"false"。

3.1.7 binary

binary類型接受base64編碼的字符串。

3.1.8 array

es沒(méi)有專用的數(shù)組類型,默認(rèn)情況下任何字段都可以包含一個(gè)或者多個(gè)值,但是一個(gè)數(shù)組中的值必須是同一種類型。動(dòng)態(tài)添加數(shù)據(jù)時(shí),數(shù)組的第一個(gè)值的類型決定整個(gè)數(shù)組的類型(其實(shí)也就是這個(gè)字段的類型),混合數(shù)組是不支持的。數(shù)組可以包含null值,空數(shù)組[]會(huì)被當(dāng)作missing field對(duì)待。另外在文檔中使用array類型不需要提前做任何配置,默認(rèn)支持。

比如添加下面一個(gè)數(shù)組的字段數(shù)據(jù):

DELETE my_index

PUT my_index/my_type/1
{
  "lists":[
    {
      "name":"xpleaf",
      "job":"es"
    }
  ]
}

其實(shí)際上該字段的類型就會(huì)被動(dòng)態(tài)映射為text:

GET my_index/my_type/_mapping

{
  "my_index": {
    "mappings": {
      "my_type": {
        "properties": {
          "lists": {
            "properties": {
              "job": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

直接搜索也是支持的:

GET my_index/my_type/_search
{
  "query": {
    "term": {
      "lists.name": {
        "value": "xpleaf"
      }
    }
  }
}

返回結(jié)果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "lists": [
            {
              "name": "xpleaf",
              "job": "es"
            }
          ]
        }
      }
    ]
  }
}
3.1.9 object

可以直接將一個(gè)json對(duì)象寫(xiě)入es中,如下:

DELETE my_index

PUT my_index/my_type/1
{
  "object":{
    "name":"xpleaf",
    "job":"es"
  }
}

其實(shí)際上該字段的類型就會(huì)被動(dòng)態(tài)映射為text:

{
  "my_index": {
    "mappings": {
      "my_type": {
        "properties": {
          "object": {
            "properties": {
              "job": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

直接搜索也是可以的:

GET my_index/my_type/_search
{
  "query": {
    "term": {
      "object.name": {
        "value": "xpleaf"
      }
    }
  }
}

返回結(jié)果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "object": {
            "name": "xpleaf",
            "job": "es"
          }
        }
      }
    ]
  }
}

object對(duì)象,實(shí)際上在es內(nèi)部會(huì)被扁平化處理,如上面的,在es中實(shí)際為:

{"object.name":"xpleaf", "object.job":"es"}

3.1.10 nested

nested類型是object類型中的一個(gè)特例,可以讓對(duì)象數(shù)組獨(dú)立索引和查詢。Lucene沒(méi)有內(nèi)部對(duì)象的概念,所以es將對(duì)象層次扁平化,轉(zhuǎn)化成字段名字和值構(gòu)成的簡(jiǎn)單列表。

雖然是object類型中的一個(gè)特例,但是其字段的type是固定的,也就是nested,這是與object的最大不同。

那么為什么要使用nested類型呢,使用object不就可以了嗎?這里貼一下官方提供的一個(gè)例子來(lái)進(jìn)行說(shuō)明(https://www.elastic.co/guide/en/elasticsearch/reference/5.6/nested.html):

Arrays of inner object fields do not work the way you may expect. Lucene has no concept of inner objects, so Elasticsearch flattens object hierarchies into a simple list of field names and values. For instance, the following document:

PUT my_index/my_type/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

would be transformed internally into a document that looks more like this:

{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}

The user.first and user.last fields are flattened into multi-value fields, and the association between alice and white is lost. This document would incorrectly match a query for alice AND smith:

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}

上面是直接使用object而導(dǎo)致的問(wèn)題,也就是說(shuō)實(shí)際上進(jìn)行上面的搜索時(shí),該文檔是不應(yīng)該被匹配出來(lái)的,但是確匹配出來(lái)了。使用nested對(duì)象類型就可以保持?jǐn)?shù)組中每個(gè)對(duì)象的獨(dú)立性,nested類型將數(shù)組中每個(gè)對(duì)象作為獨(dú)立隱藏文檔來(lái)索引,這意味著每個(gè)嵌套對(duì)象都可以獨(dú)立被搜索。

If you need to index arrays of objects and to maintain the independence of each object in the array, you should use the nested datatype instead of the object datatype. Internally, nested objects index each object in the array as a separate hidden document, meaning that each nested object can be queried independently of the others, with the nested query:

PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "user": {
          "type": "nested" 
        }
      }
    }
  }
}

PUT my_index/my_type/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

GET my_index/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }} 
          ]
        }
      }
    }
  }
}

GET my_index/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "White" }} 
          ]
        }
      },
      "inner_hits": { 
        "highlight": {
          "fields": {
            "user.first": {}
          }
        }
      }
    }
  }
}

索引一個(gè)包含100個(gè)nested字段的文檔實(shí)際上就是索引101個(gè)文檔,每個(gè)嵌套文檔都作為一個(gè)獨(dú)立文檔來(lái)索引。為了防止過(guò)度定義嵌套字段的數(shù)量,每個(gè)索引可以定義的嵌套字段被限制在50個(gè)。

3.1.11 range

range類型及其取值范圍如下:

類型 范圍
integer_range -2^31~2^31-1
float_range 32-bit IEEE 754
long_range -2^63~2^63-1
double_range 64-bit IEEE 754
date_range 64位整數(shù),毫秒計(jì)時(shí)

3.2 元字段

元字段就是描述文檔本身的字段,其分類及說(shuō)明如下:

元字段分類 具體屬性 作用
文檔屬性的元字段 _index 文檔所屬索引
_uid 包含_type_id的復(fù)合字段(取值為{type}#{id})
_type 文檔的類型
_id 文檔的id
源文檔的元字段 _source 文檔的原始JSON字符串
_size _source字段的大小
_all 包含索引全部字段的超級(jí)字段
_field_names 文檔中包含非空值的所有字段
路由的元字段 _parent 指定文檔間的父子關(guān)系
_routing 將文檔路由到特定分片的自定義路由值
自定義元字段 _meta 用于自定義元數(shù)據(jù)

各個(gè)字段的詳細(xì)說(shuō)明,可以參考:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping-fields.html。

4 映射參數(shù)

參考:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping-params.html。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI