Elasticsearch索引结构
一个Elasticsearch索引的主要结构如下:
{
"test_index": {
"aliases": {},
"mappings": {
"my_type": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"settings": {
"index": {
"creation_date": "1601371474234",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "Xov1AxZ9R5aV2Ji4ZP5YjA",
"version": {
"created": "6020299"
},
"provided_name": "test_index"
}
}
}
}
从上面的结构,我们可以看出Elasticsearch的索引结构主要包含mapping与setting两部分,下面就介绍一下mapping与setting
Mapping
Mapping类似于关系型数据库的Schema,主要包含以下内容:
1、定义索引中字段的名称
2、定义字段的数据类型,如:字符串、数字、boolean等
3、可对字段设置倒排索引的相关配置,如是否需要分词,使用什么分词器
注:从7.x开始,一个Mapping只属于一个索引的type,即一个索引只能有一个类型type,默认type 为:_doc
下面是一个典型的mappings结构
"mappings": { #mappings关键字
"my_type": { #类型名称
"properties": { #字段名称和类型的定义
"name": { #字段名
"type": "text", #字段类型
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
字段数据类型
每个字段都有一个数据type,可以是:
1、简单类型等text,keyword,date,long, double,boolean或ip。
2、支持JSON的分层性质的类型,如 object或nested。
或一种特殊类型的像geo_point, geo_shape或completion。
为不同的目的以不同的方式对同一字段建立索引通常很有用。例如,一个string字段可以被索引为text全文搜索的字段,也可以被索引keyword为排序或聚合的字段。或者,您可以使用standard分析器, english分析器和 french分析器为字符串字段建立索引。
大多数数据类型通过fields参数支持多字段,比如上面例子中我们通过fields来定义keyword的字段,这样我们就可以通过name.keyword来实现排序或者聚合
Mapping数据类型的详细介绍可以看:一文搞懂 ElasticSearch的数据类型
注:mapping中字段类型一旦设定后 禁止直接修改。因为lucene实现的倒排索引生成后不允许修改,所以我们在定义字段类型时候要考虑清楚
一般Elasticsearch会根据我们输入的内容进行动态映射
Elasticsearch有动态映射功能(Dynamic Mapping )
Dynamic Mapping 翻译为动态Mapping,功能如下:
1、在写入文档时,如果索引不存在,会自动创建索引
2、这种机制,使得我们无需手动定义mappings。Elasticsearch会自动根据文档信息,推算出字段的类型
3、有的时候,Elasticsearch可能会推算不对,如:地理位置信息
4、当类型推算得不对时,可能导致一些功能无法正常运行,如Range查询。
尽管动态映射对于入门非常有用,但有时您仍需要指定自己的显式映射,,因为动态映射的类型和分词器不一定符合你的要求。您可以在创建索引时创建字段Mapping 映射 ,也可以使用PUT Mapping API将字段添加到现有索引中。
我们在创建索引时可以指定一个mapping映射,如下所示:
{
"mappings": {
"_doc": { #添加名为_doc的映射类型
"properties": { #指定字段或属性
"title": { "type": "text" }, #指定title字段的类型为text
"name": { "type": "text" },
"age": { "type": "integer" },
"created": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
}
}
}
}
我们也可以在已有的类型上添加字段时显式指定类型和分词器
PUT /my_index/_mapping/my_type
{
"properties": {
"english_title": {
"type": "text",
"analyzer": "english"
}
}
}
注:_mapping方法表示修改mapping属性
注:已存在的字段,一旦数据被写入,就不再支持修改字段定义,我们修改已存在的字段属性,是通过Reindex api,即重建索引来实现的,在数据较多的时候,开销较大
映射参数
mappings 中field定义有以下选择
"field": {
"type": "text", //文本类型 ,指定类型
"index": "false"// ,设置成false,字段将不会被索引
"analyzer":"ik"//指定分词器
"boost":1.23//字段级别的分数加权
"doc_values":false//对not_analyzed字段,默认都是开启,analyzed字段不能使用,对排序和聚合能提升较大性能,节约内存,如果您确定不需要对字段进行排序或聚合,或者从script访问字段值,则可以禁用doc值以节省磁盘空间:
"fielddata":{"loading" : "eager" }//Elasticsearch 加载内存 fielddata 的默认行为是 延迟 加载 。 当 Elasticsearch 第一次查询某个字段时,它将会完整加载这个字段所有 Segment 中的倒排索引到内存中,以便于以后的查询能够获取更好的性能。
"fields":{"keyword": {"type": "keyword","ignore_above": 256}} //可以对一个字段提供多种索引模式,同一个字段的值,一个分词,一个不分词
"ignore_above":100 //超过100个字符的文本,将会被忽略,不被索引
"include_in_all":ture//设置是否此字段包含在_all字段中,默认是true,除非index设置成no选项
"index_options":"docs"//4个可选参数docs(索引文档号) ,freqs(文档号+词频),positions(文档号+词频+位置,通常用来距离查询),offsets(文档号+词频+位置+偏移量,通常被使用在高亮字段)分词字段默认是position,其他的默认是docs
"norms":{"enable":true,"loading":"lazy"}//分词字段默认配置,不分词字段:默认{"enable":false},存储长度因子和索引时boost,建议对需要参与评分字段使用 ,会额外增加内存消耗量
"null_value":"NULL"//设置一些缺失字段的初始化值,只有string可以使用,分词字段的null值也会被分词
"position_increament_gap":0//影响距离查询或近似查询,可以设置在多值字段的数据上火分词字段上,查询时可指定slop间隔,默认值是100
"store":false//是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值
"search_analyzer":"ik"//设置搜索时的分词器,默认跟ananlyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能
"similarity":"BM25"//默认是TF/IDF算法,指定一个字段评分策略,仅仅对字符串型和分词类型有效
"term_vector":"no"//默认不存储向量信息,支持参数yes(term存储),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 对快速高亮fast vector highlighter能提升性能,但开启又会加大索引体积,不适合大数据量用
}
Setting
setting为ES索引的配置属性,索引的配置项按是否可以更改分为静态(static)属性与动态配置,所谓的静态配置即索引创建后不能修改,静态配置只能在创建索引时或者在状态为 closed index的索引(闭合的索引)上设置
下面介绍一下索引的静态配置和动态配置
索引静态配置
index.number_of_shards :主分片数,默认为5.只能在创建索引时设置,不能修改
index.shard.check_on_startup :是否在索引打开前检查分片是否损坏,当检查到分片损坏将禁止分片被打开
可选值:false:不检测;checksum:只检查物理结构;true:检查物理和逻辑损坏,相对比较耗CPU;fix:类同与false,7.0版本后将废弃。默认值:false。
index.codec:数据存储的压缩算法,默认算法为LZ4,也可以设置成best_compression,best_compression压缩比较好,但存储性能比LZ4差
index.routing_partition_size :路由分区数,默认为 1,只能在索引创建时设置。此值必须小于index.number_of_shards,如果设置了该参数,其路由算法为: (hash(_routing) + hash(_id) % index.routing_parttion_size ) % number_of_shards。如果该值不设置,则路由算法为 hash(_routing) % number_of_shardings,_routing默认值为_id。
索引动态配置
index.number_of_replicas :每个主分片的副本数,默认为 1,该值必须大于等于0
index.auto_expand_replicas :基于可用节点的数量自动分配副本数量,默认为 false(即禁用此功能)
index.refresh_interval :执行刷新操作的频率,这使得索引的最近更改可以被搜索。默认为 1s。可以设置为 -1 以禁用刷新。
index.max_result_window :用于索引搜索的 from+size 的最大值。默认为 10000
index.max_rescore_window : 在搜索此索引中 rescore 的 window_size 的最大值
index.blocks.read_only :设置为 true 使索引和索引元数据为只读,false 为允许写入和元数据更改。
index.blocks.read_only_allow_delete:与index.blocks.read_only基本类似,唯一的区别是允许删除动作。
index.blocks.read :设置为 true 可禁用对索引的读取操作
index.blocks.write :设置为 true 可禁用对索引的写入操作。
index.blocks.metadata :设置为 true 可禁用索引元数据的读取和写入。
index.max_refresh_listeners :索引的每个分片上可用的最大刷新侦听器数
index.max_docvalue_fields_search:一次查询最多包含开启doc_values字段的个数,默认为100。
我们可以在创建索引时就进行settings配置
PUT /test_setting
{
"settings": {
"number_of_shards": "3",
"number_of_replicas": "1"
}
}
对于已存在的索引,我们想要修改它的动态配置,可以使用_settings方法
PUT /test_setting/_settings
{
"number_of_replicas": "0"
}
这样test_setting索引的副本数就变为0了
最后更新于 2022年6月26日