一、Index配置 Index modules | Elasticsearch Guide [8.10] | Elastic

Es 8.x索引配置 settings 的配置项可分为以下几种类型:

1、静态配置项

所谓静态配置项就是在创建 index 时指定,创建后不能再修改。

1.1、分片相关的配置

配置项功能备选值默认值其他说明
index.number_of_shards当前 index 拥有的主分片数5最大为 1024
index.shard.check_on_startup在启动时是否检查分片false: 打开时不检查损坏; true: 检查物理损坏; checksum: 物理损坏和逻辑损坏都检查false
index.routing_partition_size设置的自定义路由可以转到几个分片上大于 1 小于

1.2、压缩算法设置

配置项功能备选值默认值其他说明
index.codec数据压缩算法设置default:默认全长 LZ4 压缩算法; best_compression:拥有更高压缩比,但存储性能会降低default

1.3、排序设置

配置项功能备选值其他说明
index.sort.field用于排序的字段,多个使用数组排序的字段只能是 boolean,numeric,date,keyword 类型
index.sort.order排序方式asc: 正序; desc: 倒序
index.sort.mode用于多个值的字段的排序模式max : 选最小值; min:选最大值
index.sort.missing当排序字段不存在时指定哪种排序_first : 按第一个字段来排序; _last:按最后一个字段来排序

1.4、数据存储设置

配置项功能备选值
index.store.type存储的方式fs:文件系统; simplefs:随机文件存储; niofs:非阻塞文件系统存储; mmapfs:mmap 内存映射存储
index.store.preload将索引文件预加载到内存中* :所有数据; nvd:存储各个影响分数的因子的数据; dvd:文档的值; tim:文件字典; doc:发布清单; dim:点数据

2、动态配置项

所谓动态配置项是在创建 index 后,还可以通过 API 动态来修改。

2.1、分片相关配置

配置项功能备选值默认值其他说明
index.number_of_replicas每个主分片拥有的副本数1
index.auto_expand_replicas是否根据节点数量,自动扩展副本数量false也可以设置 0-5 的数字
index.routing.allocation.enable控制此索引的路由分片分配all: 针对所有分片; primaries: 所有主分片; new_primaries: 仅允许分配新建的主分片; none: 不允许分片all
index.routing.reblance.enable开启分片重新负载均衡的开关all: 针对所有分片; primaries: 所有主分片; replicas: 所有副本分片; none: 不允许分片all

2.2、查询相关的设置

配置项功能备选值默认值其他说明
index.max_result_window一次最多获取多少条记录10000
index.max_inner_result_window内层的 hits 的条数和最高的命中的数据条数100
index.max_rescore_window重新打分请求的最大数量10000
index.max_docvalue_fields_search查询中最大允许的 docvalue-field 的数量100
index.max_script_fields在查询中 script_fields 的最大数量10000
index.highlight.max_analyzed_offset高亮显示最大的字符数
index.max_terms_count查询语句中 terms 子名的最大数量65536
index.max_regex_length在正则查询表达式中使用的正则表达式最大长度1000

2.3、索引读写开关相关的配置

配置项功能
index.blocks.read_only是否只允许索引和元数据的读取操作
index.blocks_read_only_allow_delete是否只允许索引的读操作和删除操作
index.blocks.read是否禁止索引数据的读取
index.blocks.write是否禁止索引数据的写操作
index.blocks.metadata是否禁止元数据的读写操作

2.4、刷新索引的设置

配置项功能备选值默认值其他说明
index.refresh.interval执行刷新操作的频率,索引更新多久才对搜索可见-1: 表示禁止刷新; 1s: 表示 1 秒1s
index.max_refresh_listeners每个分片上最大刷新监听器的数量

2.5、translog 设置

配置项功能备选值默认值其他说明
index.translog.sync_interval将数据同步到磁盘的频率5s
index.translog.durablility将数据刷新到磁盘的时机request: 每次请求都同步刷新; async: 后台按照刷新频率定时刷新
index.translog.flush_threshold_size刷新日志的最大阀值512M
index.translog.retention.size中继日志文件保存数据的总容量512M
index.translog.retention.age中继日志文件保存的最长时间12h

2.6、慢日志设置

(1) 慢搜索日志设置

配置项功能默认值
index.search.slowlog.threshold.query.warnwarn 级别的慢搜索日志的阀值 (即多少秒的搜索才算 warn 级别的慢搜索)10s
index.search.slowlog.threshold.query.infoinfo 级别的慢搜索日志的阀值 (即多少秒的搜索才算 info 级别的慢搜索)10s
index.search.slowlog.threshold.query.debugdebug 级别的慢搜索日志的阀值 (即多少秒的搜索才算 debug 级别的慢搜索)10s
index.search.slowlog.threshold.query.tracetrace 级别的慢搜索日志的阀值 (即多少秒的搜索才算 trace 级别的慢搜索)10s
index.search.slowlog.threshold.fetch.warnwarn 级别的慢获取数据日志的阀值 (即多少秒的获取数据才算 warn 级别的慢获取)10s
index.search.slowlog.threshold.fetch.infoinfo 级别的慢获取日志的阀值 (即多少秒的获取数据才算 info 级别的慢获取)10s
index.search.slowlog.threshold.fetch.debugwarn 级别的慢获取日志的阀值 (即多少秒的获取数据才算 debug 级别的慢获取)500ms
index.search.slowlog.threshold.fetch.tracewarn 级别的慢获取日志的阀值 (即多少秒的搜索才算 trace 级别的慢获取)10s
index.search.slowlog.level慢搜索日志的级别

(2) 慢索引日志设置

配置项功能默认值
index.indexing.slowlog.threshold.index.warnwarn 级别的慢索引日志的阀值 (即多少秒的索引才算 warn 级别的慢索引)10s
index.indexing.slowlog.threshold.index.infoinfo 级别的慢索引日志的阀值 (即多少秒的索引才算 info 级别的慢索引)10s
index.indexing.slowlog.threshold.index.debugdebug 级别的慢索引日志的阀值 (即多少秒的索引才算 debug 级别的慢索引)10s
index.indexing.slowlog.threshold.index.tracetrace 级别的慢索引日志的阀值 (即多少秒的索引才算 trace 级别的慢索引)10s
index.indexing.slowlog.level慢索引日志的级别
index.indexing.slowlog.source记录 source 的大小(false/0: 记录整个慢日志; 1000: 记录 source 中的前 1000 个字符)

2.7、mapping 相关设置

配置项功能备选值默认值其他说明
index.mapping.total_fields_limit一次索引中字段数的最大数量1000
index.mapping.depth.limit索引中字段的深度限制 (即字段可以嵌套多少层)20
index.mapping.nested_fields_limit一个索引中内嵌字段的最大数量50

3、示例

PUT/my_index
{
    "settings": {
        "index": {
            "number_of_shards": "1",
            "number_of_replicas": "1",
            "refresh_interval": "60s",
            "analysis": {
                "filter": {
                    "tsconvert": {
                        "type": "stconvert",
                        "convert_type": "t2s",
                        "delimiter": ","
                    },
                    "synonym": {
                        "type": "synonym",
                        "synonyms_path": "analysis/synonyms.txt"
                    }
                },
                "analyzer": {
                    "ik_max_word_synonym": {
                        "filter": ["synonym",
                        "tsconvert",
                        "standard",
                        "lowercase",
                        "stop"],
                        "tokenizer": "ik_max_word"
                    },
                    "ik_smart_synonym": {
                        "filter": ["synonym",
                        "standard",
                        "lowercase",
                        "stop"],
                        "tokenizer": "ik_smart"
                    }
                },
                "mapping": {
                    "coerce": "false",
                    "ignore_malformed": "false"
                },
                "indexing": {
                    "slowlog": {
                        "threshold": {
                            "index": {
                                "warn": "2s",
                                "info": "1s"
                            }
                        }
                    }
                },
                "provided_name": "hospital_202101070533",
                "query": {
                    "default_field": "timestamp",
                    "parse": {
                        "allow_unmapped_fields": "false"
                    }
                },
                "requests": {
                    "cache": {
                        "enable": "true"
                    }
                },
                "search": {
                    "slowlog": {
                        "threshold": {
                            "fetch": {
                                "warn": "1s",
                                "info": "200ms"
                            },
                            "query": {
                                "warn": "1s",
                                "info": "500ms"
                            }
                        }
                    }
                }
            }
        }
    }
}

固定属性

  • index.creation_date:顾名思义索引的创建时间戳。

  • index.uuid:索引的 uuid 信息。

  • index.version.created:索引的版本号。

索引静态配置
  • index.number_of_shards:索引的主分片数,默认值是 5。这个配置在索引创建后不能修改;在 es 层面,可以通过 es.index.max_number_of_shards 属性设置索引最大的分片数,默认为 1024

  • index.codec:数据存储的压缩算法,默认值为 LZ4,可选择值还有 best_compression,它比 LZ4 可以获得更好的压缩比(即占据较小的磁盘空间,但存储性能比 LZ4 低)。

  • index.routing_partition_size:路由分区数,如果设置了该参数,其路由算法为:(hash(routing) + hash(id) % index.routing_parttion_size ) % number_of_shards。如果该值不设置,则路由算法为 hash(routing) % number_of_shardings,routing 默认值为 _id。

静态配置里,有重要的部分是配置分析器(config analyzers)。

  • index.analysis

    :分析器最外层的配置项,内部主要分为 :

    • char_filter:定义新的字符过滤器件。

    • tokenizer:定义新的分词器。

    • filter:定义新的 token filter,如同义词 filter。

    • analyzer:配置新的分析器,一般是 char_filter、tokenizer 和一些 token filter 的组合。

索引动态配置
  • index.number_of_replicas:索引主分片的副本数,默认值是 1,该值必须大于等于 0,这个配置可以随时修改。

  • index.refresh_interval:执行新索引数据的刷新操作频率,该操作使对索引的最新更改对搜索可见,默认为 1s。也可以设置为 -1 以禁用刷新

二、Mapping配置

1、什么是 Mapping

Mapping 类似于数据库中的表结构定义 schema,它的主要作用是:用来定义索引中的字段的名称、定义字段的数据类型、定义字段类型的一些其它参数,比如字符串、数字、布尔字段,倒排索引的相关配置,设置某个字段为不被索引、记录 position 等。每一种数据类型都有对应的使用场景,并且每个文档都有映射,但是在大多数使用场景中,我们并不需要显示的创建映射,因为 ES 中实现了动态映射。我们在索引中写入一个下面的 JSON 文档:

{
    "name":"jack",
    "age":18,
    "birthDate": "1991-10-05"
}

在动态映射的作用下,name 会映射成 text 类型,age 会映射成 long 类型,birthDate 会被映射为 date 类型,映射的索引信息如下。

{
  "mappings": {
    "_doc": {
      "properties": {
        "age": {
          "type": "long"
        },
        "birthDate": {
          "type": "date"
        },
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        }
      }
    }
  }
}

2、Mapping 的数据类型

ES 字段类型类似于 MySQL 中的字段类型,ES 字段类型主要有:核心类型、复杂类型、地理类型、特殊类型,常见的 ELasticSearch 数据类型如下:

一级分类二级分类具体类型
核心类型字符串类型string,text,keyword
整数类型integer,long,short,byte
浮点类型double,float,half_float,scaled_float
逻辑类型boolean
日期类型date
范围类型range(Integer_range,long_range,date_range...)
二进制类型binary (BASE64 的二进制)
复合类型数组类型array
对象类型object
嵌套类型nested
地理类型地理坐标类型geo_point
地理地图geo_shape
特殊类型IP 类型ip
.........

下面简单介绍一下常用的类型

2.1、字符串类型

从 ElasticSearch 5.x 开始不再支持 string,由 text 和 keyword 类型替代:

【text 类型】:

适用于需要被全文检索的字段,因为它会分词,例如新闻正文、邮件内容等比较长的文字,text 类型会被 Lucene 分词器(Analyzer)处理为一个个词项,并使用 Lucene 倒排索引存储,text 字段不能被用于排序。如果需要使用该类型的字段只需要在定义映射时指定 JSON 中对应字段的 type 为 text。

【keyword】

只能通过精确值搜索到,适合简短、结构化字符串,例如主机名、姓名、商品名称等,可以用于过滤、排序、聚合检索,也可以用于精确查询

总结:

对 text 类型的字段,会先使用分词器分词,生成倒排索引,用于之后的搜索。

对 keyword 类型的字段,不会分词,搜索时只能精确查找。

2.1.1、关于 text 类型的常用参数:
  1. analyzer:指明该字段用于索引时和搜索时的分析字符串的分词器(使用 search_analyzer 可覆盖它)。 默认为索引分析器或标准分词器

  2. fielddata:指明该字段是否可以使用内存中的 fielddata 进行排序,聚合或脚本编写?默认值为 false,可取值 true 或 false。(排序,分组需要指定为 true)

  3. fields:【多数类型】text 类型字段会被分词搜索,不能用于排序,而当字段既要能通过分词搜索,又要能够排序,就要设置 fields 为 keyword 类型进行聚合排序。

  4. index:【是否被索引】设置该字段是否可以用于搜索。默认为 true,表示可以用于搜索。

  5. search_analyzer:设置在搜索时,用于分析该字段的分析器,默认是【analyzer】参数的值。

  6. search_quote_analyzer:设置在遇到短语搜索时,用于分析该字段的分析器,默认是【search_analyzer】参数的值。

  7. index_options

    :【索引选项】用于控制在索引过程中哪些信息会被写入到倒排索引中。

    • docs:只索引文档号到倒排索引中,但是并不会存储;

    • freqs:文档号和关键词的出现频率会被索引,词频用于给文档进行评分,重复词的评分会高于单个次评分;

    • positions:文档号、词频和关键词 term 的相对位置会被索引,相对位置可用于编辑距离计算和短语查询 (不分词那种);

    • offsets:文档号、词频、关键词 term 的相对位置和该词的起始字符串偏移量。

2.1.2、关于 keyword 类型的常用参数:
  1. eager_global_ordinals:指明该字段是否加载全局序数?默认为 false,不加载。 对于经常用于术语聚合的字段,启用此功能是个好主意。

  2. fields:指明能以不同的方式索引该字段相同的字符串值,例如用于搜索的一个字段和用于排序和聚合的多字段。

  3. index:指明该字段是否可以被搜索,默认为 true,表示可以被搜索

  4. index_options:指定该字段应将哪些信息存储在索引中,以便用于评分。默认为 docs,但也可以设置为 freqs,这样可以在计算分数时考虑术语频率

  5. norms:在进行查询评分时,是否需要考虑字段长度,默认为 false,不考虑

  6. ignore_above:默认值是 256,该参数的意思是,当字段文本的长度大于指定值时,不会被索引,但是会存储。即当字段文本的长度大于指定值时,聚合、全文搜索都查不到这条数据。ignore_above 最大值是 32766 ,但是要根据场景来设置,比如说中文最大值 应该是设定在 10922 。

2.2、数字类型

ES 支持的数字类型有:

整型数字类型:integer 类型、long 类型、short 类型、byte 类型。

浮点型数字类型: double 类型、 float 类型、 half_float 类型、 scaled_float 类型。

这类数据类型都是以确切值索引的,可以使用 term 查询精确匹配。数字类型的字段在满足需求的前提下应当尽量选择范围较小的数据类型,字段长度越短,搜索效率越高,对于浮点数,可以优先考虑使用 scaled_float 类型,该类型可以通过缩放因子来精确浮点数,例如 12.34 可以转换为 1234 来存储。

  • long 带符号的 64 位整数,最小值 - 2^63,最大值 2^63-1

  • integer 带符号的 32 位整数,最小值 - 2^31,最大值 2^31-1

  • short 带符号的 16 位整数,最小值 - 32768,最大值 32767

  • byte 带符号的 8 位整数,最小值 - 128,最小值 127

  • double 双精度 64 位 IEEE 754 浮点数

  • float 单精度 32 位 IEEE 754 浮点数

  • half_float 半精度 16 位 IEEE 754 浮点数

  • scaled_float 带有缩放因子的缩放类型浮点数,依靠一个 long 数字类型通过一个固定的 (double 类型) 缩放因数进行缩放。

整数类型:byte(8 位 1 字节), short(16 位 2 字节), int(32 位 4 字节), long(4 位 8 字节) 浮点数:float(32 位 4 字节),double(64 位 8 字节)

2.3、日期类型

在 ES 中日期可以为以下形式:格式化的日期字符串,例如 2020-03-17 00:00、2020/03/17 时间戳(和 1970-01-01 00:00:00 UTC 的差值),单位毫秒或者秒即使是格式化的日期字符串,ES 底层依然采用的是时间戳的形式存储。

日期类型一般会结合一个 mapping 参数来使用:

format :自定义的日期格式,默认:strict_date_optional_time || epoch_millis。

-- 创建索引并设置结构
 
-- 7.X写法
PUT test_index
{
  "mappings": {
    "properties": {
      "date1": {
        "type": "date"
      },
      "date2": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "date3": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
      }
    }
  }
}
 
说明:es7.x前的版本需要在 properties 外添加 "_doc": {}
 
 
#添加2条数据
POST test_index/_doc
{
  "dateTimeFormat": "2015-01-01 12:10:30"
}
 
 
PUT test_index/_doc/1
{
  "date1": 1577808000000,
  "date2": "2020-01-01 00:00:00",
  "date3": "2020/01/01"
}
PUT test_index/_doc/2
{
  "date1": 1577808000001,
  "date2": "2020-01-01 00:00:01",
  "date3": "2020/01/01"
}
#查询测试
GET test_index/_search
{
  "sort": [
    {
      "date2": {
        "order": "desc"
      }
    }
  ]
}

2.4、布尔类型

JSON 文档中同样存在布尔类型,不过 JSON 字符串类型也可以被 ES 转换为布尔类型存储,前提是字符串的取值为 true 或者 false,布尔类型常用于检索中的过滤条件。

2.5、二进制类型

二进制类型 binary 接受 BASE64 编码的字符串,默认 store 属性为 false,并且不可以被搜索。

2.6、范围类型

范围类型可以用来表达一个数据的区间,所以会用到 gt、gte、lt、lte… 等逻辑表示符。可以分为 6 种:integer_range、float_range、long_range、double_range、date_range 以及 ip_range。

  • integer_range,带符号的 32 位整数区间,最小值 - 231,最大值 231-1

  • long_range,带符号的 64 位整数区间,最小值 - 263,最小值 263-1

  • float_range,单精度 32 位 IEEE 754 浮点数区间

  • double_range,双精度 64 位 IEEE 754 浮点数区间

  • date_range,日期值范围,表示为系统纪元以来经过的无符号 64 位整数毫秒

  • ip_range,支持 IPv4 或 IPv6(或混合)地址 ip 值范围

-- 7.X写法
PUT test_index
{
  "mappings": {
    "properties": {
      "data1": {
        "type": "integer_range"
      },
      "data2": {
        "type": "float_range"
      },
      "data3": {
        "type": "date_range",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "data4": {
        "type": "ip_range"
      }
    }
  }
}
说明:es7.x前的版本需要在 properties 外添加 "_doc": {}
 
 
PUT test_index/_doc/1
{
  "date1": {
    "gte": 100,
    "lte": 200
  },
  "date2": {
    "gte": 21.21,
    "lte": 22
  },
  "date3": {
    "gte": "2020-01-01 00:00:00",
    "lte": "2020-01-02 00:00:00"
  },
  "date4": {
    "gte": "192.168.192.10",
    "lte": "192.168.192.11"
  }
}

2.7、对象类型

对象类型即一个 JSON 对象,JSON 字符串允许嵌套对象,所以一个文档可以嵌套多个、多层对象。可以通过对象类型来存储二级文档,不过由于 Lucene 并没有内部对象的概念,所以 ES 会将原 JSON 文档扁平化,例如有下面这样的文档:

PUT test_index
{
  "mappings": {
    "properties": {
      "user": {
        "type": "object"
      }
    }
  }
}
 
PUT test_index/_doc/1
{
  "username": {
    "first": "zhang",
    "last": "san"
  }
}

上面我们看到都是一个个分开的字段,而实际上 ES 会将其转换为以下格式,并通过 Lucene 存储,即使 name 是 object 类型:

{
    "username.first": "zhang",
    "username.last": "san"
}

所以我们在进行条件搜索时也必须使用这种方式:

GET test_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "username.first": "zhang"
          }
        }
      ]
    }
  }
}

bool 查询的使用

  • must 查询必须匹配某些条件才可以返回

  • must_not查询必须不匹配某些条件

  • should当查询满足此条件时, 会增加其_score

  • filter 必须匹配, 但是结果不会计算分值。

2.8、嵌套类型

嵌套类型可以看成是一个特殊的对象类型,在文档属性是一个对象数组时使用,它允许对象数组彼此独立地编制索引和查询,例如文档:

{
  "address": [
    {
      "country": "CN",
      "city": "BJ"
    },
    {
      "country": "US",
      "city": "NY"
    }
  ]
}

示例中的文档在实际存储时,会被拆解为两个数组字段:

{
    "adress.country" : ["CN,"US"],
    "address.city" : ["BJ","NY"]
}

这样一来,单个对象内部,country 字段和 city 字段之间的匹配关系就丢失了。换句话说,使用 CN 与 NY 作为共同条件检索的文档时,上述文档也会被检索出来,这在逻辑上就出现了错误;

在示例中使用了 bool 组合查询,要求 country 字段为 CN 而 city 字段为 NY。这样的文档显然并不存在,但由于数组中的对象被平铺为两个独立的数组字段,文档仍然会被检索出来。

为了解决对象类型在数组中丢失内部字段之间匹配关系的问题,Elasticsearch 提供了一种特殊的对象类型 nested。这种类型会为数组中的每一个对象创建一个单独的文档, 以保存对象的字段信息并使它们可检索。由于这类文档并不直接可见,而是藏置在父文档之中,所以这类文档可以称为为隐式文档 或 嵌入文档

测试 nested 查询

nested 查询只能针对 nested 类型字段,需要通过 path 参数指定 nested 类型字段的路径,而在 query 参数中则包含了针对隐式文档的具体查询条件。

-- 删除索引
DELETE test_index
 
-- 创建索引
PUT test_index
{
  "mappings": {
    "properties": {
      "address": {
        "type": "nested"
      }
    }
  }
}
 
-- 索引添加文档,id设置为1
PUT test_index/_doc/1
{
  "address": [
    {
      "country": "CN",
      "city": "BJ"
    },
    {
      "country": "US",
      "city": "NY"
    }
  ]
}
 
 
#查询测试
GET test_index/_search
{
  "query": {
    "nested": {
      "path": "address",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "address.country": "CN"
              }
            },
            {
              "match": {
                "address.city": "NY"
              }
            }
          ]
        }
      }
    }
  }
}

在示例中再次使用 CN 与 NY 共同作为查询条件,但由于使用 nested 类型后会将数组中的对象转换成隐式文档,所以在 nested 查询中将不会有文档返回了。将条件更换为 CN 和 BJ,则有文档返回。

3、Mapping 的主要参数

3.1、mapping 组成

一个 mapping 主要有两部分组成:metadatamapping

metadata 元数据字段用于自定义如何处理文档关联的数据。例如:

  • _index:用于定义 document 属于哪个 index

  • type:类型,7.x 已经移除的概念, 6.x 默认为doc

  • _id:document 的唯一 id

  • _source:存放原始的 document 数据

  • size:source 字段中存放的数据的大小

mapping 中包含字段的类型和参数。本文主要介绍的 mapping 参数就需要在 field 中去定义。例如:

  • type:设置字段对应的类型,常见的有 text,keyword 等

  • analyzer:指定一个用来文本分析的索引或者搜索 text 字段的分析器, 应用于索引以及查询.

3.2、mapping 参数

主要参数如下:

  • analyzer:只能用于 text 字段,用于根据需求设置不通的分词器,默认是 ES 的标准分词

  • boost:默认值为 1。用于设置字段的权重,主要应用于查询时候的评分

  • coerce:默认是 true。主要用于清理脏数据来匹配字段对应的类型。例如字符串 “5” 会被强制转换为整数,浮点数 5.0 会被强制转换为整数

  • copy_to:能够把几个字段拼成一个字段。老字段和新组成的字段都可以查询

  • doc_values:默认值为 true。Doc Values 和倒排索引同时生成,本质上是一个序列化的 列式存储。列式存储适用于聚合、排序、脚本等操作,也很适合做压缩。如果字段不需要聚合、排序、脚本等操作可以关闭掉,能节省磁盘空间和提升索引速度。

  • dynamic:

    默认值为 true。默认如果插入的 document 字段中有 mapping 没有的,会自动插入成功,并自动设置新字段的类型;如果一个字段中插入一个包含多个字段的 json 对象也会插入成功。但是这个逻辑可以做限制:

    • ture: 默认值,可以动态插入.

    • false:数据可写入但是不能被索引分析和查询,但是会保存到_source 字段。

    • strict:无法写入

  • eager_global_ordinals:默认值为 false。设置每 refresh 一次就创建一个全局的顺序映射,用于预加载来加快查询的速度。需要消耗一定的 heap。

  • enabled:默认值为 true。设置字段是否索引分析。如果设置为 false,字段不对此字段索引分析和 store,会导致此字段不能被查询和聚合,但是字段内容仍然会存储到_source 中。

  • fielddata:默认值为 false,只作用于 text 字段。默认 text 字段不能排序,聚合和脚本操作,可以通过开启此参数打开此功能。但是会消耗比较大的内存。

  • fields:可以对一个字段设置多种索引类型,例如 text 类型用来做全文检索,再加一个 keyword 来用于做聚合和排序。

  • format:用于 date 类型。设置时间的格式。

  • ignore_above:默认值为 256,作用于 keyword 类型。指示该字段的最大索引长度(即超过该长度的内容将不会被索引分析),对于超过 ignore_above 长度的字符串,analyzer 不会进行索引分析,所以超过该长度的内容将不会被搜索到。注意:keyword 类型的字段的最大长度限制为 32766 个 UTF-8 字符,text 类型的字段对字符长度没有限制

  • ignore_malformed:默认为 false。插入新 document 的时候,是否忽略字段的类型,默认字段类型必须和 mapping 中设置的一样

  • index_options:

    默认值为 positions,只作用于 text 字段。控制将哪些信息添加到倒排索引中以进行搜索和突出显示。有 4 个选项:

    • docs 添加文档号

    • freqs 添加文档号和词频

    • positions 添加文档号,词频,位置

    • offsets 添加文档号,词频,位置,偏移量

  • index:默认值为 true。设置字段是否会被索引分析和可以查询

  • meta:可以给字段设置 metedata 字段,用于标记等

  • normalizer:可以对字段做一些标准化规则,例如字符全部大小写等

  • norms:默认值为 true。默认会存储了各种规范化因子,在查询的时候使用这些因子来计算文档相对于查询的得分,会占用一部分磁盘空间。如果字段不用于检索,只是过滤,查询等精确操作可以关闭。

  • null_value:null_value 意味着无法索引或搜索空值。当字段设置为 null , [] , 和 [null](这些 null 的表示形式都是等价的),它被视为该字段没有值。通过设置此字段,可以设置控制可以被索引和搜索。

  • properties:如果这个字段有嵌套属性,包含了多个子字段。需要用到 properties

  • search_analyzer:默认值和 analyzer 相同。在查询时,先对要查询的 text 类型的输入做分词,再去倒排索引搜索,可以通过这个设置查询的分析器为其它的,默认情况下,查询将使用 analyzer 字段制定的分析器,但也可以被 search_analyzer 覆盖

  • similarity:

    用于设置 document 的评分模型,有三个:

    • BM25:lucene 的默认评分模型

    • classic:TF/IDF 评分模型

    • boolean: 布尔评分模型

  • store:默认为 false,lucene 不存储原始内容,但是source 仍然会存储。这个属性其实是 lucene 创建字段时候的一个选项,表明是否要单独存储原始值(source 字段是 elasticsearch 单独加的和 store 没有关系)。如果字段比较长,从source 中获取损耗比较大,可以关闭source 存储,开启 store。

  • term_vector: 用于存储术语的规则。默认值为 no,不存储向量信息.

三、Java API 优化

1. @Document

public @interface Document {

    /**
     * 索引名称
     * 只能全小写,不能包含特殊字符
     * 长度限制在255字节
     */
    String indexName();

    // 默认启动时创建索引
    boolean createIndex() default true;

    /**
     * 基于version的并发控制:
     *
     * 1、ES基于自身乐观锁进行并发控制
     *    ES基于Document中的version字段进行并发控制,初始创建version为1
     *    每次需要带上version进行更新,该步骤需要多次,特别是在多线程环境下
     *
     * 2、基于external version进行并发控制
     *    ES提供了一个插件,可以不用它提供的version,可以基于自己维护的一个版本号进行控制。
     *
     *  这里需要关注两点
     *     1.external version需要与ES中的version一摸一样的时候才可以进行修改
     *     2.external_gte 提供的version比ES中的version大的时候才可以进行修改
     */
    VersionType versionType() default VersionType.EXTERNAL;

    // 是否写入类型推断
    WriteTypeHint writeTypeHint() default WriteTypeHint.DEFAULT;

    // 控制es如何动态的将字段添加到Document中
    Dynamic dynamic() default Dynamic.INHERIT;
}
建议一般使用默认配置,除非有特殊需要,如:

  @Document(indexName = "indexName")

2. @setting注解

public @interface Setting {
    String settingPath() default ""; # 指定路径,优先级高,如:"indices/indexname.setting.json"
    boolean useServerConfiguration() default false; #使用ES服务器的配置
    short shards() default 1; # 主分片数
    short replicas() default 1; # 默认数
    String refreshInterval() default "1s"; # refresh时间间隔
    String indexStoreType() default "fs"; # es自带优化
    String[] sortFields() default {}; #指定要进行排序的字段名
    SortOrder[] sortOrders() default {}; #指定升序或降序排列,默认为升序 (asc)
    SortMode[] sortModes() default {}; #指定多值字段如何进行排序,默认为min (取最小值)
    SortMissing[] sortMissingValues() default {}; #指定缺失值位置,默认为_last(将缺失值放在最后)
​
    public static enum SortMissing {
        _last,
        _first;
    }
​
    public static enum SortMode {
        min,
        max;
    }
​
    public static enum SortOrder {
        asc,
        desc;
    }
}
FSDirectory文件类型
type备注
FSDirectoryType.FS 或 Type.DEFAULTFSDirectory是lucene库实现的文件系统类,根据操作系统是否为WINDOWS,操作系统是否为64位,操作系统的文件系统是否支持MMAP来决定使用SimpleFSDirectory、NIOFSDirectory、MMapDirectory中的一种方式
SimpleFSDirectoryType.SIMPLEFS面向WINDOWS平台的文件系统
NIOFSDirectoryType.NIOFS面向LINUX平台的NIO库的文件系统
MMapDirectoryType.MMAPFS面向LINUX平台的支持MMap方式的文件系统

建议:

@Setting(shards = 3, replicas = 1, refreshInterval = "15s",sortFields = {"time"},sortOrders= {Setting.SortOrder.desc})

3. @Field注解

public @interface Field {
    String value() default ""; # 字段名称,是name的别名
    String name() default ""; # 字段名称
    FieldType type() default FieldType.Auto; # 字段类型,默认:自动检测字段的类型
    boolean index() default true; # 是否建立索引,false(1、不能查询 2、不能得到返回?)
    DateFormat[] format() default {DateFormat.date_optional_time, DateFormat.epoch_millis}; # 时间类型的格式化
    String[] pattern() default {}; # 同上
    boolean store() default false; # 是否存储原文,(false:字段内容 存储到_source中;ture:字段内容 存储到其他地方,不存储到_source中)
    boolean fielddata() default false; # 是否支持基于 text 字段的分桶聚合,true可能会消耗大量的堆空
    String searchAnalyzer() default ""; # 查询时,先对要查询的text类型的输入做分词,再去倒排索引中搜索
    String analyzer() default "";# 插入文档时,将text类型的字段做分词然后插入倒排索引
    String normalizer() default ""; #normalizer:是keyword的一个属性,可以对 keyword 生成的 单一Term 再做进一步的处理。比如:“normalizer”: “lowercase”。
    String[] ignoreFields() default {}; # 某个字段需要被忽略,因为_source会存储每一个文档的完整信息,返回的时候会返回整个文档,使用ignoreFields,那么会忽略掉对应的字段。
    boolean includeInParent() default false; # 设置所有嵌套对象属性的include_in_parent值,true:在嵌套对象中的所有字段会被添加到父文档的作为标准字段
    String[] copyTo() default {}; # 可以将多个字段的值复制到组字段中(F1),然后可以将其作为单个字段(F1)进行查询
    int ignoreAbove() default -1; #设置字段值的最大长度,超出这个长度的字段将不会被索引,但是会存储,默认256
    boolean coerce() default true; # 是否强制尝试清除脏值以适合字段的数据类型,true:尝试清除脏值;false:不清除脏值,那么请求的参数一定要符合字段类型的要求
    boolean docValues() default true; # 是否提供对排序和数据聚合的支持,注:text 或 text_annotated 等可分词字段不支持 doc values
    boolean ignoreMalformed() default false; #是否忽略字段格式类型,对数据类型不太确定时,可以尝试配置这个属性为true
    IndexOptions indexOptions() default IndexOptions.none;用于控制添加到倒排索引中的信息,服务于搜索和高亮等目的
    boolean indexPhrases() default false; # 主要将两个单词的组合索引到单独字段中,这样在进行精确的短语查询的时候会更有效,提升短语查询速度,但是要消耗更多磁盘空间
    IndexPrefixes[] indexPrefixes() default {};# 为字段值的前缀编制索引,以加快前缀搜索速度
    boolean norms() default true; #是否禁用评分,默认true:不禁用
    String nullValue() default ""; # 使用指定的值替换为null值,以便可以进行索引和搜索
    int positionIncrementGap() default -1; # text分词使用,指定position跨度
    Similarity similarity() default Similarity.Default; # text分词使用,为字段设置相似度计算打分模型
    TermVector termVector() default TermVector.none; # 字典值存储相关
    double scalingFactor() default 1.0; # 浮点数压缩相关
    int maxShingleSize() default -1; # 分词的深度
    boolean storeNullValue() default false; # 是否能存储null
    boolean positiveScoreImpact() default true; # 和排名功能查询相关
    boolean enabled() default true; # 是否创建倒排索引,若为false不能建立索引、不能被搜索、不能单独存储(只在_source元数据中展示)
    boolean eagerGlobalOrdinals() default false; #是否渴望(eager)全局序号(Ordinals)
    NullValueType nullValueType() default NullValueType.String; # # null值类型,有以下几个值:String和数值类型
​
    int dims() default -1; # 稠密向量搜索
    Dynamic dynamic() default Dynamic.INHERIT; # 控制出现新字段时候的行为,默认不添加到mapping,但可以保存
    boolean excludeFromSource() default false; # 是否排除_source元数据之外
}
​
FieldType字段类型:
public enum FieldType {
    Auto("auto"),
    Text("text"),
    Keyword("keyword"),
    Long("long"),
    Integer("integer"),
    Short("short"),
    Byte("byte"),
    Double("double"),
    Float("float"),
    Half_Float("half_float"),
    Scaled_Float("scaled_float"),
    Date("date"),
    Date_Nanos("date_nanos"),
    Boolean("boolean"),
    Binary("binary"),
    Integer_Range("integer_range"),
    Float_Range("float_range"),
    Long_Range("long_range"),
    Double_Range("double_range"),
    Date_Range("date_range"),
    Ip_Range("ip_range"),
    Object("object"),
    Nested("nested"),
    Ip("ip"),
    TokenCount("token_count"),
    Percolator("percolator"),
    Flattened("flattened"),
    Search_As_You_Type("search_as_you_type"),
    Rank_Feature("rank_feature"),
    Rank_Features("rank_features"),
    Wildcard("wildcard"),
   ...
}

根据实际业务设置,如字段不需要分词,也不需要索引和聚合:

@Field(type = FieldType.Keyword,name = "Latitude", index = false, docValues = false)
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐