Field Data Type (字段数据类型)
常见类型
binary
二进制类型接受作为Base64编码的字符串。该字段默认不存储,不可搜索。
使用:
PUT /my-index-000001?pretty
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"blob": {
"type": "binary"
}
}
}
}
PUT /my-index-000001/_doc/1?pretty
{
"name": "Some binary blob",
"blob": "U29tZSBiaW5hcnkgYmxvYg=="
}
GET my-index-000001/_search
Boolean
Boolean 字段接受JSON true 和 false 的值,但是也可以接受被解释成“true”和“false”的字符串。
使用:
POST /my-index-000001/_doc/1?pretty
{
"is_published": true
}
POST /my-index-000001/_doc/2?pretty
{
"is_published": false
}
GET my-index-000001/_doc/2
Keyword
keyword用于结构化内容,用于 id、电子邮件地址、邮政编码等。该关键字主要用于排序、汇总或术语及查询。
避免将该关键字用于全文检索搜索。如果需要改为 text 类型。
使用:
PUT my-index-000001/_doc/123
{
"mappings": {
"properties": {
"tags": {
"type": "keyword"
}
}
}
}
GET my-index-000001/_mapping
Numeric
支持以下数据类型
-
long
带符号的64位整数,最小值为-263,最大值为-263-1
-
integer
带符号的32位整数,最小值为-232,最大值为-232-1
-
short
-
byte
带符号的8位整数,最小值为-128,最大值为127
-
doule
-
float
-
half_float
-
scaled_float
以a为后缀的浮点数
long
,以固定double
比例因子缩放比如价格只需要精确到分,price 为57.34的字段缩放因子为100,存起来就是5734
-
unsigned_long
一个无符号的64位整数,最小值为0,最大值为:
2^64-1
下面是一个配置数字字段映射的示例:
DELETE my-index-000001
PUT /my-index-000001?pretty
{
"mappings": {
"properties": {
"number_of_bytes": {
"type": "integer"
},
"time_in_seconds": {
"type": "float"
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
GET my-index-000001/_mapping
PUT my-index-000001/_doc/1
{
"number_of_bytes":"5432",
"time_in_seconds":"5432",
"price":"54.32"
}
GET my-index-000001/_doc/1
应该选择哪种类型?
对于整数类型(byte
,short
,integer
和long
)而言,你应该选择这是足以让你的用例最小的类型。这将有助于索引和搜索更加有效。
对于浮点类型,使用缩放因子将浮点数据存储为整数通常会更有效,这是该scaled_float
类型在后台执行的操作。例如,price
字段可以存储在 scaled_float
的scaling_factor
中100
。所有API都可以像将字段存储为双精度一样工作,但是从根本上讲Elasticsearch将使用美分(price*100
整数)来工作。这对节省磁盘空间很有帮助,因为整数比浮点数更容易压缩。
scaling_factor
scaled_float 的附加参数,值在索引时乘以该因子,并四舍五入为最接近的long值。此参数是必需的。
例如,scaled_factor 为10的 scaled_float 会在内部将2.34存储为23并且所有搜索时间操作(查询,聚合,排序)的行为都将类似于文档的值为2.3。 高比例缩放系数值可提高准确性,但同时也会增加空间需求。 此参数是必需的。
Date
JSON中没有日期数据类型,因此Elasticsearch中的日期类型可以为:
- 含有格式化日期的字符串,例如 “2015-01-01”或“2015/01/01 12:10:30”。
- long类型的毫秒数( milliseconds-since-the-epoch)
- integer的秒数(seconds-since-the-epoch)
日期格式可以自定义,但是如果没有 format
指定,则使用默认格式:
strict_date_optional_time || epoch_millis
使用:
DELETE my-index-000001
##日期类型使用默认格式,如果想指定日期格式为yyyy-MM-dd,可以通过format指定
##比如 formt:"yyyy-MM-dd"
PUT my-index-000001
{
"mappings": {
"properties": {
"date": {
"type": "date"
}
}
}
}
##简单日期
PUT my-index-000001/_doc/1
{
"date":"2015-01-01"
}
##带时间的日期
PUT my-index-000001/_doc/2
{
"date":"2015-01-01T12:10:30Z"
}
##毫秒数
PUT my-index-000001/_doc/3
{
"date": 1420070400001
}
##请注意,sort自纪元以来,返回的所有值均以毫秒为单位
GET my-index-000001/_search
{
"sort": { "date": "asc"}
}
对象和关系类型
Object
JSON文档本质上是分层的:文档可能包含内部对象,而内部对象又可能包含对象本身。
使用:
DELETE my-index-000001
##包含一个manager内部对象,manager内部又包含了名为name的内部对象
PUT my-index-000001/_doc/1
{
"region": "US",
"manager": {
"age": 30,
"name": {
"first": "John",
"last": "Smith"
}
}
}
GET my-index-000001/_doc/1
GET my-index-000001/_mapping
在内部,文档会被索引为一个键值对列表:
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John",
"manager.name.last": "Smith"
}
上面文档结构的Mapping如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"region": {
"type": "keyword"
},
"manager": {
"properties": {
"age": { "type": "integer" },
"name": {
"properties": {
"first": { "type": "text" },
"last": { "type": "text" }
}
}
}
}
}
}
}
}
Nested
嵌套类型是对象数据类型的专用版本,允许以独立查询的方式索引对象。
使用:
Elasticsearch 内部对象的概念。因此,它将object层次化结构简化为简单的字段名和值列表。
DELETE my-index-000001
##用户字段映射为类型嵌套而不是类型对象
PUT my-index-000001
{
"mappings": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
##用户字段作为对象类型的字段动态添加
PUT my-index-000001/_doc/1
{
"group":"fans",
"user":[
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
GET my-index-000001/_search
##此查询不匹配,因为Alice和Smith不在相同的嵌套对象中。
GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
}
}
##此查询匹配,因为Alice和White位于同一嵌套对象中。
GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "White" }}
]
}
}
}
}
}
上面的文档在内部转换后会变成以下文档:
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}
文本搜索类型
Text
text 是用来索引全文值的字段,例如邮件正文或产品描述信息。
这些字段会被分析,在索引之前会通过分析器将字符串转换为单个术语的列表。分析过程中允许Elasticsearch在每个全文字段中搜索单个单词。文本字段不能用于排序,也很少用于聚合。
文本字段的映射示例:
DELETE my-index-000001
PUT my-index-000001
{
"mappings": {
"properties": {
"full_name": {
"type": "text"
}
}
}
}
Meta Fields (元数据)
每个文档都有与之关联的元数据,例如索引、映射类型和id元数据字段。在创建映射类型时,可以自定义其中一些元数据字段的行为。
Identity metadata fields
身份元数据字段
_index
- 文档所属的索引
_type [6.0版本已废除]
- 文档映射类型
_id
- 文档ID,限制大小为 512 字节
每个文档都有一个唯一的id,该id被索引,以便使用GET API或id来查询文档。id可以在创建文档时自定义,也可以由elasticsearch生成一个唯一的id。
id字段被限制在Aggregation、排序和脚本中使用。
Document source metadata fields
文档源数据字段
_source
- 原始JSON,表示文档的正文
_size
- _source字段的大小,以字节为单位。由mapping-size插件提供,需要安装后使用
Indexing metadata fields
索引元数据字段
_field_names [不需要使用]
- 文档中包含非空值的所有字段。
_ignored
_ignored
字段索引并存储文档中每个字段的名称,这些字段因格式错误ignore_malformed
并被打开而被忽略 。- 此字段可使用
term
、terms
和exists
查询进行搜索, 并作为搜索命中的一部分返回。
Routing metadata fields
路由元数据字段,自定义路由值将文档路由到特定的碎片。
_routing
一个文档被路由到索引中的一个特定分片,使用以下公式:
shard_num = hash(_routing) % num_primary_shards
如果不指定 _routing
得值,则默认为文档id。
可以通过指定每个文档的自定义路由值来实现自定义路由模式。使用:
DELETE my-index-000001
##本文档使用User1作为其路由值,而不是其ID。
PUT my-index-000001/_doc/1?routing=user1&refresh=true
{
"title": "This is a document"
}
##获取,删除或更新文档时需要提供相同的路由值。
GET my-index-000001/_doc/1?routing=user1
GET my-index-000001/_doc/1
##不指定routing的值默认为id
PUT my-index-000001/_doc/2
{
"title": "This is a document2"
}
##通过id查询
GET my-index-000001/_doc/2?routing=2
##查询中可访问_routing字段的值:
GET my-index-000001/_search
{
"query": {
"terms": {
"_routing": [ "user1" ]
}
}
}
通过自定义路由搜索
自定义路由可以减少搜索的影响,不需将搜索分散到索引中所有的分片,而是将请求发送到特定路由值匹配的分片。
DELETE my-index-000001
GET my-index-000001/_search
{
"query": {
"match": {
"title": "document"
}
}
}
##这个搜索请求仅在与User1和User2路由值相关联的分片上执行
GET my-index-000001/_search?routing=user1
{
"query": {
"match": {
"title": "document"
}
}
}
强制查询指定路由值
在使用自定义路由时,重要的是在索引、获取、删除或更新文档时提供路由值,忘记路由值会导致文档在多个分片上被索引。作为一种安全措施,路由字段可以配置为所有CRUD操作所需的自定义路由值:
DELETE my-index-000002
#强制指定路由
PUT my-index-000002
{
"mappings": {
"_routing": {
"required": true
}
}
}
#以下命令会导致:routing_missing_exception
PUT my-index-000002/_doc/1
{
"title":"No routing documents"
}
#以下命令正常执行
PUT my-index-000002/_doc/2?routing=doc2
{
"title":"666"
}
Other metadata fields
应用程序特定元数据
_meta
......
Mapping Paramater (映射参数)
字段映射使用的各种映射参数的详细解释:
analyzer
只有文本字段支持分词器映射参数
分析器参数指定在索引或搜索文本字段时用于文本分析的分析器
......
fields
以不同方式为不同目的的同一个字段建立索引。
例如字符串可以映射为全文检索字段的文本字段,也可以映射为聚合或排序的关键字字段。
DELETE my-index-000001
#raw字段是city字段的 keyword 版本
PUT my-index-000001
{
"mappings": {
"properties": {
"city": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
PUT my-index-000001/_doc/1
{
"city": "New York"
}
PUT my-index-000001/_doc/2
{
"city": "York"
}
#city字段可以用于全文检索
#city.raw字段可以用于聚合和排序
GET my-index-000001/_search
{
"query": {
"match": {
"city": "york"
}
},
"sort": {
"city.raw": "asc"
},
"aggs": {
"Cities": {
"terms": {
"field": "city.raw"
}
}
}
}
多字段与多个分词器
多字段的另一用例是以不同的方式分析同一个字段以获得更好的相关性。
例如,我们可以使用标准分析器(它将文本分解为单词)和英语分析器(它将单词词根化)来索引一个字段:
DELETE my-index-000002
#desc使用text 文本标准分词器
#desc.english 使用英文分词器
PUT my-index-000002
{
"mappings": {
"properties": {
"desc":{
"type": "text",
"fields": {
"english": {
"type":"text",
"analyzer": "english"
}
}
}
}
}
}
PUT my-index-000002/_doc/1
{
"desc":"_doc desc"
}
PUT my-index-000002/_doc/2
{
"desc":"_doc desc 2"
}
#fields 索引多个文档
GET my-index-000002/_search
{
"query": {
"multi_match": {
"query": "_doc desc",
"fields": ["desc","desc.english"],
"type": "most_fields"
}
}
}
format
使用 format 来格式化日期格式。
DELETE my-index-000001
PUT my-index-000001
{
"mappings": {
"properties": {
"createTime":{
"type": "date",
"format": "yyyy-MM-dd"
}
}
}
}
PUT my-index-000001/_doc/1
{
"createTime":"2021-06-04"
}
#日期格式不正确会抛出:date_time_parse_exception
PUT my-index-000001/_doc/2
{
"createTime":"20210604"
}
GET my-index-000001/_doc/1
index
index选项控制是否对字段值进行索引。它接受true或false,默认为true。没有索引的字段是不可查询的。
这玩意应该没人用!猜的
DELETE my-index-000001
#设置 createTime index为false
PUT my-index-000001
{
"mappings": {
"properties": {
"createTime":{
"type": "date",
"format": "yyyy-MM-dd",
"index": false
}
}
}
}
PUT my-index-000001/_doc/1
{
"createTime":"2021-06-04"
}
#检索出来永远为空
GET my-index-000001/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"createTime": {
"gte": "2021-06-04",
"lte": "2021-06-04"
}
}
}
]
}
}
}
null_value
null 值无法被索引或搜索。当字段为null时(或者一个空数组,或者值全为 null 的数组),它仍被认为没有值。
null_value必须设置成相同类型的参数。例如,一个long型的字段不能被设置成string类型的null_value。
null_value参数允许您使用指定值替换显式空值,以便它可以索引和搜索。 例如:
DELETE my-index-000001
#当status_code为空时,将只设置为NULL
PUT my-index-000001
{
"mappings": {
"properties": {
"status_code":{
"type": "keyword",
"null_value": "NULL"
}
}
}
}
PUT my-index-000001/_doc/1
{
"status_code": null
}
#空数组不包含显式的null,因此不会被NULL替换
PUT my-index-000001/_doc/2
{
"status_code": []
}
PUT my-index-000001/_doc/3
{
"status_code": ""
}
GET my-index-000001/_search
{
"query": {
"term": {
"status_code": "NULL"
}
}
}
properties
类型映射,对象字段和嵌套字段包含子字段,称为属性,这些属性可以是任何数据类型,包括对象和嵌套。
属性设置允许对同一个索引中同名的字段有不同的设置。可以使用PUT映射API向现有字段添加新属性。
下面是一个添加属性到映射类型、对象字段和嵌套字段的示例:
DELETE my-index-000001
PUT my-index-000001
{
"mappings": {
"properties": {
"manager": {
"properties": {
"age": {
"type": "integer"
},
"name": {
"type": "text"
}
}
},
"employees": {
"properties": {
"age": {
"type": "integer"
},
"name": {
"type": "text"
}
}
}
}
}
}
PUT my-index-000001/_doc/1
{
"region": "US",
"manager": {
"name": "Alice White",
"age": 30
},
"employees": [
{
"name": "John Smith",
"age": 34
},
{
"name": "Peter Brown",
"age": 26
}
]
}
GET my-index-000001/_doc/1