Elasticsearch创建一个索引怎么也这么复杂

2022-10-12  本文已影响0人  醉鱼java

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、静态索引设置

静态索引设置是只能在索引创建时或者索引关闭时使用的

2.1.2、动态索引设置

动态索引设置是可以使用update-index-settings API在激活的索引上来动态设置

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

2.2、映射

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

2.2.1、支持的数据类型

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

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

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

如上索引,父子文档,指定一个人的爱好,一个人可以有多个爱好,所以创建索引时指定父子关系字段类型,指定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的父类

<img src="/Users/cxt/Documents/personal/wechataccount/doc/database/elasticsearch/es8.1认证/根据给定的需求创建一个索引.assets/image-20220901223720420.png" alt="image-20220901223720420" style="zoom: 67%;" />



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

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实现全文检索的前提,通过全文检索可以实现返回结果不仅包含精确完全匹配的结果,还包含相近的结果。比如我们有个数据中华人民共和国,其中我们搜索中华或者人民或者共和国或者其他组合词语的时候都可以搜索出来,不仅限于中华人民共和国

2.3.2、配置文本分析器

默认情况下,Elasticsearch使用standard analyzer,如果不能满足我们的需求,我们可以使用其他的内置分析器,或者自定义分词器,分析器的组成有三部分,character filtertokenizertoken filter其中这三部分都可以根据我们的需求来进行选择设置

2.3.4、自定义分词器

需求

  1. 实现中文分词
  2. 实现拼音分词(词语全拼,词语首字母简拼)
  3. 实现:) => _happy_,:( => _sad_
  4. 使用pattern_replace替换机智如我

解决方案

过程分析

首先自定义分词器ik_smart_pinyinik_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】直接去获取。后面的话,也是尽快吧,尽量赶点进度,把工作中常用的知识点整理起来,结合考点输出汇总,如果大家有好的意见或者建议欢迎评论区留言,下篇文章见喽!!!

本文由博客一文多发平台 OpenWrite 发布!

上一篇 下一篇

猜你喜欢

热点阅读