0
点赞
收藏
分享

微信扫一扫

Elasticsearch-索引设置mappings


前言

本文基于elasticsearch7.3.0版本

映射是定义文档及其包含的字段如何存储和索引的过程

Elasticsearch-索引设置mappings_数据类型

查看索引mappings

GET index_test/_mapping

元字段meta-fields

元字段用于自定义如何处理与文档相关的元数据,主要包括_source,_index,_type,_id

_source

_source字段存储了在索引时传递的原始JSON文档
_source字段本身没有被索引(因此不是可搜索的),但它被存储起来,以便在执行时可以返回

#  创建索引
PUT index_test
{
"mappings": {
"_source": {
// true,默认值,表示使用_source field
// false,表示禁用,禁用_source field将导致查询时不会返回索引时的原始JSON文档
// 设置成false时注意:虽然字段不存储在_source field中,但是我们仍然可以搜索这个字段
"enabled": true,
// 指定哪些字段保存在_sorce field里面
// 当includes不存在或者存在时数组大小为空,此时存储的字段就是去除excludes之外的字段
// 当includes存在且数组大小不为空,此时存储的字段就是includes指定的字段
"includes": ["field1"],
// 指定哪些字段不保存在_source field里面
"excludes": ["field3"]
},
"properties": {
"field1": {
"type": "keyword"
},
"field2": {
"type": "keyword"
},
"field3": {
"type": "keyword"
}
}
}
}

// includes不存在,excludes中的字段排除掉,所以保存:field1,field2
"_source": {
"excludes": ["field3"]
}

// includes存在但是数组为空,excludes中的字段排除掉,所以保存:field1,field2
"_source": {
"includes": [],
"excludes": ["field3"]
}

// includes存在且数组不为空,保存的字段就是includes指定的字段,所以保存:field1
"_source": {
"includes": ["field1"],
"excludes": ["field3"]
}

_index

表示文档存储在哪个索引中,也可以用来查询和聚合使用

# 聚合每个索引中的文档数
GET _search
{
"size": 0,
"aggs": {
"index_terms_aggs": {
"terms": {
"field": "_index"
}
}
}
}

_type

表示文档存储在索引中的哪个类型里,只有一个类型_doc

_id

文档唯一标识

字段类型

核心数据类型

字符串

  • text:索引时会分词,类比查询中的match,查询时会分词
  • keyword:索引时不会分词,原样索引,类比查询中的term,查询时不会分词

# 创建索引
PUT index_test
{
"mappings": {
"properties": {
"content":{
// text, 索引时会分词, 可以设置analyzer
"type": "text"
},
"tag":{
// keyword, 索引时不会分词, 不能指定analyzer, 否则创建索引时会报错
"type": "keyword"
}
}
}
}

# 会分词,这里mappings中没有指定analyzer,也没有指定default分析器,所以使用内置standard分析器
POST index_test/_analyze
{
"text":["这是测试文本,测试分词效果"],
"field": "content"
}

# 不会分词
POST index_test/_analyze
{
"text":["这是测试文本,测试分词效果"],
"field": "tag"
}

注意:keyword类型不能设置analyzer,否则创建索引时会报错

# keyword类型指定分析器报错
PUT index_test
{
"mappings": {
"properties": {
"content":{
"type": "text"
},
"tag":{
"type": "keyword",
"analyzer": "ik_max_word"
}
}
}
}

{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [tag] has unsupported parameters: [analyzer : ik_max_word]"
}
],
"type": "mapper_parsing_exception",
"reason": "Failed to parse mapping [_doc]: Mapping definition for [tag] has unsupported parameters: [analyzer : ik_max_word]",
"caused_by": {
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [tag] has unsupported parameters: [analyzer : ik_max_word]"
}
},
"status": 400
}

默认创建的mappings, 每个字符串字段解析成text, 并且会默认一个fields为keyword

// my_test索引事先不存在
POST my_test/_doc/1
{
"userName": "jack",
"password": "123456"
}

// 查看mappings
GET my_test/_mapping

// 结果
{
"my_test" : {
"mappings" : {
"properties" : {
"password" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"userName" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}

数字

整数类型

类型

取值范围

描述

byte

-128 ~ 127(-27 ~ 27-1)

1个字节,一个有符号的8 bit整数

short

-32768 ~ 32767(-215 ~ 215-1)

2个字节,一个有符号的16 bit整数

integer

-231 ~ 231-1

4个字节,一个有符号的32 bit整数

long

-263 ~ 263-1

8个字节,一个有符号的64 bit整数

如何选择类型
就整数类型而言(byte, short, integer和long),应该选择适合用例的最小类型。这将有助于索引和搜索效率更高。但是,请注意,存储是基于存储的实际值进行优化的,因此选择一种类型而不是另一种类型将不会对存储需求产生影响。
比如:明确一个值最小值为0,最大为100,选择byte

浮点类型

类型

取值范围

double

64 bit双精度IEEE 754浮点数

float

32 bit单精度IEEE 754浮点数

half_float

16 bit半精度IEEE 754浮点数

scaled_float

缩放类型的的浮点数,由一个double和一个long型缩放因子组成

如何选择类型
对于浮点类型,优先考虑使用带缩放因子的scaled_float浮点类型
如果scaled_float不是很合适,那么你应该在浮点类型中选择适合用例的最小类型:double, float和half_float

对于double、float和half_float,-0.0和+0.0是不同的值,使用term查询查找-0.0不会匹配+0.0,同样range查询中上边界是-0.0不会匹配+0.0,下边界是+0.0不会匹配-0.0。

scaled_float说明:比如价格需要保留三位小数,price为132.889,缩放因子为1000,存起来就是132889

PUT my_test
{
"mappings": {
"properties": {
"price":{
"type": "scaled_float",
// 设置缩放因子,这个参数必须有,否则创建索引时报错
"scaling_factor": 1000
}
}
}
}

PUT my_test/_doc/1
{
// 实际存储的值 : 132.889 * 1000(缩放因子) = 132889
"price": 132.889
}

日期

ElasticSearch 内部会将日期数据转换为UTC,并存储为milliseconds-since-the-epoch的long型整数(时间戳)
详细请参考这篇博客:​​​Elasticsearch-日期数据类型和时区详解​​

布尔

布尔字段接受JSON true和false值,但也可以接受被解释为true或false的字符串

布尔



true, “true”


false, “false”

二进制

这个binary类型接受base 64编码的字符串,可用来存储二进制形式的数据
默认情况下,字段只存储不索引,因此也不能被搜索
注意: base 64编码的二进制值必须没有嵌入的换行符。\n

范围

类型

取值

integer_range

带符号的32 bit整数的范围,-231 ~ 231-1

long_range

有符号64 bit整数的范围,-263 ~ 263-1

float_range

32 bit单精度IEEE 754浮点数范围

double_range

64 bit双精度IEEE 754浮点数范围

date_range

表示milliseconds-since-the-epoch的long型整数, 即64 bit整数毫秒的无符号日期值的范围

ip_range

支持以下任一项的IP值范围IPv 4或IPv 6(或混合)地址

PUT range_index
{
"mappings": {
"properties": {
"expected_attendees": {
"type": "integer_range"
},
"time_frame": {
"type": "date_range",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}

PUT range_index/_doc/1?refresh
{
"expected_attendees" : {
"gte" : 10,
"lte" : 20
},
"time_frame" : {
"gte" : "2015-10-31 12:00:00",
"lte" : "2015-11-01"
}
}

复合数据类型

数组

在Elasticearch中,没有专门的array数据类型。默认情况下,任何字段都可以包含零或多个值,但是数组中的所有值必须具有相同的数据类型,ElasticSearch不支持元素为多个数据类型:[ 10, “some string” ]
数组可能包含null值,这些值要么为配置的null_value或者完全跳过。空数组[]被视为缺失字段–一个没有值的字段
常见数组:

  • 字符串数组:[“one”, “two” ]
  • 整数数组:[1, 2 ]
  • 嵌套数组:[1, [ 2, 3]这相当于[1, 2, 3 ]
  • 对象数组:[{ “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }]

注意:对象数组不像预期的那样工作:不能独立于数组中的其他对象查询每个对象。如果您需要能够做到这一点,那么您应该使用nested数据类型,而不是object数据类型。

对象

JSON文档本质上是分层的:文档可能包含内部对象,而内部对象也可能包含内部对象本身
不需要显示的设置字段type为object, 因为这是默认值

# my_index事先不存在
PUT my_index/_doc/1
{
"region": "US",
"manager": {
"age": 30,
"name": {
"first": "John",
"last": "Smith"
}
}
}

# 在内部,这个文档被索引为一个简单的键值对列表,如下所示:
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John",
"manager.name.last": "Smith"
}

# 查看这个索引mappings
GET my_index/_mapping

# 结果
{
"my_index" : {
"mappings" : {
"properties" : {
"manager" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"properties" : {
"first" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"last" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
},
"region" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}

对象数组

nested数据类型是一种特殊的object数据类型,它允许对对象数组进行索引,使它们可以彼此独立地查询

object数据类型存在的问题

# my_index索引事先不存在, user字段被动态添加为object字段类型
PUT my_index/_doc/1
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}

# 内部存储, user.first和user.last之间没有了关联关系
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}

# 查询, 此时不能正确地匹配alice AND smith, 本来应该查询不出来数据的, 这时候查询出来了id为1的文档
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "Alice"
}
},
{
"match": {
"user.last": "Smith"
}
}
]
}
}
}

如果需要索引对象数组并维护数组中每个对象的独立性,则应使用nested数据类型,而不是object数据类型。在内部,嵌套对象将数组中的每个对象索引为单独的隐藏文档,这意味着每个嵌套对象可以独立于其他对象进行查询,nested查询:

# 创建索引
PUT my_index
{
"mappings": {
"properties": {
"user": {
// 设置字段类型
"type": "nested",
"properties": {
"first": {
"type": "keyword"
},
"last": {
"type": "keyword"
}
}
}
}
}
}

# 索引文档
PUT my_index/_doc/1
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}

# 使用nested查询
GET my_index/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
// 此查询匹配,因为Alice和White在同一个嵌套对象中
"must": [
{
"match": {
"user.first": "Alice"
}
},
{
"match": {
"user.last": "White"
}
}
]
}
},
// inner_hits允许我们高亮显示匹配的嵌套文档
"inner_hits": {
"highlight": {
"fields": {
"user.first": {}
}
}
}
}
}
}

地理数据类型

地点

类型字段geo_point接受经纬度对

  • lat:纬度
  • lon:经度

有五种方法可以指定地理点,如下所示:

PUT my_index
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}

# 表示为对象的geo_point
PUT my_index/_doc/1
{
"text": "Geo-point as an object",
"location": {
"lat": 41.12,
"lon": -71.34
}
}

# geo_point表示为字符串, 格式为: "lat,lon"(纬度,经度)
PUT my_index/_doc/2
{
"text": "Geo-point as a string",
"location": "41.12,-71.34"
}

# geohash表示geo_point
PUT my_index/_doc/3
{
"text": "Geo-point as a geohash",
"location": "drm3btev3e86"
}

# 数组表示的geo_point, 格式为: [lon, lat]([经度, 纬度])
PUT my_index/_doc/4
{
"text": "Geo-point as an array",
"location": [ -71.34, 41.12 ]
}

# POINT字符串, 存储时报错
# {
# "type": "parse_exception",
# "reason": "unsupported symbol [o] in geohash [POINT(-71.34 41.12)]"
# }
PUT my_index/_doc/5
{
"text": "Geo-point as a WKT POINT primitive",
"location" : "POINT (-71.34 41.12)"
}

# 查询
GET my_index/_search
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 42,
"lon": -72
},
"bottom_right": {
"lat": 40,
"lon": -74
}
}
}
}
}

地形

这个geo_shape数据类型为任意几何形状(如矩形和多边形)的索引和搜索提供了便利。当要索引的数据或正在执行的查询包含的形状不只是点时,就应该使用它。

可以对类型使用地质形状查询.

特殊数据类型

ip

ip字段可以索引/存储IPv 4或IPv 6地址

completion

这个completion suggester(建议)提供自动完成/搜索即用类型的功能。这是一个导航功能,引导用户在输入时获得相关结果,从而提高搜索精度。它不是用于拼写更正,也不是指像term或phrase suggester。

理想情况下,自动完成功能应该和用户输入一样快,以提供与用户已经输入的内容相关的即时反馈。因此,completion suggester是优化的速度。该建议程序使用的数据结构支持快速查找,但构建成本很高,并且存储在内存中。

token_count

token_count类型是一个integer类型,该字段接受字符串值,对它们进行分析,然后对字符串中的标记数进行索引。

PUT my_index
{
"mappings": {
"properties": {
"name": {
// 使用内置的standard分析器
"type": "text",
"fields": {
"length": {
"type": "token_count",
"analyzer": "standard"
}
}
}
}
}
}

# name分析后有2个token
PUT my_index/_doc/1
{ "name": "John Smith" }

# name分析后有3个token
PUT my_index/_doc/2
{ "name": "Rachel Alice Williams" }

# 查询name包含3个token的文档
GET my_index/_search
{
"query": {
"term": {
"name.length": 3
}
}
}

映射参数

analyzer和search_analyzer

详细参考:​​Elasticsearch-分析器详解​​

  • analyzer: 指定字段索引和查询时的分析器
  • search_analyzer: 指定字段查询时的分析器, 优先级高于analyzer

字段索引时分析器优先级:

  1. mappings analyzer
  2. settings default分析器
  3. 内置standard分析器

字段查询时分析器优先级

  1. 查询时指定的分析器
  2. mappings search_analyzer
  3. mappings analyzer
  4. settings default_search分析器
  5. settings default分析器
  6. 内置standard分析器

format

自定义日期格式化格式

index

index选项控制字段值是否被索引,elasticsearch默认索引所有字段,它接受true或false, 默认为true
没有被索引的字段不可查询, 但是仍然会存储在_source中

enabled

ElasticSearch试图索引给它的所有字段,但有时你只想存储字段而不对其进行索引

这个enabled设置,该设置只能应用于顶层映射定义和object字段,导致Elasticearch完全跳过对字段内容的解析。仍然可以从_source字段,但它不能搜索,也不能存储在store字段中

PUT my_index
{
"mappings": {
"properties": {
"session_data": {
"type": "object",
// 这个session_data字段被禁用
"enabled": false,
// 这个时候store只能为false, 为true则创建索引时报错
"store": false
}
}
}
}

# enabled为false, store为true时, 创建索引报错
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [session_data] has unsupported parameters: [store : true]"
}
],
"type": "mapper_parsing_exception",
"reason": "Failed to parse mapping [_doc]: Mapping definition for [session_data] has unsupported parameters: [store : true]",
"caused_by": {
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [session_data] has unsupported parameters: [store : true]"
}
},
"status": 400
}

# 任意数据都可以传递给session_data字段,因为它将被完全忽略
PUT my_index/_doc/session_1
{
"session_data": {
"arbitrary_object": {
"some_array": [ "foo", "bar", { "baz": 2 } ]
}
}
}

# 注意,由于Elasticsearch完全跳过解析字段内容,所以可以将非对象数据添加到禁用的字段中
# 这个session_data也将忽略不是JSON对象的值
PUT my_index/_doc/session_2
{
"session_data": "none"
}

整个映射也可能被禁用,在这种情况下,文档存储在_source字段,这意味着可以检索该字段,但没有以任何方式对其内容进行索引

PUT my_index
{
"mappings": {
// 整个映射被禁用
"enabled": false
}
}

PUT my_index/_doc/session_1
{
"user_id": "kimchy",
"session_data": {
"arbitrary_object": {
"some_array": [ "foo", "bar", { "baz": 2 } ]
}
},
"last_updated": "2015-12-06T18:20:22"
}

# 可以检索文档
GET my_index/_doc/session_1

# 检查映射会发现没有添加任何字段
GET my_index/_mapping

# 返回
{
"my_index" : {
"mappings" : {
"enabled" : false
}
}
}

copy_to

copy_to参数允许你将多个字段的值复制到一组字段中,然后可以将该字段作为单个字段进行查询

PUT my_index
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text",
"store": true
}
}
}
}

PUT my_index/_doc/1
{
"first_name": "John",
"last_name": "Smith"
}

# full_name字段不会出现在_source中
GET my_index/_search
{
"query": {
"match": {
"full_name": {
"query": "John Smith",
"operator": "and"
}
}
}
}

# 返回
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"first_name" : "John",
"last_name" : "Smith"
}
}
]
}
}

# copy的内容会存储在store字段中
GET my_index/_search
{
"stored_fields": ["full_name"],
"query": {
"match": {
"full_name": {
"query": "John Smith",
"operator": "and"
}
}
}
}

# 返回
{
"took" : 815,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.5753642,
"fields" : {
"full_name" : [
"John",
"Smith"
]
}
}
]
}
}

store

默认情况下,字段值被索引使它们可以被搜索,但它们不是存储,这意味着可以查询字段,但无法检索原始字段值

但通常这不是问题,默认情况下,字段值已经存储在_source里面,所以store默认值为false
如果你只想检索单个字段或几个字段的值,而不是整个_source字段的值。则可以使用source filtering

使用情况一:没有存储在_source中的字段, 可以使用store存储, 比如说:copy_to字段

使用情况二:只想检索指定字段, 通常这个可以使用source filtering代替

store查询和_source查询区别:

  • IO的区别: 查询整个_source字段或者_source部分字段都是一次IO, store查询每个字段一次IO, 也就是查询多少个字段就有多少次IO
  • 返回值的区别: 查询_source原样返回, 为了保持一致性, 存储的字段总是作为数组返回, 因为无法知道原始字段值是单个值、多个值还是空数组

PUT my_index
{
"mappings": {
"properties": {
"title": {
"type": "text",
"store": true
},
"content": {
"type": "text"
}
}
}
}

PUT my_index/_doc/1
{
"title": "Some short title",
"content": "A very long content field..."
}

# 从store中查询
GET my_index/_search
{
"stored_fields": ["title"]
}

# 返回
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"fields" : {
// 一个字段一次IO
// 为了保持一致性,存储的字段总是作为数组返回, 因为无法知道原始字段值是单个值、多个值还是空数组
// 如果需要原始值,则应从_source获取字段值
"title" : [
"Some short title"
]
}
}
]
}
}

# 从_source中查询
GET my_index/_search
{
"_source": {
"includes": ["title"]
}
}

# 返回
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
// 整个_source字段是一次IO
"_source" : {
"title" : "Some short title"
}
}
]
}
}

fields

为了不同的目的,以不同的方式对同一个字段进行索引通常是有用的。这就是multi-fields
例如,字符串可以映射为text字段用于全文搜索,并作为keyword用于排序或聚合的字段
注意:多个字段不会更改_source

PUT my_index
{
"mappings": {
"properties": {
"city": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}

PUT my_index/_doc/1
{
"city": "New York"
}

PUT my_index/_doc/2
{
"city": "York"
}

GET my_index/_search
{
"query": {
"match": {
"city": "york"
}
},
"sort": {
"city.raw": "asc"
},
"aggs": {
"Cities": {
"terms": {
"field": "city.raw"
}
}
}
}

multi-fields多分析器
multi-fields的另一个用例是以不同的方式分析同一个字段,以获得更好的相关性。
例如,我们可以用standard分析器将文本分解成文字,然后再用english分析器词根形式

PUT my_index
{
"mappings": {
"properties": {
"text": {
"type": "text",
"fields": {
"english": {
"type": "text",
"analyzer": "english"
}
}
}
}
}
}

PUT my_index/_doc/1
{ "text": "quick brown fox" }

PUT my_index/_doc/2
{ "text": "quick brown foxes" }

GET my_index/_search
{
"query": {
"multi_match": {
"query": "quick brown foxes",
"fields": [
"text",
"text.english"
],
"type": "most_fields"
}
}
}

null_value

null值不能被索引或搜索。当字段设置为null,(空数组[]或数组为null)它被视为该字段没有值

  • null_value参数允许你把null显式替换为指定的值,以便可以对其进行索引和搜索
  • null_value需要与字段有相同的数据类型。例如,long字段不能指定null_value为字符串
  • null_value只影响数据的索引方式,不会修改_source文件

PUT my_index
{
"mappings": {
"properties": {
"status_code": {
"type": "keyword",
// 显式替换为字符串"NULL"
"null_value": "NULL"
}
}
}
}

PUT my_index/_doc/1
{
// 替换
"status_code": null
}

PUT my_index/_doc/2
{
// 空数组不包含显式null,所以不会用null_value
"status_code": []
}

# 查询"NULL", 返回文档1, 不返回文档2
GET my_index/_search
{
"query": {
"term": {
"status_code": "NULL"
}
}
}

doc_values

默认情况下大多数字段都是被索引的,这使得它们可以被搜索。
倒排索引允许查询在唯一排序的term列表中查找搜索词,并从该列表中立即访问包含该term的文档列表。

在脚本中对字段值的排序、聚合和访问需要不同的数据访问模式。
我们不需要查找term和查找文档,而是需要能够查找文档并找到它在某个field中的term。

doc值是在文档索引时构建的磁盘上数据结构,这使得这种数据访问模式成为可能。
它们存储与_source相同的值,但是以一种面向列的方式来进行排序和聚合,效率要高得多。
几乎所有字段类型都支持doc值,除了text和annotated_text字段

默认情况下,所有支持doc值的字段都启用了这些值。
如果你确定不需要对字段进行排序或聚合,或者访问脚本中的字段值,则可以禁用doc值以节省磁盘空间

PUT my_index
{
"mappings": {
"properties": {
"status_code": {
// status_code字段doc_values默认启用
"type": "keyword"
},
"session_id": {
"type": "keyword",
// session_id的doc_values禁用,但仍然可以查询, 不能用于排序和聚合
"doc_values": false
}
}
}
}


举报

相关推荐

0 条评论