• 【分布式搜索引擎elasticsearch】


    1.elasticsearch基础

    什么是elasticsearch?

    • 一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能

    什么是elastic stack(ELK)?

    • 是以elasticsearch为核心的技术栈,包括beats、Logstash、kibana、elasticsearch
      elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域
      在这里插入图片描述
      倒排索引
      倒排索引的概念是基于MySQL这样的正向索引而言的。
      那么什么是正向索引呢?例如给下表(tb_goods)中的id创建索引:
      在这里插入图片描述
      如果是根据id查询,那么直接走索引,查询速度非常快。

    但如果是基于title做模糊查询,只能是逐行扫描数据,流程如下:

    1)用户搜索数据,条件是title符合"%手机%"

    2)逐行获取数据,比如id为1的数据

    3)判断数据中的title是否符合用户搜索条件

    4)如果符合则放入结果集,不符合则丢弃。回到步骤1

    逐行扫描,也就是全表扫描,随着数据量增加,其查询效率也会越来越低。当数据量达到数百万时,就是一场灾难。

    倒排索引中有两个非常重要的概念:

    • 文档(Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息
    • 词条(Term):对文档数据用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如:我是中国人,就可以分为:我、是、中国人、中国、国人这样的几个词条

    创建倒排索引是对正向索引的一种特殊处理,流程如下:

    • 将每一个文档的数据利用算法分词,得到一个个词条
    • 创建表,每行数据包括词条、词条所在文档id、位置等信息
    • 因为词条唯一性,可以给词条创建索引,例如hash表结构索引

    在这里插入图片描述
    倒排索引的搜索流程如下(以搜索"华为手机"为例):

    1)用户输入条件"华为手机"进行搜索。

    2)对用户输入内容分词,得到词条:华为手机

    3)拿着词条在倒排索引中查找,可以得到包含词条的文档id:1、2、3。

    4)拿着文档id到正向索引中查找具体文档。

    如图:

    在这里插入图片描述
    虽然要先查询倒排索引,再查询对应的正排索引,但是无论是词条、还是文档id都建立了索引,查询速度非常快!无需全表扫描。

    正向索引

    • 优点:
      • 可以给多个字段创建索引
      • 根据索引字段搜索、排序速度非常快
    • 缺点:
      • 根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。

    倒排索引

    • 优点:
      • 根据词条搜索、模糊搜索时,速度非常快
    • 缺点:
      • 只能给词条创建索引,而不是字段
      • 无法根据字段做排序

    elasticsearch是面向**文档(Document)**存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json格式后存储在elasticsearch中:

    索引和映射

    索引(Index),就是相同类型的文档的集合。

    例如:

    • 所有用户文档,就可以组织在一起,称为用户的索引;
    • 所有商品的文档,可以组织在一起,称为商品的索引;
    • 所有订单的文档,可以组织在一起,称为订单的索引;
    • 在这里插入图片描述
    • Mysql:擅长事务类型操作,可以确保数据的安全和一致性
    • Elasticsearch:擅长海量数据的搜索、分析、计算
      在这里插入图片描述

    索引库操作

    mapping映射属性:
    在这里插入图片描述
    在这里插入图片描述

    创建索引库和映射

    基本语法:

    • 请求方式:PUT
    • 请求路径:/索引库名,可以自定义
    • 请求参数:mapping映射
    • 在这里插入图片描述

    查询索引库

    基本语法

    • 请求方式:GET
    • 请求路径:/索引库名
    • 请求参数:无
    • 在这里插入图片描述

    修改索引库
    倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping

    虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。
    在这里插入图片描述
    删除索引库

    • 请求方式:DELETE
    • 请求路径:/索引库名
    • 请求参数:无
    • 在这里插入图片描述

    索引库操作总结

    索引库操作有哪些?

    • 创建索引库:PUT /索引库名
    • 查询索引库:GET /索引库名
    • 删除索引库:DELETE /索引库名
    • 添加字段:PUT /索引库名/_mapping

    文档操作

    新增文档
    在这里插入图片描述

    查询文档
    在这里插入图片描述
    删除文档
    在这里插入图片描述
    修改文档

    修改有两种方式:

    • 全量修改:直接覆盖原来的文档
    • 增量修改:修改文档中的部分字段

    全量修改:
    全量修改是覆盖原来的文档,其本质是:

    • 根据指定的id删除文档
    • 新增一个相同id的文档

    注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。
    在这里插入图片描述
    增量修改:
    增量修改是只修改指定id匹配的文档中的部分字段。
    在这里插入图片描述

    文档操作总结

    • 创建文档:POST /{索引库名}/_doc/文档id { json文档 }

    • 查询文档:GET /{索引库名}/_doc/文档id

    • 删除文档:DELETE /{索引库名}/_doc/文档id

    • 修改文档:

      • 全量修改:PUT /{索引库名}/_doc/文档id { json文档 }
      • 增量修改:POST /{索引库名}/_update/文档id { “doc”: {字段}}

      RestAPI

      1. 向数据库导入数据
        在这里插入图片描述
    1. 配置
      在这里插入图片描述
    2. 索引库设计
    PUT /hotel
    {
      "mappings": {
        "properties": {
          "id": {
            "type": "keyword"
          },
          "name":{
            "type": "text",
            "analyzer": "ik_max_word",
            "copy_to": "all"
          },
          "address":{
            "type": "keyword",
            "index": false
          },
          "price":{
            "type": "integer"
          },
          "score":{
            "type": "integer"
          },
          "brand":{
            "type": "keyword",
            "copy_to": "all"
          },
          "city":{
            "type": "keyword",
            "copy_to": "all"
          },
          "starName":{
            "type": "keyword"
          },
          "business":{
            "type": "keyword"
          },
          "location":{
            "type": "geo_point"
          },
          "pic":{
            "type": "keyword",
            "index": false
          },
          "all":{
            "type": "text",
            "analyzer": "ik_max_word"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    几个特殊字段说明:

    • location:地理坐标,里面包含精度、纬度
    • all:一个组合字段,其目的是将多字段的值 利用copy_to合并,提供给用户搜索
    1. 初始化RestClient
      在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。在这里插入图片描述
    2. 创建索引库
      在这里插入图片描述

    删除索引库:
    在这里插入图片描述
    判断索引库是否存在:
    在这里插入图片描述

    RestClient操作文档

    首先要将数据库的酒店数据查询出来,写入elasticsearch中(按照索引库的mapping的规则)。
    在这里插入图片描述
    新增文档的DSL语句如下:
    在这里插入图片描述
    在这里插入图片描述
    查询文档:
    在这里插入图片描述
    在这里插入图片描述
    删除文档:
    在这里插入图片描述
    在这里插入图片描述
    修改文档:
    在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:

    • 如果新增时,ID已经存在,则修改
    • 如果新增时,ID不存在,则新增

    在这里插入图片描述
    批量处理:
    批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。
    在这里插入图片描述

    总结

    文档操作的基本步骤:

    • 初始化RestHighLevelClient
    • 创建XxxRequest。XXX是Index、Get、Update、Delete、Bulk
    • 准备参数(Index、Update、Bulk时需要)
    • 发送请求。调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk
    • 解析结果(Get时需要)
  • 相关阅读:
    【字符编码】c++编码格式及转换
    【Pycharm 安装Django报错显示:ERROR: Failed building wheel for backports.zoneinfo】
    【算法训练-排序算法 三】【排序应用】合并区间
    Python连接MySQL数据库(简单便捷)
    PMP每日一练 | 考试不迷路-11.30(包含敏捷+多选)
    深度吐槽阿里云ack服务
    【Pandas】优化读取文件内存占用过大的问题
    ReactNative
    easyPoster一个基于uniapp的canvas绘制海报库支持绘制图表到海报中
    南京--ChatGPT/GPT4 科研实践应用
  • 原文地址:https://blog.csdn.net/qq_51240148/article/details/132625536