您好,登錄后才能下訂單哦!
[TOC]
其實(shí)就是es的字段類型是由es來(lái)做自動(dòng)檢測(cè)還是由我們自己來(lái)指定,因此會(huì)分為動(dòng)態(tài)映射和靜態(tài)映射。
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類型 |
默認(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
}
}
}
}
}
}
}
}
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"
}
}
}
}
}
}
默認(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
}
一級(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。
ex 5.x之后不支持,但仍可以添加,由text或keyword替代。
用于做全文搜索的字段,其字段內(nèi)容會(huì)被分詞器分析,在生成倒排索引前,字符串會(huì)被分詞器分成一個(gè)個(gè)的詞項(xiàng)。
實(shí)際應(yīng)用中,text多用在長(zhǎng)文本的字段中,如article的content,顯然,這樣的字段用于排序和聚合都是沒(méi)有太大意義的。
只能通過(guò)精確值搜索到,區(qū)別于text類型。
其索引的詞項(xiàng)都是字段內(nèi)容本身,因此在實(shí)際應(yīng)用中,會(huì)用來(lái)比較、排序、聚合等操作。
具體注意的細(xì)節(jié)問(wèn)題可以考慮官方文檔,一般的使用都能滿足需求。
json中沒(méi)有日期類型,所以默認(rèn)情況es的時(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í)間字符串。
設(shè)置字段類型為boolean后,可以填入的值為:true、false、"true"、"false"。
binary類型接受base64編碼的字符串。
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"
}
]
}
}
]
}
}
可以直接將一個(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"}
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è)。
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í) |
元字段就是描述文檔本身的字段,其分類及說(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。
參考:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping-params.html。
免責(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)容。