ElasticSearch(三)—文档字段参数设置以及元字段

一、 字段参数设置

analyzer:

指定分词器。elasticsearch 是一款支持全文检索的分布式存储系统,对于 text类型的字段,首先会使用分词器进行分词,然后将分词后的词根一个一个存储在倒排索引中,后续查询主要是针对词根的搜索。

analyzer 该参数可以在每个查询、每个字段、每个索引中使用,其优先级如下(越靠前越优先):

1、字段上定义的分词器

2、索引配置中定义的分词器

3、默认分词器(standard)

normalizer:

规范化,主要针对 keyword 类型,在索引该字段或查询字段之前,可以先对原始数据进行一些简单的处理,然后再将处理后的结果当成一个词根存入倒排索引中,默认为 null,比如:

bash 复制代码
PUT index
{ "settings": { "analysis": { "normalizer": { "my_normalizer": { // 1
"type": "custom", "char_filter": [], "filter": ["lowercase", "asciifolding"] // 2
}
}
}
},"mappings": { "_doc": { "properties": { "foo": { "type": "keyword", "normalizer": "my_normalizer" // 3
}
}
}
}
}

代码 1:首先在 settings 中的 analysis 属性中定义 normalizer。

代码 2:设置标准化过滤器,示例中的处理器为小写、asciifolding。

代码 3:在定义映射时,如果字段类型为 keyword,可以使用 normalizer引用定义好的 normalizer

coerce:

数据不总是我们想要的,由于在转换 JSON body 为真正 JSON 的时候,整型数字 5 有可能会被写成字符串"5"或者浮点数 5.0,这个参数可以将数值不合法的部分去除。默认为 true。

例如:将字符串会被强制转换为整数、浮点数被强制转换为整数。

例如存在如下字段类型:

bash 复制代码
"number_one": { "type": "integer"}

声明 number_one 字段的类型为数字类型,那是否允许接收"6"字符串形式的数据呢?因为在 JSON 中,"6"用来赋给 int 类型的字段,也是能接受的,默认 coerce 为 true,表示允许这种赋值,但如果 coerce 设置为 false,此时 es只能接受不带双引号的数字,如果在coerce=false 时,将"6"赋值给 number_one时会抛出类型不匹配异常。

doc_values:

Doc values 的存在是因为倒排索引只对某些操作是高效的。 倒排索引的优势 在于查找包含某个项的文档,而对于从另外一个方向的相反操作并不高效,即:确定哪些项是否存在单个文档里,聚合需要这种次级的访问模式。

对于以下倒排索引:

如果我们想要获得所有包含 brown 的文档的词的完整列表,倒排索引是根据项来排序的,所以我们首先在词项列表中找到 brown ,然后扫描所有列,找到包含 brown 的文档。我们可以快速看到 Doc_1 和 Doc_2 包含 brown 这个 token。

然后,对于聚合部分,我们需要找到 Doc_1 和 Doc_2 里所有唯一的词项。 用倒排索引做这件事情代价很高: 我们会迭代索引里的每个词项并收集 Doc_1 和 Doc_2 列里面 token。这很慢而且难以扩展:随着词项和文档的数量增加,执行时间也会增加。

Doc values 通过转置两者间的关系来解决这个问题。倒排索引将词项映射到包含它们的文档,doc values 将文档映射到它们包含的词项:

当数据被转置之后,想要收集到 Doc_1 和 Doc_2 的唯一 token 会非常容易。获得每个文档行,获取所有的词项,然后求两个集合的并集。

doc_values 缺省是 true,即是开启的,并且只适用于非 text 类型的字段。

dynamic:

是否允许动态的隐式增加字段。在执行 index api 或更新文档 API 时,对于_source 字段中包含一些原先未定义的字段采取的措施,根据 dynamic 的取值,会进行不同的操作:

true,默认值,表示新的字段会加入到类型映射中。

false,新的字段会被忽略,即不会存入_souce 字段中,即不会存储新字段,也无法通过新字段进行查询。

strict,会显示抛出异常,需要新使用 put mapping api 先显示增加字段映射。

enabled:

是否建立索引,默认情况下为 true,es 会尝试为你索引所有的字段,但有时候某些类型的字段,无需建立索引,只是用来存储数据即可。也就是说,ELasticseaech 默认会索引所有的字段,enabled 设为 false 的字段,elasicsearch 会跳过字段内容,该字段只能从_source 中获取,但是不可搜。只有映射类型(type)和 object 类型的字段可以设置 enabled 属性。

eager_global_ordinals:

表示是否提前加载全局顺序号。Global ordinals 是一个建立在 doc values 和fielddata 基础上的数据结构, 它为每一个精确词按照字母顺序维护递增的编号。每一个精确词都有一个独一无二的编号 并且 精确词 A 小于精确词 B 的编号. Global ordinals 只支持 keyword 和 text 型字段,在 keyword 字段中, 默认是启用的 而在 text 型字段中 只有 fielddata 和相关属性开启的状态下才是可用的。

fielddata:

为了解决排序与聚合,elasticsearch 提供了 doc_values 属性来支持列式存储,但 doc_values 不支持 text 字段类型。因为 text 字段是需要先分析(分词),会影响 doc_values 列式存储的性能。

es 为了支持 text 字段高效排序与聚合,引入了一种新的数据结构(fielddata),使用内存进行存储。默认构建时机为第一次聚合查询、排序操作时构建,主要存储倒排索引中的词根与文档的映射关系,聚合,排序操作在内存中执行。因此fielddata 需要消耗大量的 JVM 堆内存。一旦 fielddata 加载到内存后,它将永久存在。

通常情况下,加载 fielddata 是一个昂贵的操作,故默认情况下,text 字段的字段默认是不开启 fielddata 机制。在使用 fielddata 之前请慎重考虑为什么要开启 fielddata。

ignore_above:

ignore_above 用于指定字段索引和存储的长度最大值,超过最大值的会被忽略。

ignore_malformed:

ignore_malformed 可以忽略不规则数据,对于 login 字段,有人可能填写的是 date 类型,也有人填写的是邮件格式。给一个字段索引不合适的数据类型发生异常,导致整个文档索引失败。如果 ignore_malformed 参数设为 true,异常会被忽略,出异常的字段不会被索引,其它字段正常索引。

index:

index 属性指定字段是否索引,不索引也就不可搜索,取值可以为 true 或者false,缺省为 true。

index_options:

index_options 控制索引时存储哪些信息到倒排索引中,,用于搜索和突出显示目的。

docs 只存储文档编号

freqs 存储文档编号和词项频率。

positions 文档编号、词项频率、词项的位置被存储

offsets 文档编号、词项频率、词项的位置、词项开始和结束的字符位置都被存储

fields:

fields 可以让同一文本有多种不同的索引方式,比如一个 String 类型的字段,可以使用 text 类型做全文检索,使用 keyword 类型做聚合和排序。

norms:

norms 参数用于标准化文档,以便查询时计算文档的相关性。norms 虽然对评分有用,但是会消耗较多的磁盘空间,如果不需要对某个字段进行评分,最好不要开启 norms。

null_value:

一般来说值为 null 的字段不索引也不可以搜索,null_value 参数可以让值为null 的字段显式的可索引、可搜索。

position_increment_gap:

文本数组元素之间位置信息添加的额外值。

举例,一个字段的值为数组类型:"names": [ "John Abraham", "Lincoln Smith"]。

为了区别第一个字段和第二个字段,Abraham 和 Lincoln 在索引中有一个间距,默认是 100。例子如下,这是查询"Abraham Lincoln"是查不到的:

bash 复制代码
PUT my_index/groups/1
{ "names": [ "John Abraham", "Lincoln Smith"]}
bash 复制代码
GET my_index/groups/_search
{ "query": { "match_phrase": {"names": { "query": "Abraham Lincoln"}}}}

指定间距大于 10 0 可以查询到:

bash 复制代码
GET my_index/groups/_search
{ "query": { "match_phrase": { "names": { "query": "Abraham Lincoln", "slop":101}}}}

想要调整这个值,在 mapping 中通过 position_increment_gap 参数指定间距即可。

properties:

Object 或者 nested 类型,下面还有嵌套类型,可以通过 properties 参数指定。比如:

bash 复制代码
PUT my_index
{ "mappings": { "my_type": { "properties": { "manager": { "properties": { "age": { "type": "integer" }, "name": { "type": "text" }}},"employees": { "type":"nested", "properties": { "age": { "type": "integer" }, "name": { "type":"text" }}}}}}}

对应的文档结构:

bash 复制代码
PUT my_index/my_type/1
{ "region": "US", "manager": { "name": "Alice White", "age": 30},"employees": [{"name": "John Smith", "age": 34},{ "name": "Peter Brown", "age": 26}]}

search_analyzer:

通常,在索引时和搜索时应用相同的分析器,以确保查询中的术语与反向索引中的术语具有相同的格式,如果想要在搜索时使用与存储时不同的分词器,则使用 search_analyzer 属性指定,通常用于 ES 实现即时搜索(edge_ngram)。

similarity:

指定相似度算法,其可选值:

BM25

当前版本的默认值,使用 BM25 算法。

classic

使用 TF/IDF 算法,曾经是 es,lucene 的默认相似度算法。

boolean

一个简单的布尔相似度,当不需要全文排序时使用,并且分数应该只基于查

询条件是否匹配。布尔相似度为术语提供了一个与它们的查询boost相等的分数。

store:

默认情况下,字段值被索引以使其可搜索,但它们不存储。这意味着可以查询字段,但无法检索原始字段值。通常这并不重要。字段值已经是_source 字段的一部分,该字段默认存储。如果您只想检索单个字段或几个字段的值,而不是整个_source,那么这可以通过字段过滤上下文 source filting context 来实现。

在某些情况下,存储字段是有意义的。例如,如果您有一个包含标题、日期和非常大的内容字段的文档,您可能只想检索标题和日期,而不需要从大型_source 字段中提取这些字段,可以将标题和日期字段的 store 定义为 ture。

term_vector:

Term vectors 包含分析过程产生的索引词信息,包括:

索引词列表

每个索引词的位置(或顺序)

索引词在原始字符串中的原始位置中的开始和结束位置的偏移量。

term vectors 会被存储,索引它可以作为一个特使的文档返回。

term_vector 可取值:

no

不存储 term_vector 信息,默认值。

yes

只存储字段中的值。

with_positions

存储字段中的值与位置信息。

with_offsets

存储字段中的值、偏移量

with_positions_offsets

存储字段中的值、位置、偏移量信息。

二、 元字段 meta-fields

一个文档根据我们定义的业务字段保存有数据之外,它还包含了元数据字段(meta-fields)。元字段不需要用户定义,在任一文档中都存在,有点类似于数据库的表结构数据。在名称上有个显著的特征,都是以下划线"_"开头。

大体分为五种类型:身份(标识)元数据、索引元数据、文档元数据、路由元数据以及其他类型的元数据,当然不是每个文档这些元字段都有的。

身份(标识)元数据

_index:文档所属索引 , 自动被索引,可被查询,聚合,排序使用,或者脚本里访问。

_type:文档所属类型,自动被索引,可被查询,聚合,排序使用,或者脚本里访问。

_id:文档的唯一标识,建索引时候传入 ,不被索引,可通过_uid 被查询,脚本里使用,不能参与聚合或排序。

_uid:由_type 和_id 字段组成,自动被索引 ,可被查询,聚合,排序使用,或者脚本里访问,6.0.0 版本后已废止。

索引元数据:

_all: 自动组合所有的字段值,以空格分割,可以指定分器词索引,但是整个值不被存储,所以此字段仅仅能被搜索,不能获取到具体的值。6.0.0 版本后已废止。

_field_names:索引了每个字段的名字,可以包含 null 值,可以通过 exists查询或 missing 查询方法来校验特定的字段

文档元数据:

_source : 一个 doc 的原生的 json 数据,不会被索引,用于获取提取字段值 ,启动此字段,索引体积会变大,如果既想使用此字段又想兼顾索引体积,可以开启索引压缩。_source 是可以被禁用的,不过禁用之后部分功能不再支持,这些功能包括:部分 update api、运行时高亮搜索结果索引重建、修改 mapping 以及分词、索引升级debug 查询或者聚合语句索引自动修复。

_size: 整个_source 字段的字节数大小,需要单独安装一个 mapper-size 插

件才能展示。

路由元数据:

_routing: 一个 doc 可以被路由到指定的 shard 上。

其他

_meta:一般用来存储应用相关的元信息。例如:

bash 复制代码
put /open-soft/_mapping
{ "_meta": { "class": "cn.enjoyedu.User", "version": {"min": "1.0", "max": "1.3"}}}
相关推荐
java1234_小锋2 小时前
Elasticsearch是如何实现Master选举的?
大数据·elasticsearch·搜索引擎
梦幻通灵8 小时前
ES分词环境实战
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客8 小时前
Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
大数据·运维·elasticsearch·搜索引擎·全文检索
小黑屋说YYDS14 小时前
ElasticSearch7.x入门教程之索引概念和基础操作(三)
elasticsearch
Java 第一深情16 小时前
Linux上安装单机版ElasticSearch6.8.1
linux·elasticsearch·全文检索
KevinAha1 天前
Elasticsearch 6.8 分析器
elasticsearch
wuxingge1 天前
elasticsearch7.10.2集群部署带认证
运维·elasticsearch
Elastic 中国社区官方博客1 天前
Elasticsearch:如何部署文本嵌入模型并将其用于语义搜索
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索
Dreams°1232 天前
【大数据测试 Elasticsearch 的标准--超详细篇】
大数据·elasticsearch·jenkins
鸠摩智首席音效师2 天前
如何在 Elasticsearch 中配置 SSL / TLS ?
elasticsearch·ssl