映射参数
用于字段映射的参数,对部分或全部字段数据类型是通用的。映射参数对字段映射的特殊需求进行设置,比如设置字段的分词,字段的权重,是否被索引,日期的格式,等等,Elasticsearch的功能非常强大,光映射参数高达28个。
1、analyzer参数
可分词的字符串型字段的值通过一个分析器将字符串装换为一连串的索引词。每个查询、每个字段或每个索引都可以指定分析器。
在创建索引时,Elasticsearch会以这个顺序查找分析器:
- 在字段映射中定义的分析器
- 在索引设置中名为default的分析器
- 标准分析器
- 在查询时,有更多的层次
- 在全文查询中定义的分析器
- 在字段映射中定义的搜索分析器
- 在字段映射中定义的分析器
- 在索引设置中名为default_search的分析器
- 在索引设置中名为default的分析器
- 标准分析器
为特定字段指定分词器最简单的方式是在字段映射中定义:
PUT /myindex2
{
"mappings": {
"test2":{
"properties": {
"text":{
"type": "text",
"fields": {
"english":{"type": "text", "analyzer": "english"}
}
}
}
}
}
}
2、boost参数
在索引的时候,通过boost参数可以对一个字段进行加权;对相关性得分计数更多:
PUT /myindex2
{
"mappings": {
"test2":{
"properties": {
"title":{"type": "text", "boost": 2},//2被加权
"content":{"type": "text"}//默认加权参数为1.0
}
}
}
}
注意:
索引时最好不要进行加权,主要有这几个原因:
- 除非重索引所有的文档,索引加权值不会发生改变
- 每个查询都支持查询加权,会产生同样的效果。不同的地方在于不需要重索引就可以调整加权值
- 索引加权值所谓norm的一部分,只有一个字节。降低了字段长度归一化因子的分辨率,会导致低质量的相关性计算
索引加权的唯一优势在于作用与_all字段。当查询_all字段的时候,源于title字段的词比源于content字段的词有更高的分数。(查询_all字段会更加缓慢)。
3、coerce参数
数据不都是干净的。一个数字取决于如何产生,可能通过JSON体中确定的JSON数值进行提供,比如5;也可能通过一个字符串进行提供,比如"5"。或者,整型数据可能被提供浮点型数据,例如5.0或者"5…0"。
强制尝试清理脏值来匹配字段的数据类型:
- 字符串会被强制转换为数字
- 浮点型数据会被截取为整型数据
- 经纬地理点数据会归一化到标准-180:180/–90:90坐标系统
PUT /myindex2
{
"mappings": {
"test2":{
"properties": {
"number_one":{"type": "integer"},
"number_two":{
"type": "integer",
"coerce": false //禁用强制类型转换
}
}
}
}
}
PUT /myindex2/test2/1 //成功
{
"number_one":"10"
}
PUT /myindex2/test2/2 //报错,格式转换失败
{
"number_two":"10"
}
全局设置:
index.mapping.coerce
设置可以在索引级别上对所有映射类型整体禁用强制类型转换。
4、copy_to参数
利用copy_to参数可以创建自定义的_all字段。换句话说,多个字段的值可以被复制到一组字段,然后可以作为单个字段进行查询。
PUT /myindex2
{
"mappings": {
"test2":{
"properties": {
"first_name":{"type": "text", "copy_to": "full_name"},
"last_name":{"type": "text", "copy_to": "full_name"},
"full_name":{"type": "text"}
}
}
}
}
PUT /myindex2/test2/1
{
"first_name":"John",
"last_name":"Smith"
}
GET /myindex2/_search
{
"query": {
"match": {
"full_name": {
"query": "John Smith","operator":"and"
}
}
}
}
first_name和last_name字段的值会被复制到full_name字段中。first_name和last_name字段仍然可以单独进行查询,而且full_name可以用来同时查询两个字段的内容。
- 字段的值时复制过来的,并不是分组(分析过程的结果)
- 原始的_source字段不会被修改来展示复制的值
- 利用"copy_to":[“field_1”,“field_2”],可以将相同的值复制到多个字段
5、doc_values参数
大多数的字段默认被索引,使他们可以被搜索到。反向索引允许查询请求在唯一的索引词中寻找搜索的索引词,找到之后立即访问包含索引词的文档列表。
排序、聚合以及在脚本中访问字段值需要一个不同的数据访问模式。我们需要能够查找文档并在一个字段中寻找存在的索引词。
文档值(Doc Value)是磁盘上的数据结构,在文档索引阶段创建,使上面这种数据访问模式称为可能。doc_values支持几乎所有字段类型。
所有的字段默认包含在文档值中。如果确定一个字段不需要排序、聚合或者在脚本中访问字段值,可以禁用文档值来节省存储空间。
PUT /myindex2
{
"mappings": {
"test2":{
"properties": {
"status_code":{"type": "text","index": false},//默认拥有文档值
"session_id":{"type": "text","index": false,"doc_values":false}//禁用文档值,但仍然可以被查询
}
}
}
}
6、dynamic参数
默认,字段可以被动态地添加到一个文档中,或者添加到文档内部对象中,仅仅通过索引一个包含新字段的文档。
dynamic设置控制新字段是否可以被动态添加,接受三种设置:
- true:新检测到的字段会被添加到映射中(默认)
- false:新检测的字段会被忽略。新字段必须明确添加
- strict:如果新字段被检测到,一个异常会被抛出而且文档会被丢失
PUT /myindex2
{
"mappings": {
"test2":{
"dynamic":false,//类型级别上禁用动态映射,新的顶级字段不会被自动添加
"properties": {
"user":{//user继承了类型级别的设置,同样禁用
"properties": {
"name":{"type":"text"},
"social_networks":{"dynamic":true,"properties":{}}//启动动态映射,新字段可以被添加到social_networks中
}
}
}
}
}
}
7、enabled参数
Elasticsearch尝试索引所有的字段,但是一些情况下仅仅需要存储字段而不进行索引。
enabled设置,仅可以被应用于映射类型和对象字段,导致Elasticsearch跳过字段内容的分解。JSON仍然可以从_source字段取回,但是不能搜索或以其它方式存储。
PUT /myindex2
{
"mappings": {
"session":{
"properties": {
"user_id":{"type": "text", "index":false},
"last_updated":{"type": "date"},
"session_data":{"enabled":false}//enabled参数为false,任意的数据都可以被存储在session_data字段,不过session_data会忽略非JSON对象的值
}
}
}
}
PUT /myindex2/session/1
{
"user_id":"kimchy",
"session_data":{
"arbitrary_object":{"some_array":["foo","bar",{"baz":2}]}
},
"last_updated":"2015-12-06T18:20:22"
}
PUT myindex2/session/2
{
"user_id":"jpountz",
"session_data":"none",
"last_updated":"2015-12-06T18:22:13"
}
整个映射类型都可以被禁用,在这种情况下文档被存储在_source字段,意味着它们可以被取回但是没有任何内容以任何方式被索引:
PUT /myindex2
{
"mappings": {
"session": {"enabled":false}
}
}
PUT /myindex2/session/1
{
"user_id":"kimchy",
"session_data":{
"arbitrary_object":{"some_array":["foo","bar",{"baz":2}]}
},
"last_updated":"2015-12-06T18:20:22"
}
结果:
8、fielddate参数
大多数的字段默认被索引,方便搜索到。反向索引允许查询请求在唯一的索引词有序列表中寻找搜索的索引词,找到之后立即访问包含索引词的文档列表。
排序、聚合以及在脚本中访问字段值需要一个不同的数据访问模式。我们需要能够查找到文档并在一个字段中寻找存在的索引词。
大多数的字段可以使用索引时存储在磁盘上的doc_values值来实现这种数据访问模式,但是分析过的字符串字段不支持doc_values。
相对的,分词的字符串在查询时利用一个称为"字段数据"(fielddata)的数据结构。这个数据结构在字段被用于聚合,排序或者脚本访问的第一时间创建。从磁盘上为每个分片读取整个反向索引,倒置索引词和文档的对应关系,然后将结果存储到内存中Java虚拟机堆内存中,字段数据有三个参数:
- fomat:表示是否启动
- loading:用的时机
- filter:过滤加载的数据
加载字段数据是一个昂贵的过程,一旦被加载,就会在分片的生命周期内驻留在内存中。
1. fielddata.format
test字段不能被用于排序、聚合或者脚本引用。
2. fielddata.loading
这是针对每个字段的设置,控制什么时候字段数据会被加载到内存。接受三个参数:
- lazy:字段数据仅在需要的时候加载到内存中(默认)
- eager:在新的搜索分片对搜索可见之前,字段数据就被加载到内存中。如果用户搜索请求一个大容量分片,比起触发被动加载,这么做可以减少请求延迟。
- eager_global_ordinals:仅加载必须的部分到内存中。加载之后,Elasticsearch创建整体序数数据来组成一个所有索引词的列表。默认情况下,整体序数是被动创建的。如果字段有非常高的基数,在这种情况下就可以使用主动加载。
fielddata.filter
字段数据过滤可以用来减少加载讹你村中的索引词的数量,这么做可以减少内存使用量。索引词可以通过频率或正则表达式以及两者的配合进行过滤。
通过频率过滤可以加载部分索引词,这些索引词的频率落在最小值和最大值之间。频率可以表示为确切的数字(当数值比1.0大)或者作为一个百分比的数(例如0.01是1%,1.0是100%)。每个分片都会计算频率。频率基于有字段值的文档数量,相对于分片中的所有的文档。
可以通过min_segment_size
参数指定分片影噶包含的最少文件量来完全排除小容量分片:
索引词也可以通过正则表达式进行过滤:只有匹配正则表达式的值会被加载。注意:正则表达式被应用于字段中的每个索引词,而不是整个字段值:
已有的字段映射可以更新这些过滤而且会影响分片下一次加载字段数据。利用清理缓存接口来用新的过滤条件重载字段数据。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。