在 Elasticsearch 中,映射指的是 mapping,用来定义一个文档以及其所包含的字段如何被存储和索引,可以在映射中事先定义字段的数据类型、字段的权重、分词器等属性,就如同在关系型数据库中创建数据表时会设置字段的类型。
Elasticsearch 中一个字段可以是核心类型之一,如字符串或者数值型,也可以是一个从核心类型派生的复杂类型,如数值。
映射分类
在 Elasticsearch 中,映射可分为动态映射和静态映射。在关系型数据库中写入数据之前首先要建表,在建表语句中声明字段的属性,在 Elasticsearch 中,则不必如此,Elasticsearch 最重要的功能之一就是让你尽可能快地开始探索数据,文档写入 Elasticsearch 中,它会根据字段的类型自动识别,这种机制称为动态映射,而静态映射则是写入数据之前对字段的属性进行手工设置。
静态映射
静态映射是在创建索引时手工指定索引映射,和 SQL 中在建表语句中指定字段属性类似。相比动态映射,通过静态映射可以添加更详细、更精准的配置信息,例子如下:
PUT my_index
{
"mappings": {
"article": {
"_all": {
"enabled": false
},
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"similarity": "BM25",
"store": true
},
"summary": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"similarity": "BM25"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"similarity": "BM25",
"store": true
}
}
},
"question_and_anwser": {
"_all": {
"enabled": false
},
"properties": {
"question": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"similarity": "BM25"
},
"anwser": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"similarity": "BM25"
},
"question_user_id": {
"type": "long"
},
"anwser_user_id": {
"type": "long"
},
"create_time": {
"type": "date",
"format": "strict_date_optional_time || epoch_mills"
}
}
}
}
}
动态映射
动态映射是一种偷懒的方式,可直接创建索引并写入文档,文档中字段的类型是 Elasticsearch 自动识别的,不需要在创建索引的时候设置字段的类型。在实际项目中,如果遇到的业务在导入数据之前不确定有哪些字段,也不清楚字段的类型是什么,使用动态映射非常合适。当 Elasticsearch 在文档中碰到一个以前没见过的字段时,它会利用动态映射来决定该字段的类型,并自动把该字段添加到映射中,根据字段的取值自动推测字段类型的规则见下表:
JSON 格式的数据 | 自动推测的字段类型 |
---|---|
null | 没有字段被添加 |
true or false | boolean 类型 |
浮点类型数字 | float 类型 |
数字 | long 类型 |
JSON 对象 | object 类型 |
数组 | 由数组中第一个非空值决定 |
string | 有可能是 date 类型(若开启日期检测)、double 或 long 类型、text 类型、keyword 类型 |
下面举一个例子认识动态 mapping,在 Elasticsearch 中创建一个新的索引并查看它的 mapping,命令如下:
PUT books
GET books/_mapping
此时 books 索引的 mapping 是空的,返回结果如下:
{
"books": {
"mappings": {}
}
}
再往 books 索引中写入一条文档,命令如下:
PUT books/it/1
{
"id": 1,
"publish_date": "2019-11-10",
"name": "master Elasticsearch"
}
文档写入完成之后,再次查看 mapping,返回结果如下:
{
"books": {
"mappings": {
"it": {
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"publish_date": {
"type": "date"
}
}
}
}
}
}
id、publish_date、name 三个字段分别被推测为 long 类型、date 类型和 text 类型,这就是动态 mapping 的功劳。
使用动态 mapping 要结合实际业务需求来综合考虑,如果将 Elasticsearch 当作主要的数据存储使用,并且希望出现未知字段时抛出异常来提醒你注意这一问题,那么开启动态 mapping 并不适用。在 mapping 中可以通过 dynamic
设置来控制是否自动新增字段,接受以下参数:
- true:默认值为 true,自动添加字段。
- false:忽略新的字段。
- strict:严格模式,发现新的字段抛出异常。
下面通过例子和实际操作来学习 dynamic 控制新增字段的方法。创建一个 books 索引并指定 mapping,设置 it 类型下 dynamic 属性的取值为 strict,也就是说,it 类型下的文档中出现 mapping 中没有定义的字段会抛出异常,命令如下:
PUT books
{
"mappings": {
"it": {
"dynamic": "strict",
"properties": {
"title": {
"type": "text"
},
"publish_date": {
"type": "date"
}
}
}
}
}
写入三个文档:
PUT books/it/1
{
"title": "master Elasticsearch",
"publish_date": "2017-06-01"
}
PUT books/it/2
{
"title": "master Elasticsearch"
}
PUT books/it/3
{
"title": "master Elasticsearch",
"publish_date": "2017-06-01",
"author":"Tom"
}
文档 books/it/1 和 books/it/2 会创建成功,books/it/3 中出现了新的字段 author,该字段在 mapping 中并没有定义,会抛出 strict_dynamic_mapping_exception 异常。
核心类型
Elasticsearch 字段类型的核心类型有字符串类型、数字类型、日期类型、布尔类型、二进制类型、范围类型等。
一级分类 | 二级分类 | 具体类型 |
---|---|---|
核心类型 | 字符串类型 | string、text、keyword |
数字类型 | long、integer、short、byte、double、float、half_float、scaled_float | |
日期类型 | date | |
布尔类型 | boolean | |
二进制类型 | binary | |
范围类型 | range |
字符串类型
字符串是最直接的,如果在索引字符,字段就应该是 text 类型。它们也是最有趣,因为在映射中有很多选项来分析它们。解析文本、转变文本、将其分解为基本元素使得搜索更为相关,这个过程叫作分析。
Elasticsearch 5.X 之后的字段类型不再支持 string,由 text 或 keyword 取代。如果仍使用 string,会给出警告。
-
text
如果一个字段是要被全文搜索的,比如邮件内容、产品描述、新闻内容,应该使用 text 类型。设置 text 类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分词器分成一个一个词项(term)。text 类型的字段不用于排序,且很少用于聚合(Terms Aggregation 除外)。
-
keyword
keyword 类型适用于索引结构化的字段,比如 email 地址、主机名、状态码和标签,通常用于过滤(比如,查找已发布博客中 status 属性为 published 的文章)、排序、聚合。类型为 keyword 的字段只能通过精确值搜索到,区别于 text 类型。
如上所提到的,text 类型字段可以在映射中指定相关的分析选项,通过 index 选项指定。
index 选项可以设置为 analyzed
(默认)、 not_analyzed
或 no
。
-
analyzed
默认情况下,index 被设置为 analyzed,并产生了如下行为:分析器将所有字符转为小写,并将字符串分解为单词。当期望每个单词完整匹配时,请使用这种选项。举个例子,如果用户搜索 “elasticsearch”,他们希望在结果列表里看到 “Principles and Practice of Elasticsearch”。
-
not_analyzed
将 index 设置为 not_analyzed,将会产生相反的行为:分析过程被略过,整个字符串被当作单独的词条进行索引。当进行精准的匹配时,请使用这个选项,如搜索标签。你可能希望 “big data” 出现在搜索 “big data” 的结果中,而不是出现在搜索 “data” 的结果中。同样,对于多数的词条计数聚集,也需要这个。如果想知道最常出现的标签,可能需要 “big data” 作为一整个词条统计,而不是 “big” 和 “data” 分开统计。
-
no
如果将 index 设置为 no,索引就被略过了,也没有词条产生,因此无法在那个字段上进行搜索。当无须在这个字段上搜索时,这个选项节省了存储空间,也缩短了索引和搜索的时间。例如,可以存储活动的评论。尽管存储和展示这些评论是很有价值的,但是可能并不需要搜索它们。在这种情况下,关闭那个字段的索引,使得索引的过程更快,并节省了存储空间。
数字类型
数字类型支持 byte、short、integer、long、float、double、half_float 和 scaled_float,它们的取值范围如下表:
类型 | 取值范围 |
---|---|
long | -2^63 至 2^63-1 |
integer | -2^31 至 2^31-1 |
short | -32768 至 32767 |
byte | -128 至 127 |
double | 64 位双精度 IEEE 754 浮点类型 |
float | 32 位单精度 IEEE 754 浮点类型 |
half_float | 16 位半精度 IEEE 754 浮点类型 |
scaled_float | 缩放类型的浮点数 |
对于 float、half_float 和 scaled_float,-0.0 和 +0.0 是不同的值,使用 term 查询查找 -0.0 不会匹配 +0.0,同样 range 查询中上边界是 -0.0,也不会匹配 +0.0,下边界是 +0.0,也不会匹配 -0.0。
对于数字类型的字段,在满足需求的情况下,要尽可能选择范围小的数据类型。比如,某个字段的取值最大值不会超过 100,那么选择 byte 类型即可。迄今为止,吉尼斯世界记录的人类的年龄的最大值为 134 岁,对于年龄字段,short 类型足矣。字段的长度越短,索引和搜索的效率越高。
处理浮点数时,优先考虑使用 scaled_float 类型。scaled_float 是通过缩放因子把浮点数变成 long 类型,比如价格只需要精确到分,price 字段的取值为 57.34,设置放大因子为 100,存储起来就是 5734。所有的 API 都会把 price 的取值当作浮点数,事实上 Elasticsearch 底层存储的是整数类型,因为压缩整数比压缩浮点数更加节省存储空间。
数字类型配置映射的例子如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"number_of bytes": {
"type": "integer"
},
"time_in_seconds": {
"type": "float"
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
}
日期类型
JSON 中没有日期类型,所以在 Elasticsearch 中的日期可以是以下几种形式:
- 格式化日期的字符串,如 “2015-01-01” 或 “2015/01/01 12:10:30”。
- 代表 milliseconds-since-the-epoch 的长整型数(epoch 指的是一个特定的时间:1970-01-01 00:00:00 UTC)。
- 代表 seconds-since-the-epoch 的整型数。
Elasticsearch 内部会把日期转换为 UTC(世界标准时间),并将其存储为表示 milliseconds-since-the-epoch 的长整型数,这样做的原因是和字符串相比,数值在存储和处理时更快。日期格式可以自定义,如果没有自定义,默认格式如下:
"strict_date_optional_time||epoch_millis"
日期类型配置映射的例子如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"dt": {
"type": "date"
}
}
}
}
}
写入 3 个文档:
PUT my_index/my_type/1
{
"dt": "2019-11-14"
}
PUT my_index/my_type/2
{
"dt": "2019-11-14T13:16:302"
}
PUT my_index/my_type/3
{
"dt": 1573664468000
}
默认情况下,以上 3 个文档的日期格式都可以被解析,内部存储的是毫秒计时的长整型数。
布尔类型
如果一个字段是布尔类型,可接受的值为 true
、 false
。Elasticsearch 5.4 版本以前,可以接受被解释为 true 或 false 的字符串和数字,5.4 版本以后只接受 true、false、"true"、"false"。
布尔类型配置映射的例子如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"is_published": {
"type": "boolean"
}
}
}
}
}
写入 3 条文档:
PUT my_index/my_type/1
{
"is_published": true
}
PUT my_index/my_type/2
{
"is_published": "true"
}
PUT my_index/my_type/3
{
"is_published": false
}
执行以下搜索,文档 1 和文档 2 都可以被搜索:
GET my_index/_search
{
"query": {
"term": {
"is_published": true
}
}
}
binary 类型
binary 类型接受 base64 编码的字符串,默认不存储(这里的不存储是指 store 属性取值为 false),也不可搜索。
布尔类型配置映射的例子如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"name": {
"type": "text"
},
"blob": {
"type": "binary"
}
}
}
}
}
写入一条文档,其中 blob 的值为字符串 "Some binary blob" 的 Base64 编码:
PUT my_index/my_type/1
{
"name": "Some binary blob",
"blob": "U29t2SBiaW5hcnkgYmxvYg=="
}
range 类型
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 位整数,毫秒计时 |
下面代码创建了一个 range_index 索引,expected_attendees 字段为 integer_range 类型,time_frame 字段为 date_range 类型。
PUT range_index
{
"mappings": {
"my_type": {
"properties": {
"expected_attendees": {
"type": "integer_range"
},
"time_frame": {
"type": "date_range",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
索引一条文档,expected_attendees 的取值为 10 到 20,time_frame 的取值是 2015-10-31 12:00:00 至 2015-11-01,命令如下:
PUT my_index/my_type/1
{
"expected_attendees": {
"gte": 10,
"lte": 20
},
"time_frame": {
"gte": "2019-10-31 12:00:00",
"lte": "2019-11-01"
}
}
复合类型
Elasticsearch 字段类型的复合类型有数组类型、对象类型和嵌套类型。
一级分类 | 二级分类 | 具体类型 |
---|---|---|
核心类型 | 数组类型 | array |
对象类型 | object | |
嵌套类型 | nested |
数组类型
Elasticsearch 没有专用的数组类型,默认情况下任何字段都可以包含 0 个或者多个值,但是一个数组中的值必须是同一种类型。例如:
- 字符数组 :
["one","two"]
- 整型数组 :
[1,3]
- 嵌套数组 :
[1,[2,3]],等价于 [1,2,3]
- 对象数组 :
[{"city":"amsterdam","country":"nederland"},{"city":"brussels","country":"belgium"}]
动态添加数据时,数组的第一个值的类型决定整个数组的类型。混合数组类型是不支持的,比如: [1,"abc"]
。数组可以包含 null
值,空数组 [ ]
会被当作 missing field 对待。
在文档中使用 array 类型不需要提前做任何配置,默认支持。例如写入一条带有数组类型的文档,命令如下:
PUT my_index/my_type/1
{
"message": "some arrays in this document...",
"tags": ["elasticsearch", "wow"],
"lists": [{
"name": "prog_list",
"description": "programming list"
},
{
"name": "cool_list",
"description": "cool stuff list"
}]
}
搜索 lists 字段下的 name,命令如下:
GET my_index/_search
{
"query": {
"match": {
"lists.name": "cool_list"
}
}
}
object 类型
JSON 本质上具有层级关系,文档包含内部对象,内部对象本身还包含内部对象,请看下面的例子:
{
"region": "US",
"manager": {
"age": 30,
"name": {
"first": "John",
"last": "Smith"
}
}
}
上面的文档中,整体是一个 JSON 对象,JSON 中包含一个 manager 对象,manager 对象又包含名为 name 的内部对象。写入到 Elasticsearch 之后,文档会被索引成简单的扁平 key-value 对,格式如下:
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John",
"manager.name.last": "Smith"
}
上面文档结构的显式映射如下:
{
"mappings": {
"my_type": {
"properties": {
"region": {
"type": "keyword"
},
"manager": {
"properties": {
"age": {
"type": "integer"
},
"name": {
"properties": {
"first": {
"type": "text"
},
"last": {
"type": "text"
}
}
}
}
}
}
}
}
}
nested 类型
nested 类型是 object 类型中的一个特例,可以让对象数组独立索引和查询。Lucene 没有内部对象的概念,所以 Elasticsearch 将对象层次扁平化,转化成字段名字和值构成的简单列表。
使用 Object 类型有时会出现问题,比如文档 my_index/my_type/1 的结构如下:
PUT my_index/my_type/1
{
"group": "fans",
"user": [{
"first": "John",
"last": "Smith"
}, {
"first": "Alice",
"last": "White"
}]
}
user 字段会被动态添加为 Object 类型,最后会被转换为以下平整的形式:
{
"group": "fans",
"user.first": ["alice", "john"],
"user.last": ["smith", "white"]
}
user.first 和 user.last 扁平化以后变为多值字段,alice 和 white 的关联关系丢失了。执行以下搜索会搜索到上述文档:
GET my_index/_search
{
"query": {
"bool": {
"must": [{
"match": {
"user.first": "Alice"
}
},
{
"match": {
"user.last": "Smith"
}
}]
}
}
}
事实上是不应该匹配的,如果需要索引对象数组并避免上述问题的产生,应该使用 nested 对象类型而不是 object 类型,nested 对象类型可以保持数组中每个对象的独立性。Nested 类型将数组中每个对象作为独立隐藏文档来索引,这意味着每个嵌套对象都可以独立被搜索,映射中指定 user 字段为 nested 类型:
PUT /my_index
{
"mappings": {
"my_type": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
}
再次执行上述查询语句,文档不会被匹配。
索引一个包含 100 个 nested 字段的文档实际上就是索引 101 个文档,每个嵌套文档都作为一个独立文档来索引。为了防止过度定义嵌套字段的数量,每个索引可以定义的嵌套字段被限制在 50 个。
地理类型
Elasticsearch 的地理相关类型有地理坐标类型和地理图形类型。
一级分类 | 二级分类 | 具体类型 |
---|---|---|
地理类型 | 地理坐标类型 | geo_point |
地理图形类型 | geo_shape |
geo_point 地理坐标
geo point 类型用于存储地理位置信息的经纬度,可用于以下几种场景:
- 查找一定范围内的地理位置。
- 通过地理位置或者相对中心点的距离来聚合文档。
- 把距离因素整合到文档的评分中。
- 通过距离对文档排序。
指定 location 字段为 geo_point 类型,映射如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}
geo_point 字段接收以下 4 种类型的地理位置数据,分别介绍如下:
-
经纬度坐标键值对。
PUT my_index/my_type/1 { "text": "geo_point as an object", "location": { "lat": 41.12, "lon": -71.34 } }
-
字符串格式的地理坐标参数。
PUT my_index/my_type/2 { "text": "geo_point as a string", "location": "41.12,-71.34" }
-
地理坐标的哈希值。
PUT my_index/my_type/3 { "text": "geo_point as a geohash", "location": "u1269qu5dcgp" }
-
数组形式的地理坐标。
PUT my_index/my_type/4 { "text": "geo_point as an array", "location": [-71.34, 41.12] }
geo_shape 地理图形
geo_point 类型可以存储一个坐标点,geo_shape 类型可以存储一块区域,比如矩形、三角形或者其他多边形。GeoJSON 是一种对各种地理数据结构进行编码的格式,对象可以表示几何、特征或者特征集合,支持点、线、面、多点、多线、多面等几何类型。GeoJSON 里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。
GeoJSON 类型 | Elasticsearch 类型 | 说明 |
---|---|---|
Point | point | 一个单独的经纬度坐标点 |
LineString | linestring | 任意的线条,由两到多个点组成 |
Polygon | polygon | 由 N+1 个点组成的封闭 N 边形 |
MultiPoint | multipoint | 一组不连续但有可能相关联的点 |
MultiLineString | multilinestring | 多条不关联的线 |
MultiPolygon | multipolygon | 多个不关联的多边形 |
GeometryCollection | geometrycollection | 几何对象的集合 |
N/A | envelop | 由左上角坐标或右下角坐标确定的封闭矩形 |
N/A | circle | 由圆心和半径确定的圆,默认单位为米 |
下面通过实例演示如何使用 geo_shape 类型。首先创建一个索引,映射中指定 location 字段为 geo_shape 类型,命令如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"location": {
"type": "geo_shape"
}
}
}
}
}
写入一条由经纬度组成的点:
PUT my_index/city/1
{
"location": {
"type": "point",
"coordinates": [-77.03653, 38.897676]
}
}
写入一条由多个点组成的线:
PUT my_index/city/2
{
"location": {
"type": "linestring",
"coordinates": [
[-77.03653, 38.897676],
[-77.009051, 38.889939]
]
}
}
写入一条首尾封闭的多边形:
PUT my_index/city/3
{
"location": {
"type": "polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
]
]
}
}
写入多个多边形:
PUT my_index/city/4
{
"location": {
"type": "polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.2, 0.2],
[100.8, 0.2],
[100.8, 0.8],
[100.2, 0.8],
[100.2, 0.2]
]
]
}
}
特殊类型
Elasticsearch 特殊类型有 IP 类型、范围类型、令牌计数类型、附件类型和抽取类型。
一级分类 | 二级分类 | 具体类型 |
---|---|---|
地理类型 | IP 类型 | ip |
范围类型 | completion | |
令牌计数类型 | token_count | |
附件类型 | attachment | |
抽取类型 | percolator |
ip 类型
ip 类型的字段用于存储 IPv4 或者 IPv6 的地址。在映射中指定字段为 ip 类型的映射和查询语句如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"id_addr": {
"type": "ip"
}
}
}
}
}
PUT my_index/my_type/1
{
"ip_addr": "192.168.1.1"
}
GET my_index/_search
{
"query": {
"term": {
"ip_addr": "192.168.0.0/16"
}
}
}
token_count 类型
token_count 用于统计字符串分词后的词项个数,本质上是一个整数型字段。举个例子,映射中指定 name 为 text 类型,增加 name.length 字段用于统计分词后词项的长度,类型为 token_count,分词器为标准分词器,命令如下:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"name": {
"type": "text",
"fields": {
"length": {
"type": "token_count",
"analyzer": "standard"
}
}
}
}
}
}
}
写入两条文档做测试,解析后第一条文档的 name.length 值为 2,第二条文档的 name.length 值为 3,命令如下:
PUT my_index/my_type/1
{
"name": "John Smith"
}
PUT my_index/my_type/2
{
"name": "Rachel Alice Williams"
}
搜索测试:
GET my_index/_search
{
"query": {
"term": {
"name.length": 3
}
}
}
mapping 属性
elasticsearch 的 mapping 中的字段属性非常多,具体如下表格:
属性名 | 描述 |
---|---|
type |
字段类型,常用的有 text、integer 等等。 |
store |
是否存储指定字段,可选值为 true |false ,设置 true 意味着需要开辟单独的存储空间为这个字段做存储,而且这个存储是独立于 _source 的存储的。 |
norms |
是否使用归一化因子,可选值为 true |false ,不需要对某字段进行打分排序时,可禁用它,节省空间;type 为 text 时,默认为 true;而 type 为 keyword 时,默认为 false。 |
index_options |
索引选项控制添加到倒排索引(Inverted Index)的信息,这些信息用于搜索(Search)和高亮显示:
默认情况下,被分析的字符串(analyzed string)字段使用 positions,其他字段默认使用 docs。 此外,需要注意的是 index_option 是 elasticsearch 特有的设置属性;临近搜索和短语查询时,index_option 必须设置为 offsets,同时高亮也可使用 postings highlighter。 |
term_vector |
索引选项控制词向量相关信息:
term_vector 是 lucene 层面的索引设置。 |
similarity |
指定文档相似度算法(也可以叫评分模型):
|
copy_to |
复制到自定义 _all 字段,值是数组形式,即表明可以指定多个自定义的字段。 |
analyzer |
指定索引和搜索时的分析器,如果同时指定 search_analyzer 则搜索时会优先使用 search_analyzer。 |
search_analyzer |
指定搜索时的分析器,搜索时的优先级最高。 |
fielddata |
默认是 false,因为 doc_values 不支持 text 类型,所以有了 fielddata,fielddata 是 text 版本的 doc_values,也是为了优化字段进行排序、聚合和脚本访问。 和 doc_values 不同的是,fielddata 使用的是内存,而不是磁盘;因为 fielddata 会消耗大量的堆内存,fielddata 一旦加载到堆中,在 segment 的生命周期之内都将一致保持在堆中,所以谨慎使用。 |