乐趣区

关于后端:Elasticsearch创建一个索引怎么也这么复杂

ES(8.1)认证考题纲要参考如下

https://mp.weixin.qq.com/s/x7lMmMAo2563JysMJ8vgRQ

明天是咱们学习 ES8.1 官网搜寻工程师的第一课,首先第一个问题就是 依据给定的需要创立一个索引,本篇文章将采纳如下(总分总)的模式剖析该题目,第一局部先进行考题的剖析,猜想要考的知识点大略有什么,而后第二局部对该题目波及的知识点进行剖析解说,每一个考点后都跟着简略的解读,最初模仿汇总该考题,最终实现熟练掌握该题目。后续本类型文章如不非凡阐明均应用该种形式进行解说,如果有好的倡议欢送留在评论区探讨

本文构造如下:

1、题目剖析(总)

2、题目拆解知识点(分)

3、总结(模仿出题考试,总)

上面进入第一局部,题目分析阶段

一、题目剖析

题目:依据给定的需要创立一个索引

解读:首先我在看到这个题目的第一感觉就是这个题目很简略,不就是创立个索引吗,最多就是设置几个主分片,几个正本分片,略微再深点就是字段类型、自定义分词器、索引别名,看着如同很简略,其实实际操作起来还是有肯定难度的,不过考试过程中可能查阅官网,所以咱们只有熟记考点官网地位即可,上面我就该题目波及到的(索引设置,字段映射类型,文本剖析)这三点进行剖析

通过浏览本文,你能够取得什么?

1、定义一个索引罕用的配置项有哪些

2、自定义字段映射与动静字段映射

3、如何设置字段的数据类型

4、文本剖析中 TokenizerToken filterCharacter filters各自施展什么作用以及如何设置

5、定义一个指定分片数量的索引,蕴含自定义分词器,自定义字段映射

二、题目拆解

2.1、索引设置

2.1.1、动态索引设置

动态索引设置是只能在索引创立时或者索引敞开时应用的

  • index.number_of_shards

    索引主分片数量设置,默认 1,只能在索引创立时设置,索引敞开时不能批改此选项

  • index.number_of_routing_shards

    index.number_of_shards 一起应用的整数值,文档路由到主分片的分片数

  • index.codec

    压缩存储数据策略抉择,默认LZ4

  • index.routing_partition_size

    路由能够达到的分片数,默认 1,只能在索引创立时设置,这个值必须小于 index.number_of_shards,除非index.number_of_shards 的值也是 1

  • index.soft_deletes.enabled

    索引软删除开关,只能在创立索引时进行配置,默认true

  • index.soft_deletes.retention_lease.period

    软删除记录保留最长期限策略,默认值12h

  • index.load_fixed_bitset_filters_eagerly

    嵌套查问预加载缓存过滤器,默认true

  • index.shard.check_on_startup

    分片关上时是否对分片进行查看的开关。默认false,还有true,checksum,除非特地精通各配置项含意,否则不倡议更改

2.1.2、动静索引设置

动静索引设置是能够应用update-index-settings API 在激活的索引上来动静设置

更改敞开掉的动态或者动静索引设置可能导致不正确的设置,如果不删除或者重建索引,则无奈更正这些谬误设置

  • index.number_of_replicas

    正本分片数量设置,默认为 1

  • index.auto_expand_replicas

    依据集群中数据节点的数量主动开展的正本数量,默认 false 敞开

  • index.search.idle.after

    分片多久没有申请或搜寻会被认为是闲暇的分片, 默认30s

  • index.refresh_interval

    执行 refresh 的距离,默认 1s, 能够设置-1 来禁用

  • index.max_result_window

    es 搜寻后果返回的最大记录数量(from+size),默认10000

  • index.max_inner_result_window

    es 搜寻后果中聚合桶返回的最大数量,默认100

  • index.max_rescore_window

    Rescore 申请的返回记录最大值,默认10000

  • index.max_docvalue_fields_search

    查问申请中对 docvalue_fields 数量的限度,默认100

  • Index.max_script_fields

    查问申请中容许的 script_fields 的数量最大值,默认32

  • Index.max_ngram_diff

    NGramTokenizerNGramTokenFilter 之间min_grammax_gram之间的 最大差别值,默认1

  • index.max_shingle_diff

    shingle token filtermax_shingle_sizemin_shingle_size最大差值,默认3

  • index.max_refresh_listeners

    索引分片上最大的监听器数量,实现了 refresh=wait_for 的监听器

  • index.analyze.max_token_count

    应用 analyze api 获取最大的 token 数量,默认10000

  • index.highlight.max_analyzed_offset

    高亮显示时设置的最大字符数,默认1000000

  • index.max_terms_count

    Term 查问中 term 的最大的数量,默认65536

  • index.max_regex_length

    正则查问中表达式的最大长度,默认1000

  • index.query.default_field

    查问语句中查问的字段设置,默认*, 查问除了元数据之外的所有字段

  • index.routing.allocation.enable

    管制索引分片调配

    • all 容许所有分片调配(默认)
    • primaries 只容许主分片调配
    • new_primaries 只容许新创建的主分片调配
    • none 不容许分片调配
  • index.routing.rebalance.enable

    管制索引分片从新均衡

    • all 容许所有分片从新均衡(默认)
    • primaries 容许主分片从新均衡
    • replicas 运行正本分片从新均衡
    • none 不容许分片从新均衡
  • index.gc_deletes

    已删除文档的历史版本号可被用于版本化操作的距离,默认60s

  • index.default_pipeline

    设置索引默认的ingest pipeline

  • index.final_pipeline

    索引最终的final ingest pipeline ,所有的申请都会走,如果该管道不存在,申请将会失败

    不能应用 final ingest pipeline 批改_index 字段,如果应用 final ingest pipeline 批改_index 字段,该申请将失败

  • index.hidden

    索引是否暗藏,默认 不返回暗藏的索引,申请时也能够应用参数expand_wildcards 管制,默认false

2.2、映射

映射在咱们的应用中有动静映射、动静映射模版、显式设置映射三块。动静映射也就是咱们不须要应用显式的设置字段类型,由 Elasticsearch 来进行揣测类型生成映射;动静映射模版就是介于两头的一种,意思是咱们提前设置好映射关系,并定一个模版名称、匹配规定,在进行索引插入数据的时候,依据匹配规定找到符合条件的动静模版,依据模版中的显式设置来生成索引;显式设置映射关系就是对索引中的每个字段都固定类型,无需进行类型揣测。上面咱们就以这三个方面深刻的看下字段映射关系如何设置,在看字段映射如何设置之前先来理解一下 Elasticsearch 中的数据类型都反对哪些?

2.2.1、反对的数据类型

本文数据类型只介绍下工作中常常应用的,个别的数据类型参考《依据给定需要创立索引进阶篇》,后续推出都会有的,全都会有的

本文数据类型只介绍下工作中常常应用的,个别的数据类型参考《依据给定需要创立索引进阶篇》,后续推出都会有的,全都会有的

本文数据类型只介绍下工作中常常应用的,个别的数据类型参考《依据给定需要创立索引进阶篇》,后续推出都会有的,全都会有的

  • 聚合字段类型

    类型设置为 aggregate_metric_double 作为一个对象,子字段能够有 min,max,sum,value_count, 当咱们对字段设置为aggregate_metric_double 字段做聚合时,它可能间接应用子字段的值进行聚合,比方最大值就能够间接去子对象中 max 的值比拟,详情可参考如下文章

    https://mp.weixin.qq.com/s/er…

  • 字段别名类型

    举例一个实用的例子,咱们在做 es 中数据汇总的时候有这么一个统计, 统计 log.level 为 info 级别的日志,然而因为数据源来自各个渠道,无奈都满足 ECS(Elastic Common Schema), 所以咱们能够应用字段别名,比方索引 1 中对应的统计字段是 log.level.keyword, 索引 2 对应的是 level.keyword, 然而 mapping 又无奈进行批改来实现,所以咱们创立一个字段别名 log.level 对应 log.level.keyword, 索引二中对应 level.keyword, 咱们统计时只须要对 lov.level 统计即可了

    咱们晓得索引能够起一个别名,字段也能够起一个别名,做搜寻、聚合、排序的时候间接应用 字段别名 进行查问、聚合和排序,上面是自己对字段别名的一个深度学习,参考如下:

    https://mp.weixin.qq.com/s/YM…

  • 数组字段

    数组字段没有固定的类型,然而数组中的所有元素类型必须统一,数组里能够蕴含零个或多个元素,如果为空,则是代表这个数组是没有值的字段

  • binary

    二进制类型,默认该类型字段不能够被搜寻,也不存储

  • Boolean

    接管 truefalse或者能够解析为 truefalse的字符串 ”true“"false"和空字符串""

  • Date

    工夫类型,能够是 2022-08-01 或者2022-08-01 12:00:00, 也能够是一个秒数或者毫秒数,工夫格局能够自定义格局,如果不增加应用默认格局 "strict_date_optional_time||epoch_millis",应用工夫类型字段排序时会主动转换为工夫戳毫秒数进行排序

  • Date nano

    Date类型的补充字段,纳秒存储

  • Geo

    形容地理位置信息的字段数据类型,因为知识点较多,详细信息可参考另一篇文章,艰深解读了 geo_pointgeo_shape两种类型的数据,如果查问,聚合,排序等

    https://mp.weixin.qq.com/s/nw…

  • Ip

    保留网络地址信息,反对 ipv4ipv6类型的存储与检索,具体可查看官网

  • Join

    对于 Join 类型,不是很罕用,然而也有应用,罕用的我独自摘出来写了一篇文章,不罕用或者比较简单常见的就简略一句话概括了,这个 Join 就在上面大略说说吧,首先还是先创立一个索引

    PUT my-index-000001
    {
      "mappings": {
        "properties": {
          "my_id": {"type": "keyword"},
          "my_join_field": { 
            "type": "join",
            "relations": {"user": "hobby"}
          }
        }
      }
    }

如上索引,父子文档,指定一个人的喜好,一个人能够有多个喜好,所以创立索引时指定父子关系字段类型,指定 user 的子类为 hobby,每条文档都有一个名称( 父文档或子文档 ),以上图创立的索引为例,每个文档都要指定这是个user 还是个 hobby,如下, 文档 1 是父文档 张三 用户,文档 2 是父文档 李四 用户,文档 3,4 张三 的喜好,文档 5,6 李四 的喜好

PUT my-index-000001/_doc/1?refresh
{
  "my_id": "1",
  "text": "张三",
  "my_join_field": {"name": "user"}
}

PUT my-index-000001/_doc/2?refresh
{
  "my_id": "2",
  "text": "李四",
  "my_join_field": {"name": "user"}
}

PUT my-index-000001/_doc/3?routing=1&refresh 
{
  "my_id": "3",
  "text": "乒乓球",
  "my_join_field": {
    "name": "hobby", 
    "parent": "1" 
  }
}

PUT my-index-000001/_doc/4?routing=1&refresh
{
  "my_id": "4",
  "text": "篮球",
  "my_join_field": {
    "name": "hobby",
    "parent": "1"
  }
}
PUT my-index-000001/_doc/5?routing=1&refresh 
{
  "my_id": "5",
  "text": "读书",
  "my_join_field": {
    "name": "hobby", 
    "parent": "2" 
  }
}

PUT my-index-000001/_doc/6?routing=1&refresh
{
  "my_id": "6",
  "text": "下棋",
  "my_join_field": {
    "name": "hobby",
    "parent": "2"
  }
}

须要留神的是 写入数据时必须指定路由值,因为父子文档必须保证数据存储在同一个分片

一个父文档能够有多个子文档, 如下,userhobbygirlfriend的父类,grielfriendfans 的父类



PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {"user": ["hobby", "girlfriend"],  
          "girlfriend": "fans" 
        }
      }
    }
  }
}
  • Keyword

    • 关键字类型,繁多的内容,比方身份证,姓名,Ip 等这种数据应用
    • 常量类型字段,一个索引中该字段的值是固定不变的,创立索引时指定,如果与指定的值不同,文档回绝写入
    • 含糊查问类型,含糊查问可在 keyword 类型时应用,通配符类型在文本内容基数较大时候的做了优化

    关键字类型数据能够用于聚合,排序,查问(term)

  • Nested

    嵌套对象类型,作为一个独自的 lucene 文档索引,反对查问,排序,聚合,聚合父文档等性能,具体可参考博主的另一篇 Nested 详解,点击标签即可拜访

  • Numeric

    数字类型,反对longintegershortbytedoublefloathalf_floatscaled_floatunsigned_long

    对于整数类型,应用 longintegershortbyte 就能够,浮点数能够应用 scaled_float,如果scaled_float 不能满足,那能够选取精读更高的doublefloathalf_float

  • Object

    在学习 Nested 嵌套对象类型的时候咱们曾经提到了一点,如果咱们不晓得对象类型,默认的就是 Object 类型的数据,在 Elasticsearch 外部,这个文档会被索引成一个简略扁平化的键值对模式

  • Range

    示意一个范畴内的数据,应用 gt 或者 gte 定义下界,应用 ltlte 定义上界,不过反对的聚合的类型无限,反对 histogram 或者cardinality

    反对的类型有integer_rangefloat_rangelong_rangedouble_rangedate_rangeip_range

  • Text

    文本类型、为了 textmatch_only_texttext传统的全文检索字段类型;match_only_text一种优化占用空间的文本类型,敞开打分,对须要执行查看进行较慢的操作,适宜用作日志索引

    个别状况下应用 text 文件类型的字段还会应用一个 keyword 的字段,进行 聚合、排序、关键字匹配 等操作

2.2.2、字段动静映射

何为 Dynamic mapping,咱们晓得在应用关系型数据库mysql 的时候,咱们创立一个表之后须要创立字段,比方 字符串 ID字符串 NAME,工夫类型 CREATE_TIME等字段来应用,而 Elasticsearch 弱小的就在于咱们不在像关系型数据库那样提前设置好字段以及每个字段的类型,咱们只须要保留一个文档,ES会主动的推断出数据类型并创立好 索引,类型,字段映射关系

Elasticsearch 检测到新字段时,默认状况下 Elasticsearch 会主动的识别字段数据类型,并将字段增加到 mapping 映射中,然而咱们能够通过参数 dynamic 来指定是否主动增加字段映射,可选值有 trueruntime,如果为 true 默认应用以下规定生成字段映射关系

JSON data type “dynamic”:”true” “dynamic”:”runtime”
null
true or false boolean boolean
double float double
long long long
object object
array 依据数组中第一个非空的值判断 依据数组中第一个非空的值判断
日期类型的字符串 date date
数字类型的字符串 float or long double or long
不是日期也不是数字的字符串 text类型以及 .keyword 的字类型 keyword

也能够设置 dynamicfalse,这样在遇到新的字段时会抛出异样

2.2.3、字段动静映射模版

下面咱们看到 Elasticsearch 会主动的推断数据类型,生成字段映射,那么 Dynamic template 动静模版就是自定义映射,提前内置好映射关系,在应用时通过肯定的规定匹配上即可

如下:如果字段名称是 ip 结尾 的字符串,映射为 ip 类型 的运行时字段

PUT my-index-000001/
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings_as_ip": {
          "match_mapping_type": "string",
          "match": "ip*",
          "runtime": {"type": "ip"}
        }
      }
    ]
  }
}

如果想加到 mapping 中只需替换 runtimemapping即可

PUT my-index-000001/
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings_as_ip": {
          "match_mapping_type": "string",
          "match": "ip*",
          "mapping": {"type": "ip"}
        }
      }
    ]
  }
}

2.2.4、自定义字段映射

自定义字段映射,其实就是关系数据库中创立表时的字段设置,顾名思义就是提前设置好索引须要的字段以及字段类型,在增加文档时如遇到新字段报错(可配置),个别在标准索引字段时应用,比方日志索引,依据日期每天定时生成一个新的索引,这个索引咱们就能够提前设置好模版,生成索引时间接应用模版生成,而模版中,间接定义好字段的类型,也就是说,自定义字段映射关系能够在映射模版的根底上应用的(对于索引模版的应用查看后文)如下是自定义字段映射的一个小例子

咱们创立一个索引 my-index-000001,其中ageinteger类型,emailkeyword 类型,nametext 类型

PUT /my-index-000001
{
  "mappings": {
    "properties": {"age":    { "type": "integer"},  
      "email":  {"type": "keyword"}, 
      "name":   {"type": "text"}     
    }
  }
}

后续如果咱们想批改这个曾经创立的索引,比方减少个字段,那能够应用如下语句

PUT /my-index-000001/_mapping
{
  "properties": {
    "employee-id": {
      "type": "keyword",
      "index": false
    }
  }
}

查看索引 mapping 语句如下

# 查看所有的字段映射
GET my-index-000001/_mapping
# 查看某一个字段的映射关系,此处以 age 举例
GET my-index-000001/_mapping/field/age

2.3、文本剖析

2.3.1、什么是文本剖析

文本剖析是 Elasticsearch 实现全文检索的前提,通过全文检索能够实现返回后果不仅蕴含准确齐全匹配的后果,还蕴含相近的后果。比方咱们有个数据 中华人民共和国 ,其中咱们搜寻 中华 或者 人民 或者 共和国 或者其余组合词语的时候都能够搜寻进去,不仅限于 中华人民共和国

  • Tokenization: 当咱们进行全文检索时,分词能够让咱们把一个词语拆分成更小的词语,默认状况下,这些小的词语也是有独自的词语语义
  • Normalization: 其中 Tokenization 能够解决单个关键词的匹配查问,然而还是准确匹配,不能解决以下这种状况的查问

    • Quickquick 的大小写
    • foxfoxes 的词根
    • jumpsleaps 的近义词

    为了解决这些问题,文本剖析能够将这些 token 分词规范化为规范格局,这样就能够实现大小写,词根匹配,近义词匹配。

    为了确保搜寻时搜索词与预期的词匹配,尽量要应用雷同的 tokenizationnormalization规定

2.3.2、配置文本分析器

默认状况下,Elasticsearch应用 standard analyzer,如果不能满足咱们的需要,咱们能够应用其余的内置分析器,或者自定义分词器,分析器的组成有三局部,character filtertokenizertoken filter 其中这三局部都能够依据咱们的需要来进行抉择设置

  • Character filter

    翻译一下就是字符过滤器,用在分词之前,罕用的有 html 符号 移除,正则 替换、映射字符 替换

  • Tokenizer

    外围分词器,将一组字符流拆成单个词语,具体的分词策略在此实现,默认的 规范分词器 ,罕用的 中文分词器 英文分词器 拼音分词器

  • Token filter

    分词之后的词语过滤,比方英文中的 停用词移除 (a,an,the)、转换大小写

2.3.4、自定义分词器

需要
  1. 实现中文分词
  2. 实现拼音分词(词语全拼,词语首字母简拼)
  3. 实现:) => _happy_,:(=> _sad_
  4. 应用 pattern_replace 替换 机智如我
解决方案
  • 应用中文 IK 分词器拼音分词器 组合实现上述 需要 1,2
  • 应用 char_filter 实现上述 需要 3
  • 应用 filter 实现上述 需要 4
过程剖析

首先自定义分词器 ik_smart_pinyinik_max_pinyin

  • ik_smart_pinyin:简略分词,分的比拟粗,词语少
  • ik_max_pinyin:最大粒度分词,分的比拟细,词语多

其中 ik_smart_pinyin 退出 pinyin_first_letter_and_full_pinyin_filter 实现拼音分词

ik_max_pinyin也退出 pinyin_first_letter_and_full_pinyin_filter 实现拼音分词,然而为了比照,此处 ik_max_pinyin 分词器再退出自定义的 pattern_replace_filter 实现上述的 需要 4 ,退出 my_mappings_char_filter 实现上述 需要 3

settings 全部内容

残缺的创立索引 settings 内容如下

PUT ik_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "ik_smart_pinyin": {
          "tokenizer": "ik_smart",
          "filter": ["pinyin_first_letter_and_full_pinyin_filter"]
        },
        "ik_max_pinyin": {
          "tokenizer": "ik_max_word",
          "filter": [
            "pinyin_first_letter_and_full_pinyin_filter",
            "pattern_replace_filter"
          ],
          "char_filter": "my_mappings_char_filter"
        }
      },
      "filter": {
        "pinyin_first_letter_and_full_pinyin_filter": {
          "type": "pinyin",
          "keep_separate_first_letter": false,
          "keep_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "lowercase": true,
          "remove_duplicated_term": true
        },
        "pattern_replace_filter": {
          "type": "pattern_replace",
          "pattern": "(我)",
          "replacement": "机智如 $1"
        }
      },
      "char_filter": {
        "my_mappings_char_filter": {
          "type": "mapping",
          "mappings": [":) => _happy_",
            ":(=> _sad_"]
        }
      }
    }
  }
}

2.4、小结

在下面创立的自定义分词器的根底上,咱们在创立 mapping 字段关系映射时就能够间接指定 ik_smart_pinyin 或者 ik_max_pinyin 分词器即可实现分词啦,如下示例所示:

PUT ik_index/_mapping/
{
  "properties": {
    "content": {
      "type": "text",
      "analyzer": "ik_smart_pinyin"
    }
  }
}

三、总结

假总结,真心理总结

通过下面的学习,咱们晓得了设置索引时的罕用参数、常见的字段类型以及建设字段映射关系时的参数设置,能够看得出来,创立索引就这三块,只有这三块应用纯熟了,哪怕不查看官网也能够间接创立出一个满足本人需要的索引,鉴于考试时也都是能够参考官网的,所以下面的内容也不必死记硬背,只须要了解,多操作,记住常见的配置项即可了。好了该篇文章曾经进入序幕了,始终想早点完结,然而写着写着就发现,知识点太多,假如都写到这篇文章里,那就长的过分了,所以文中就分了几篇小的,比方字段类型那块,Geo、Nested 等独自输入了一篇文章,想参考学习的能够关注公众号【醉鱼 JAVA】间接去获取。前面的话,也是尽快吧,尽量赶点进度,把工作中罕用的知识点整顿起来,联合考点输入汇总,如果大家有好的意见或者倡议欢送评论区留言,下篇文章见喽!!!

本文由 mdnice 多平台公布

退出移动版