当前位置: 首页 > news >正文

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

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: 8081spring:datasource:url: jdbc:mysql://127.0.0.1:3306/es?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:configuration:map-underscore-to-camel-case: truetypeAliasesPackage: com.test.xulk.es.entitymapperLocations: classpath*:mybatis/**/*Mapper.xmlglobal-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@BeforeEachvoid setUp() {// // HttpHost.create("http://127.0.0.1:9200") // 若果是集群就配置多个this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://127.0.0.1:9200")));}// 销毁@AfterEachvoid tearDown() throws IOException {client.close();}//    测试初始化/*@Testvoid testInit() {System.out.println(client);}*/// 创建索引库@Testvoid 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);}// 删除索引库@Testvoid testDeleteIndex() throws IOException {// 1.准备Request      PUT /hotel  hotel 索引名DeleteIndexRequest request = new DeleteIndexRequest("hotel");// 3.发送请求client.indices().delete(request, RequestOptions.DEFAULT);}// 查询索引库@Testvoid 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 ? "存在" : "不存在");}}

文档操作的示例代码

 插入对比

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

 查询对比

    // 查询文档@Testvoid testGetDocumentById() throws IOException {// 1.准备RequestGetRequest 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

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

  修改对比

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

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

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

批量插入

    // 批量插入/导入数据@Testvoid 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.转JSONString 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.lqws.cn/news/117559.html

相关文章:

  • 自动化生产线,IT部署一站式解决方案-Infortrend KS私有云安全,一机多用
  • 国芯思辰ADE芯片成功替代ADS1296R,除颤仪核心部件实现自主可控
  • 【使用JAVA调用deepseek】实现自能回复
  • 嵌入式链表操作原理详解
  • 使用 systemctl 实现程序自启动与自动重启
  • Attention Is All You Need:抛弃循环神经网络的时代来了!
  • [AI Claude] 软件测试1
  • 【深度学习优化算法】02:凸性
  • 使用 SseEmitter 实现 Spring Boot 后端的流式传输和前端的数据接收
  • 《最近公共祖先》题集
  • DeepSeek本地部署及WebUI可视化教程
  • AI智能体,为美业后端供应链注入“智慧因子”(4/6)
  • 华为云Flexus+DeepSeek征文|Flexus云服务器单机部署+CCE容器高可用部署快速搭建生产级的生成式AI应用
  • vue项目中beforeDestroy或destroyed使用this.$notify.closeAll()失效
  • 华为云Flexus+DeepSeek征文|华为云Flexus服务器dify平台通过自然语言转sql并执行实现电商数据分析
  • 洛谷 单源最短路径 Dijkstra算法+优先队列
  • Flask框架详解:轻量高效的Python Web开发利器
  • 固定ip和非固定ip的区别是什么?如何固定ip地址
  • 搭建强化推荐的决策服务架构
  • OSPF域间路由
  • 企业的业务活动和管理活动是什么?-中小企实战运营和营销工作室博客
  • react+taro 开发第五个小程序,解决拼音的学习
  • 链路状态路由协议-OSPF
  • SpringAI集成DeepSeek实战
  • 近几年字节飞书测开部分面试题整理
  • 二极管MOS管选型
  • 【AI学习笔记】Coze工作流写入飞书多维表格(即:多维表格飞书官方插件使用教程)
  • Spring AI Tool Calling
  • Spring 中注入 Bean 有几种方式?
  • 通用寄存器的 “不通用“ 陷阱:AX/CX/DX 的寻址禁区与突围之道