Elasticsearch从安装到实战、kibana安装以及自定义IK分词器/集成整合SpringBoot详细的教程(二)

news2025/6/6 17:46:12
package com.test.xulk.es.entity.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.test.xulk.es.entity.Hotel;


public interface HotelMapper extends BaseMapper<Hotel> {
}

集成Springboot 项目里面

官方地址: Elasticsearch clients | Elastic Docs

引入依赖:由于需要链接数据库,所以也添加数据库相关依赖了

<dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>9.0.0</version>
            <scope>runtime</scope>
        </dependency>

        <!--elasticsearch-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--FastJson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.71</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

配置文件

logging:
    config: classpath:logback.xml
server:
    port: 8081

spring:
    datasource:
        url: jdbc:mysql://127.0.0.1:3306/es?useSSL=false
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
    configuration:
        map-underscore-to-camel-case: true
    typeAliasesPackage: com.test.xulk.es.entity
    mapperLocations: classpath*:mybatis/**/*Mapper.xml
    global-config:
        db-config:
            logic-delete-value: 1  # 逻辑已删除值
            logic-not-delete-value: 0  # 逻辑未删除值

创建实体类

package com.test.xulk.es.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("tb_hotel")
public class Hotel {
    @TableId(type = IdType.INPUT)
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;
    private String longitude;
    private String latitude;
    private String pic;
}

Mapper接口

package com.test.xulk.es.entity.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.test.xulk.es.entity.Hotel;


public interface HotelMapper extends BaseMapper<Hotel> {
}

services的接口和实现类

package com.test.xulk.es.entity.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.test.xulk.es.entity.Hotel;
import com.test.xulk.es.entity.mapper.HotelMapper;
import com.test.xulk.es.entity.service.IHotelService;
import org.springframework.stereotype.Service;

@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
}






package com.test.xulk.es.entity.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.test.xulk.es.entity.Hotel;

public interface IHotelService extends IService<Hotel> {
}

创建索引

 # address 不搜索 无需添加索引  "index": false
 # 没必要分词  "type": "keyword",  keyword是精准查询

PUT /hotel
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "name": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "address": {
        "type": "keyword",
        "index": false
      },
      "price": {
        "type": "integer"
      },
      "score": {
        "type": "integer"
      },
      "brand": {
        "type": "keyword"
      },
      "city": {
        "type": "keyword"
      },
      "starName": {
        "type": "keyword"
      },
      "business": {
        "type": "keyword"
      },
      "location": {
        "type": "geo_point"
      },
      "pic": {
        "type": "keyword",
        "index": false
      }
    }
  }
}

# 由于有多个字段是相同的类型,分词也类似,为了提高效率,可以合成一个
name / brand / city / starName 都拷贝到all里面

 # address 不搜索 无需添加索引  "index": false
 # 没必要分词  "type": "keyword",  keyword是精准查询

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",
        "copy_to": "all"
      },
      "business": {
        "type": "keyword"
      },
      "location": {
        "type": "geo_point"
      },
      "pic": {
        "type": "keyword",
        "index": false
      },
      "all": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

es的映射对象

package com.test.xulk.es.esdoc;

import com.test.xulk.es.entity.Hotel;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class HotelDoc {
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;
    private String location;
    private String pic;

}

索引库的操作示例代码

package com.test.xulk;

import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.io.IOException;

/**
 * @program: spring-boot-mq-sentinel-xxl-es
 * @author: xulk
 * @create: 2025-06-02 10:43
 */
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = HotelIndexTest.class)
public class HotelIndexTest {

    private static final String MAPPING_TEMPLATE = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\": {\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"address\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"price\": {\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"score\": {\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"brand\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"city\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"starName\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"business\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"location\": {\n" +
            "        \"type\": \"geo_point\"\n" +
            "      },\n" +
            "      \"pic\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"all\": {\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

    private RestHighLevelClient client;

    // 快捷键  alt + inster  选择第二个 SetUp方法
    // 初始化 client
    @BeforeEach
    void setUp() {
        // // HttpHost.create("http://127.0.0.1:9200") // 若果是集群就配置多个
        this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://127.0.0.1:9200")));
    }

    // 销毁
    @AfterEach
    void tearDown() throws IOException {
        client.close();
    }

    //    测试初始化
    /*@Test
    void testInit() {
        System.out.println(client);
    }*/

    // 创建索引库
    @Test
    void testCreateIndex() throws IOException {
        // 1.准备Request      PUT /hotel  hotel 索引名
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        // 2.准备请求参数
        request.source(MAPPING_TEMPLATE, XContentType.JSON);
        // 3.发送请求
        client.indices().create(request, RequestOptions.DEFAULT);
    }

    // 删除索引库
    @Test
    void testDeleteIndex() throws IOException {
        // 1.准备Request      PUT /hotel  hotel 索引名
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
        // 3.发送请求
        client.indices().delete(request, RequestOptions.DEFAULT);
    }


    // 查询索引库
    @Test
    void testGetIndex() throws IOException {
        // 1.准备Request      PUT /hotel  hotel 索引名
        GetIndexRequest request = new GetIndexRequest("hotel");
        // 3.发送请求
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println( exists ? "存在" : "不存在");
    }


}

文档操作的示例代码

 插入对比

@Test
    void testAddDocument() throws IOException {
        // 1.查询数据库hotel数据
        Hotel hotel = hotelService.getById(61083L);
        // 2.转换为HotelDoc
        HotelDoc hotelDoc = new HotelDoc();
        BeanUtils.copyProperties(hotel, hotelDoc);
        hotelDoc.setLocation(hotel.getLatitude() + ", " + hotel.getLongitude());
        // 3.转JSON
        String json = JSON.toJSONString(hotelDoc);
        // 1.准备Request
        IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
        // 2.准备请求参数DSL,其实就是文档的JSON字符串
        request.source(json, XContentType.JSON);
        // 3.发送请求
        client.index(request, RequestOptions.DEFAULT);
    }

 查询对比

    // 查询文档
    @Test
    void testGetDocumentById() throws IOException {
        // 1.准备Request
        GetRequest request = new GetRequest("hotel", "61083");
        // 2.准备请求参数DSL,其实就是文档的JSON字符串
        GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
        // 3.发送请求
        String json = getResponse.getSourceAsString();
        System.out.println( json );

    }

删除

与查询相比,仅仅是请求方式从DELETE变成GET


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

  修改对比

  • 全量修改:本质是先根据id删除,再新增

  • 增量修改:修改文档中的指定字段值

    @Test
    void testUpdateById() throws IOException {
        // 1.准备Request
        UpdateRequest request = new UpdateRequest("hotel", "61083");
        // 2.准备修改的参数    修改哪个字段就写哪个字段
        request.doc(
                "price","100",
                "score","45"
        );
        // 3.发送请求
        client.update(request, RequestOptions.DEFAULT);
    }

批量插入

    // 批量插入/导入数据
    @Test
    void testBulkRequest() throws IOException {
        // 1.查询数据库hotel数据
        List<Hotel> list = hotelService.list();
        BulkRequest bulkRequest = new BulkRequest();
        for (Hotel hotel : list) {
            HotelDoc hotelDoc = new HotelDoc();
            // 1.构建参数
            BeanUtils.copyProperties(hotel, hotelDoc);
            hotelDoc.setLocation(hotel.getLatitude() + ", " + hotel.getLongitude());
            // 3.转JSON
            String json = JSON.toJSONString(hotelDoc);
            // 4.创建新增文档的Request对象
            IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString()).source(json, XContentType.JSON);
            bulkRequest.add(request);
        }
        client.bulk(bulkRequest, RequestOptions.DEFAULT);
    }

批量查询数据

GET /hotel/_search

数据库也是201条数据

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

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

相关文章

数据库管理-第333期 Oracle 23ai:RAC打补丁完全不用停机(20250604)

数据库管理333期 2025-06-04 数据库管理-第333期 Oracle 23ai&#xff1a;RAC打补丁完全不用停机&#xff08;20250604&#xff09;1 概念2 要求3 操作流程4 转移失败处理总结 数据库管理-第333期 Oracle 23ai&#xff1a;RAC打补丁完全不用停机&#xff08;20250604&#xff0…

【DAY39】图像数据与显存

内容来自浙大疏锦行python打卡训练营 浙大疏锦行 知识点&#xff1a; 图像数据的格式&#xff1a;灰度和彩色数据模型的定义显存占用的4种地方 模型参数梯度参数优化器参数数据批量所占显存神经元输出中间状态 batchisize和训练的关系 作业&#xff1a;今日代码较少&#xff0…

AI代码库问答引擎Folda-Scan

简介 什么是 Folda-Scan &#xff1f; Folda-Scan 是一款革命性的智能项目问答工具&#xff0c; 完全在浏览器中本地运行 。它使用高级语义矢量化将您的代码库转变为对话伙伴&#xff0c;使代码理解和 AI 协作变得前所未有的简单和安全。其采用尖端的 Web 技术和 AI 算法构建&…

Kafka深度技术解析:架构、原理与最佳实践

一、 消息队列的本质价值与核心特性 1.1 分布式系统的“解耦器” 异步通信模型 代码列表 graph LRA[生产者] -->|异步推送| B[(消息队列)]B -->|按需拉取| C[消费者1]B -->|按需拉取| D[消费者2] 生产者发送后立即返回&#xff0c;消费者以自己的节奏处理消息。典…

基于cnn的通用图像分类项目

背景 项目上需要做一个图像分类的工程。本人希望这么一个工程可以帮助学习ai的新同学快速把代码跑起来&#xff0c;快速将自己的数据集投入到实战中&#xff01; 代码仓库地址&#xff1a;imageClassifier: 图片分类器 数据处理 自己准备的分类图像&#xff0c;按照文件夹分…

Linux环境管道通信介绍

目录 前言 一、通信的本质 二、匿名管道 1.通信资源——文件缓冲区 2.为什么叫匿名管道&#xff1f; ​编辑 3.匿名管道的创建过程 4.pipe函数 小结 5.一些问题 1&#xff09;匿名管道为什么要求父子进程将原本的读/写权限只保留一个 2&#xff09;为什么一开始父进程要以读/写…

DIC技术助力金属管材全场应变测量:高效解决方案

在石油管道、汽车排气系统、航空航天液压管路等工业场景中&#xff0c;金属管作为关键承力部件&#xff0c;其拉伸性能&#xff08;如弹性极限、颈缩行为、断裂韧性&#xff09;直接影响结构安全性和使用寿命。 实际应用中&#xff0c;选用合适的管材非常重要&#xff0c;通过…

嵌入式学习--江协stm32day1

失踪人口回归了&#xff0c;stm32的学习比起51要慢一些&#xff0c;因为涉及插线&#xff0c;可能存在漏插&#xff0c;不牢固等问题。 相对于51直接对寄存器的设置&#xff0c;stm32因为是32位修改起来比较麻烦&#xff0c;江协课程是基于标准库的&#xff0c;是对封装函数进…

湖北理元理律师事务所:债务化解中的心理重建与法律护航

专业法律顾问视角 一、债务危机的双重属性&#xff1a;法律问题与心理困境 在对173名债务人的调研中发现&#xff1a; 68%存在焦虑引发的决策障碍&#xff08;如不敢接听银行电话&#xff09; 42%因羞耻感隐瞒债务导致雪球效应 湖北理元理律师事务所创新采用法律-心理双轨…

【更新中】(文档+代码)基于推荐算法和Springboot+Vue的购物商城

概要设计 本节规划和定义了Woodnet桌游电商平台的软件概要设计说明书&#xff0c;描述了软件的总体设计、接口设计、运行设计、系统数据库结构设计以及系统出错处理设计&#xff0c;从整体上说明了系统设计的结构层次、处理流程、系统用例等。 本系统是一个独立的系统&#x…

六种高阶微分方程的特解(原创:daode3056)

高阶微分方程的通解是指包含所有可能解的解的表达式。对于一个 n 阶微分方程&#xff0c;其通解通常包含 n 个任意常数。这些任意常数可以通过初始条件或边界条件来确定。高阶微分方程的特解是指在通解中&#xff0c;特定地选择了一组常数&#xff0c;使得解满足给定的初始条件…

【C++11(上)】—— 我与C++的不解之缘(三十)

一、C11 这里简单了解一下C发展好吧&#xff1a; C11是C的第二个大版本&#xff0c;也是自C98以来最重要的一个版本。 它引入了大量的更改&#xff0c;它曾被人们称为C0x&#xff0c;因为它被期待在2010年之前发布&#xff1b;但在2011年8月12日才被采纳。 C03到C11花了8年时间…

【多线程初阶】wait() notify()

文章目录 协调多个线程间的执行顺序join 和 wait 区别sleep 和 wait 区别 wait()方法线程饿死调用 wait()唤醒 wait() notify()方法wait() 和 notify() 需对同一对象使用确保先 wait ,后 notify多个线程在同一对象上wait notify随机唤醒一个wait notifyAll()方法应用 wait() 和…

安全-JAVA开发-第二天

Web资源访问的流程 由此可见 客户访问JAVA开发的应用时 会先通过 监听器&#xff08;Listener&#xff09;和 过滤器&#xff08;Filter&#xff09; 今天简单的了解下这两个模块的开发过程 监听器&#xff08;Listener&#xff09; 主要是监听 我们触发了什么行为 并进行反应…

Python基础:文件简单操作

&#x1f343;引言 手把手带你快速上手Python Python基础专栏 一、&#x1f343;文件是什么 变量是把数据保存到内存中. 如果程序重启/主机重启, 内存中的数据就会丢失。 要想能让数据被持久化存储, 就可以把数据存储到硬盘中. 也就是在文件中保存。 通过文件的后缀名, 可以看…

深度学习项目之RT-DETR训练自己数据集

RT-DETR 1.模型介绍&#x1f4cc; 什么是 RT-DETR &#xff1f;&#x1f4d6; 核心改进点&#x1f4ca; 结构示意&#x1f3af; RT-DETR 优势⚠️ RT-DETR 缺点&#x1f4c8; 应用场景&#x1f4d1; 论文 & 官方仓库2.模型框架3.Yaml配置文件4.训练脚本5.训练完成截图6.总结…

以太网帧结构和封装【二】-- IP头部信息

1字节 byte 8比特 bit 【位和比特是同一个概念】 比特/位&#xff0c;字节之间的关系是&#xff1a; 位&#xff08;Bit&#xff09; 中文名&#xff1a;位&#xff08;二进制位&#xff09;。 英文名&#xff1a;Bit&#xff08;Binary Digit 的缩写&#xff09;。 含义&…

Promtail采集服务器本地日志存储到Loki

✅ 一、前提条件 已安装 Loki 服务 日志文件目录可访问&#xff08;如 /var/log&#xff09; 具备 sudo 权限 &#x1f9e9; 二、下载 Promtail 二进制文件 # 替换为你想要的版本 VERSION"3.5.1"# 创建目录 sudo mkdir -p /opt/promtail cd /opt/promtail# 下载并…

学习STC51单片机27(芯片为STC89C52RCRC)

每日一言 你读过的书、走过的路、流过的汗&#xff0c;终将成就独一无二的你。 硬件&#xff1a;LCD1602液晶显示 非标协议外设 概述 LCD1602&#xff08;Liquid Crystal Display&#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符(16列两行) 那我…

DA14531_beacon_大小信标设备开发

蓝牙信标是一款通过广播指定蓝牙信号&#xff0c;实现信标信号扫描、识别和获得辅助信息的电子产品。 不同品名的蓝牙信标采用相同的 UUID 和广播信号格式&#xff0c;但在 MAC 地址、工作寿命、体积和广播周期上有所差异。 小武编程巧用DA14531开发一款蓝牙信标.