Java修仙传之神奇的ES(基础使用)

news2025/7/12 20:56:23

前言

ES是什么:一款强大的搜索引擎

ES拓展:elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)
kibana:可视化
ES:搜索引起
Logstash:数据抓取,数据同步

ES为什么搜索快:核心:倒排索引

ES的底层:Java语言的搜索引擎类库Lucene

ES的竞品:solr,splunk等

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

什么是elastic stack(ELK)?
是以elasticsearch为核心的技术栈,包括beats、Logstash、kibana、elasticsearch

什么是Lucene?
是Apache的开源搜索引擎类库,提供了搜索引擎的核心API

倒排索引

正向索引

有没有正向索引呢?
	有。mysql id查询,全表扫描,模糊搜索等。
	特征:逐条搜索,依次递进

举例:模糊搜索x表中,携带手机的数据

流程概述:逐条搜索,逐条比对

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

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

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

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

如果添加一个条件 id = x

1:id查询

2:拿到数据比对

3:符合返回,不符合为空

备注:随着数量增加,即使增加了索引,速度也会逐渐变慢

倒排索引(根据词条查询,发挥最大效果)

备注:根据关键字查询时,发挥最大效果

本质:就是一个词条库,一词条对应N个ID。变相的id查询。

关键字输入->分词->获取文档id->根据文档id查询

概念了解:
一个es,有多个索引库
一个索引库下,有N条数据(每条数据叫一个文档)
一条文档,可以被分为N个词条

倒排索引,正是基于词条

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

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

倒排索引流程

倒排索引的搜索流程如下(以搜索"华为手机"为例):

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

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

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

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

总结

- 正向索引是最传统的,根据id索引的方式。但根据词条查询时,必须先逐条获取每个文档,然后判断文档中是否包含所需要的词条,是根据文档找词条的过程。
- 而倒排索引则相反,是先找到用户要搜索的词条,根据词条得到保护词条的文档的id,然后根据id获取文档。是根据词条找文档的过程。

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

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

ES的一些概念

索引库(=MYSQL的库)

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

举例:

MYSQL用户表 = ES用户索引库

MYSQL订单表 = ES订单索引库

字段(=MYSQL列名)

文档(=MYSQL一条数据)

一个文档=MYSQL一条数据

映射(=MYSQL约束(唯一非空等))

DSL语句(=SQL语句)

大白话:ES的操作语句

概念总结

MySQL

Elasticsearch

说明

Table

Index

索引(index),就是文档的集合,类似数据库的表(table)

Row

Document

文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式

Column

Field

字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)

Schema

Mapping

Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)

SQL

DSL

DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

ES跟MYSQL区别

- Mysql:擅长事务类型操作,可以确保数据的安全和一致性
- Elasticsearch:擅长海量数据的搜索、分析、计算

使用场景

  • 对安全性要求较高的写操作,使用mysql实现
  • 对查询性能要求较高的搜索需求,使用elasticsearch实现
  • 两者再基于某种方式,实现数据的同步,保证一致性

备注:这里数据同步用的就是Logstash

IK分词器

:w            - 保存文件,不退出 vim
:w file  -将修改另外保存到 file 中,不退出 vim
:w!          -强制保存,不退出 vim
:wq          -保存文件,退出 vim
:wq!        -强制保存文件,退出 vim
:q            -不保存文件,退出 vim
:q!          -不保存文件,强制退出 vim
:e!          -放弃所有修改,从上次保存文件开始再编辑

1:添加配置

2:定义文件,添加词语(要分为一组的)

备注:就是写个文件,直接把词加进去。文件名=上面配置的

3:重启es,kibana,测试即可

SDL语句

索引库操作

PUT /索引库名称
{
  "mappings": {
    "properties": {
      "字段名":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "字段名2":{
        "type": "keyword",
        "index": "false"
      },
      "字段名3":{
        "properties": {
          "子字段": {
            "type": "keyword"
          }
        }
      },
      // ...略
    }
  }
}

GET /索引库名

PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping。
虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。

- 请求方式:DELETE
- 请求路径:/索引库名
- 请求参数:无
删除索引库:DELETE /索引库名

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

文档操作

POST /索引库名/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
    "字段3": {
        "子属性1": "值3",
        "子属性2": "值4"
    },
    // ...
}

GET /{索引库名称}/_doc/{文档id}

DELETE /{索引库名}/_doc/id值

// 备注:这种方式相当于覆盖了原文档(全量修改)
PUT /{索引库名}/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
    // ... 略
}

// 备注:这种方式修改了指定id匹配的文档中的部分字段
POST /{索引库名}/_update/文档id
{
    "doc": {
         "字段名": "新的值",
    }
}

#  查询全部文档
GET 索引库名/_search

- 创建文档:POST /{索引库名}/_doc/文档id   { json文档 }
- 查询文档:GET /{索引库名}/_doc/文档id
- 删除文档:DELETE /{索引库名}/_doc/文档id
- 修改文档:
  - 全量修改:PUT /{索引库名}/_doc/文档id { json文档 }
  - 增量修改:POST /{索引库名}/_update/文档id { "doc": {"字段名":"新值"}}

RestHighLevelClient

依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:
<properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

索引库:创建,删除,判断是否存在

   private RestHighLevelClient client;

    //总结下流程:
    //1:基于配置文件或者代码连接到ES集群
    //2:初始化RestHighLevelClient
    //3:使用RestHighLevelClient来操作索引库(记得关闭连接)
        //3.1:不同的需求,写不同的api
        //3.2:发送给ES集群的请求,都是Request对象
    
    //判断索引库是否存在
    @Test
    void testExistsHotelIndex() throws IOException {
        boolean exists = client.indices().exists(new org.elasticsearch.client.indices.GetIndexRequest("hotel"), RequestOptions.DEFAULT);
        System.out.println("索引库是否存在:" + exists);
    }

    //删除索引库
    @Test
    void testDeleteHotelIndex() throws IOException {
        // 1.创建Request对象
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
        // 2.发送请求
        client.indices().delete(request, RequestOptions.DEFAULT);
    }

    //创建索引库
    @Test
    void createHotelIndex() throws IOException {
        // 1.创建Request对象
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        // 2.准备请求的参数:DSL语句
        request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
        // 3.发送请求
        //如果提示过时, CreateIndexRequest导包需要导入短的那个,长的那个过时了
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println("索引库创建结果是:" + response.isAcknowledged());
    }

	
    //在每一个测试方法(@Test)之前都会运行
    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
            //ip因人而异
                HttpHost.create("http://192.168.200.130:9200")
        ));
    }
	//在每一个测试方法(@Test)之后都会运行
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }

文档:新增,删除,查询,修改,批量操作

 @Autowired
    private IHotelService hotelService;

    private RestHighLevelClient client;

    //批量新增(BulkRequest增删改都是用)
    @Test
    void testBulkRequest() throws IOException {
        // 批量查询酒店数据
        List<Hotel> hotels = hotelService.list();

        // 1.创建Request
        BulkRequest request = new BulkRequest();
        // 2.准备参数,添加多个新增的Request
        for (Hotel hotel : hotels) {
            // 2.1.转换为文档类型HotelDoc
            HotelDoc hotelDoc = new HotelDoc(hotel);
            // 2.2.创建新增文档的Request对象
            IndexRequest hotel1 = new IndexRequest("hotel").id(hotelDoc.getId().toString());
            hotel1.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
            request.add(hotel1);
        }
        // 3.发送请求
        client.bulk(request, RequestOptions.DEFAULT);
    }


    //修改文档
    // POST /索引库名/_update/文档id
//    {
//        "doc"{
//            "name": "四钻",
//            "price": "952"
//        }
//    }
//    }
    //全量修改:根据id覆盖
    //增量修改:根据id修改对应数据
    @Test
    void testUpdateDocument() throws IOException {
        // 1.准备Request
        UpdateRequest request = new UpdateRequest("hotel", "61083");
        //准备请求参数
        request.doc(
                "price", "952",
                "startName", "四钻"
        );
        //发送请求
        client.update(request, RequestOptions.DEFAULT);
    }


    //删除文档  DELETE /hotel/_doc/{id}
    @Test
    void testDeleteDocument() throws IOException {
        // 1.准备Request
        DeleteRequest request = new DeleteRequest("hotel", "61083");
        // 2.发送请求
        client.delete(request, RequestOptions.DEFAULT);
    }

    //查询文档  GET /hotel/_doc/{id}
    @Test
    void testQueryDocument() throws IOException {
        //准备req对象
        GetRequest request = new GetRequest("hotel").id("61083");
        //发送请求
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        //解析响应结果
        if (response.isExists()) {
            String sourceAsString = response.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(sourceAsString, HotelDoc.class);
            System.out.println(hotelDoc);
        }
    }


    //新增文档
//    POST /{索引库名}/_doc/1
//    {
//        "name": "Jack",
//            "age": 21
//    }
    //数据库数据导入es
    @Test
    void testAddDocument() throws IOException {
        // 1.根据id查询酒店数据(从mysql中获取一条记录)
        Hotel hotel = hotelService.getById(61083L);
        // 2.转换为文档类型
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // 3.将HotelDoc转json
        String json = JSON.toJSONString(hotelDoc);

        //准备req对象
        IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
        // 2.准备Json文档
        request.source(json, XContentType.JSON);
        //发送请求
        client.index(request, RequestOptions.DEFAULT);
        //简化版
        //   client.index(new IndexRequest("hotel").id(hotelDoc.getId().toString()).source(json, XContentType.JSON), RequestOptions.DEFAULT);
    }

    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.200.130:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }

// 创建一个BulkRequest对象
BulkRequest request = new BulkRequest();

// 添加索引操作																	
IndexRequest indexRequest1 = new IndexRequest("索引库名").id("文档id").source("field1", "value1");
request.add(indexRequest1);

// 添加更新操作
UpdateRequest updateRequest1 = new UpdateRequest("my_index", "2").doc("field2", "value2");
request.add(updateRequest1);

// 添加删除操作
DeleteRequest deleteRequest1 = new DeleteRequest("my_index", "3");
request.add(deleteRequest1);

// 执行批量操作
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1158073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Element UI的table不同应用

目录 一、自定义表头 二、纵向表头(动态表头) 2.1、分别拿到表头和表头中日期对应的行数据 2.2、拿到每个日期对应的列数据 一、自定义表头 <el-table-column prop"chu" align"center"><!-- 自定义表头 --><template slot"header…

uniapp 微信小程序 授权隐私流程 网上没有的踩坑记录!

首先什么时候我们需要授权操作&#xff0c;比如下图我们调用这些接口时候首先必须让用户授权&#xff0c;这个政策是2022年2月21日24时起对一下接口增加用户授权操作&#xff0c;详情可以看微信文档 授权的逻辑按照官网的意思是&#xff1a; 这个时候就踩坑了&#xff0c;我把…

Linux命令超详细

Linux基础命令 Linux的目录结构 /&#xff0c;根目录是最顶级的目录了Linux只有一个顶级目录&#xff1a;/路径描述的层次关系同样适用/来表示/home/itheima/a.txt&#xff0c;表示根目录下的home文件夹内有itheima文件夹&#xff0c;内有a.txt ls命令 功能&#xff1a;列出…

高级文本编辑软件 UltraEdit mac中文版介绍说明

UltraEdit mac是一款在Windows系统中非常出名的文本编辑器&#xff0c; UltraEdit for mac对于IT程序猿来说&#xff0c;更是必不可少&#xff0c;可以使用UltraEdit编辑配置文件、查看16进制文件、代码高亮显示等&#xff0c;虽然Mac上已经有了很多优秀的文本编辑器&#xff0…

NOA赛道研究:预计2024年渗透率10%!中算力平台迎窗口期

从基础L2到L3的产业演进中&#xff0c;NOA是至关重要的一步&#xff0c;值得被密切关注。 对于产业链不同位置的玩家&#xff0c;其关注的点有所不同&#xff1a;①对于整车厂来说&#xff0c;根据高工智能汽车监测的数据&#xff0c;基础L2的一体机产品已经趋向于成熟&#x…

看完这个,别说你还找不到免费好用的配音软件

有很多小伙伴还在找配音工具&#xff0c;今天就给大家一次性分享四款免费好用的配音工具&#xff0c;每一个都经过测试&#xff0c;并且是我们自己也在用的免费配音工具 第一款&#xff0c;悦音配音工具 拥有强悍的AI智能配音技术&#xff0c;更专业&#xff0c;完美贴近真人配…

出现身份验证错误,要求函数不受支持windows

现象环境&#xff1a; win10 企业版 mstsc内网远程server2016&#xff0c;出现错误代码&#xff1a; 远程桌面连接出现身份验证错误。要求的函数不受支持。这可能是由于CredSSP加密数据库修正 出现身份验证错误 原因&#xff1a; 系统更新&#xff0c;微软系统补丁的更新将…

armbian 安裝配置教程

1、安装贝锐蒲公英 下载安装包 cd /usr/local/share mkdir pgyvpn wget https://pgy.oray.com/softwares/58/download/1839/PgyVisitor_Raspberry_2.4.0.52291_arm64.deb安装 dpkg -i PgyVisitor_Raspberry_2.4.0.52291_arm64.deb 输入pgyvisitor login/pgyvisitor login -…

全网最全的RDMA拥塞控制入门基础教程

RDMA-CC&#xff08;全网最全的RDMA拥塞控制入门基础教程&#xff09; 文章目录 RDMA-CC&#xff08;全网最全的RDMA拥塞控制入门基础教程&#xff09;DMARDMARDMA举例RDMA优势RDMA的硬件实现方法RDMA基本术语FabricCA&#xff08;Channel Adapter&#xff09;Verbs 核心概念Me…

波浪理论第3波anzo capital昂首资本3个方法3秒确认

要想通过波浪理论在交易中赚取最大利润&#xff0c;确认第三波必不可少&#xff0c;因为第三波通常是趋势中最大和最强的一波&#xff0c;今天anzo capital昂首资本3个方法3秒确认。 首先&#xff0c;第一个确认方法—斜率。 通常&#xff0c;第三波的斜率会比第一波更陡峭&a…

使用 Python 进行自然语言处理第 5 部分:文本分类

一、说明 关于文本分类&#xff0c;文章已经很多&#xff0c;本文这里有实操代码&#xff0c;明确而清晰地表述这种过程&#xff0c;是实战工程师所可以参照和依赖的案例版本。 本文是 2023 年 1 月的 WomenWhoCode 数据科学跟踪活动提供的会议系列文章中的一篇。 之前的文章在…

Linux进程控制——进程创建与退出

我们在用C语言结尾的时候总是会有return 0&#xff0c;但是有些人并不知道它到底有什么意思 还有在进程状态中让进程使用kill命令能够停下来&#xff0c;这些与进程控制有着密切的关系1.进程的创建 fork函数能够在代码中创建一个子进程&#xff0c;我们创建子进程的目的就是为…

电商课堂|5分钟了解电商数据分析完整流程,建议收藏!

账户效果下降&#xff0c;如何能够快速找到问题并优化调整&#xff1f; 相信百分之90%的竞价员都会说&#xff1a;“做数据分析。” 没错&#xff0c;数据分析能够帮助我们快速锁定问题所在&#xff0c;确定优化方向&#xff0c;还可以帮助我们找到流量控制的方向。那么做电商&…

绝地反击:阿里云服务器比腾讯云更优惠!

2023阿里云服务器优惠活动来了&#xff0c;以前一直是腾讯云比阿里云优惠&#xff0c;阿里云绝地反击&#xff0c;放开老用户购买资格&#xff0c;99元服务器老用户可以买&#xff0c;并且享受99元续费&#xff0c;阿腾云亲测可行&#xff0c;大家抓紧吧&#xff0c;数量不多&a…

软信天成:智能数据治理解决方案-干货分享

近年来&#xff0c;数据治理成为备受关注的焦点&#xff0c;越来越多的企业和组织开始注重数据治理&#xff0c;以更好地保护和管理数据。为助力企业有效开展数据治理工作&#xff0c;软信天成基于过往实施案例&#xff0c;梳理出有关数据治理实施的关键要素和心得&#xff0c;…

Techlink TL24G06 网络变压器 10G 基座单端口变压器

功能特征&#xff1a; 1、符合IEEE 802.3标准。 2、符合RoHS。 3、工作温度范围&#xff1a;0C至70C。 4、储存温度范围&#xff1a;-20C至125C。

Java实现对Html文本的处理

1.引入jsoup <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.8.3</version> </dependency> 2. html示例 示例代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1…

EG4003-一颗为微波、红外信号放大及处理输出的数模混合芯片

产品描述&#xff1a; EG4003是一款特意为微波、红外信号放大及处理输出的数模混合芯片&#xff0c;内部集成了运算放大器、双门限电压比较器、参考电压源、延时时间定时器和封锁时间定时器及状态控制器等&#xff0c;专用于防盗报警系统、人体门控制装置、照明控制开关等场合。…

C# 通过Costura.Fody把DLL合并到exe程序中

打包独立的exe程序有多种方法&#xff0c;这里只说Costura.Fody。 我们用VS发布应用程序可以借助Costura.Fody直接打包成一个独立的exe程序&#xff0c;但是一些非托管的做了几次都没打进去&#xff0c;最后成功了&#xff0c;这里记录一下。 首先安装Costura.Fody 或者可以通…

华为OD机试 - 统计射击比赛成绩 - 逻辑分析(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…