14.Spring2.7.x 整合 Elasticsearch7.17

Elasticsearch:一个分布式的、Restful 风格的搜索引擎;支持对各种类型的数据的索引;搜索速度快,可以提供实时的搜索服务;便于水平扩展,每秒可以处理 PB 级海量数据


目录

1.Spring 整合 Elasticsearch

1.1 实体类与 ES 建立关系 

1.2 实现接口

1.3 测试类


1.Spring 整合 Elasticsearch

  • 引入依赖:spring-boot-starter-data-elasticsearch
  • 配置 Elasticsearch:cluster-name、cluster-notes
  • Spring Data Elaticsearch:ElaticsearchRestTemplate、ElaticsearchRepository

依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

配置:

# ElasticsearchProperties
spring.data.elasticsearch.cluster-name=xiaowen
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

解决冲突:Elasticsearch 底层是基于 Netty;Redis 底层也是基于 Netty,两者启动 natty 的时候由冲突

在 Application 类(核心入口配置类,最先被加载的)添加:

  • 添加 @PostConstruct 注解:管理 Bean 的初始化方法,由注解所修饰的方法会在构造器调用完成之后被执行
  • 添加方法:解决 netty 启动冲突问题(Netty4Utils.setAvailableProcessors())
package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import javax.annotation.PostConstruct;@SpringBootApplication
public class DemoApplication {//添加 @PostConstruct 注解:管理 Bean 的初始化方法,由注解所修饰的方法会在构造器调用完成之后被执行@PostConstructpublic void init() {// 解决netty启动冲突问题// see Netty4Utils.setAvailableProcessors()System.setProperty("es.set.netty.runtime.available.processors", "false");}public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}

1.1 实体类与 ES 建立关系 

编写与需求相关的代码:把数据库中存的帖子再存到 ES 服务器中,在 ES 服务器中搜索帖子

帖子表存到 ES 中的索引,每个字段对应的类型、怎么搜索都是要进行配置,但是配置不需要写 xml 文件,通过注解实现,注解写在实体类中(针对帖子操作,写在 discussPost 类中)

  • 在此类中添加注解 @Document(indexName = " ", type = " ", shards =  , replicas =  ):Spring 整合 ES,底层访问 ES 会自动将实体数据和 ES 服务器的索引映射:indexName:索引;type:类型;shards:分片;replicas:副本(ElasticSearch7.x已经不推荐使用type了,并且将在8.0彻底移除)
  • 主键通常会加 @Id、普通字段添加 @Field(type = FiledType. )
  • 重点是 title 和 context:搜索帖子主要搜索标题和内容(类型为 type = FieldType.Text),存储的时候尽可能多的拆分关键词,增加搜索范围(使用 analyzer = "ik_max_word");搜索的时候,需要尽可能满足需求,不需要拆分太多次(使用searchAnalyzer = "ik_smart")
/*** 与 ES 中的索引对应*///Spring 整合 ES,底层访问 ES 会自动将实体数据和 ES 服务器的索引映射
@Document(indexName = "discusspost")
public class DiscussPost {@Idprivate int id;@Field(type = FieldType.Integer)private int userId;//搜索帖子主要搜索标题和内容//存储的时候尽可能多的拆分关键词,增加搜索范围(使用 analyzer = "ik_max_word")// 搜索的时候,需要尽可能满足需求,不需要拆分太多次(使用searchAnalyzer = "ik_smart")@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")private String title;@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")private String content;@Field(type = FieldType.Integer)private int type;@Field(type = FieldType.Integer)private int status;//帖子状态@Field(type = FieldType.Date)private Date createTime;//创建时间@Field(type = FieldType.Integer)private int commentCount;//评论数量@Field(type = FieldType.Double)private double score;//分数
}

上述这个实体类就和es之间的数据建立了联系。

1.2 实现接口

在dao下新建elasticsearch,实现 DiscussPostRepository 接口,继承时声明泛型,主键类型

  • 添加注解 @Repository:这个接口是数据访问层代码,ES可以看作特殊的数据库(@Mapper 是 MyBatis 专用注解)
package com.example.demo.dao.elasticsearch;import com.example.demo.entity.DiscussPost;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {}

1.3 测试类

package com.example.demo;import com.example.demo.dao.DiscussPostMapper;
import com.example.demo.dao.elasticsearch.DiscussPostRepository;
import com.example.demo.entity.DiscussPost;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = DemoApplication.class)
public class ElasticsearchTests {@Autowiredprivate DiscussPostMapper discussMapper;@Autowiredprivate DiscussPostRepository discussRepository;@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;//查询@Testpublic void testInsert() {discussRepository.save(discussMapper.selectDiscussPostById(241));discussRepository.save(discussMapper.selectDiscussPostById(242));discussRepository.save(discussMapper.selectDiscussPostById(243));}//插入多条数据@Testpublic void testInsertList() {discussRepository.saveAll(discussMapper.selectDiscussPosts(101, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(102, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(103, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(111, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(112, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(131, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(132, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(133, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(134, 0, 100));}//修改@Testpublic void testUpdate() {DiscussPost post = discussMapper.selectDiscussPostById(231);post.setContent("我是新人,使劲灌水.");discussRepository.save(post);}//删除@Testpublic void testDelete() {// discussRepository.deleteById(231);discussRepository.deleteAll();}//搜索@Testpublic void testSearchByRepository() {NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content")).withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC),SortBuilders.fieldSort("score").order(SortOrder.DESC),SortBuilders.fieldSort("createTime").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).withHighlightFields( //高亮显示new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")).build();// elasticTemplate.queryForPage(searchQuery, class, SearchResultMapper)// 底层获取得到了高亮显示的值, 但是没有返回.Iterable<DiscussPost> page = discussRepository.findAll();for (DiscussPost post : page) {System.out.println(post);}}// 查询数据并将关键字高亮显示@Testpublic void testSearchByTemplate() {// withQuery()用于构造搜索条件NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content")).withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC),SortBuilders.fieldSort("score").order(SortOrder.DESC),SortBuilders.fieldSort("createTime").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).withHighlightFields(new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")).build();//查询SearchHits<DiscussPost> search = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);long count = elasticsearchRestTemplate.count(searchQuery, DiscussPost.class);System.out.println("共查询到: "+ count +"条数据");//得到查询返回的内容List<SearchHit<DiscussPost>> searchHits = search.getSearchHits();// 设置一个最后需要返回的实体类集合List<DiscussPost> discussPosts = new ArrayList<>();// 遍历返回的内容,进行处理for (SearchHit<DiscussPost> hit : searchHits) {// 获取高亮的内容Map<String, List<String>> highlightFields = hit.getHighlightFields();// 将高亮的内容添加到content中(匹配到的如果是多段,就将第一段高亮显示)// 没有匹配到关键字就显示原来的title和contenthit.getContent().setTitle(highlightFields.get("title")==null ? hit.getContent().getTitle():highlightFields.get("title").get(0));hit.getContent().setContent(highlightFields.get("content")==null ? hit.getContent().getContent():highlightFields.get("content").get(0));// 放到实体类中discussPosts.add(hit.getContent());}for (DiscussPost post : discussPosts) {System.out.println(post);}}
}

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

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

相关文章

DevExpress WinForms Pivot Grid组件,一个类似Excel的数据透视表控件(二)

界面控件DevExpress WinForms的Pivot Grid组件是一个类似Excel的数据透视表控件&#xff0c;用于多维(OLAP)数据分析和跨选项卡报表。在上文中&#xff08;点击这里回顾>>&#xff09;我们介绍了DevExpress WinForms Pivot Grid组件的性能、分析服务、数据塑造能力等&…

Java实现一个简单的贪吃蛇小游戏

一. 准备工作 首先获取贪吃蛇小游戏所需要的头部、身体、食物以及贪吃蛇标题等图片。 然后&#xff0c;创建贪吃蛇游戏的Java项目命名为snake_game&#xff0c;并在这个项目里创建一个文件夹命名为images&#xff0c;将图片素材导入文件夹。 再在src文件下创建两个包&#xff0…

Java的ThreadLocal

ThreadLocal ThreadLocal 是 Java 中一个非常有用的类&#xff0c;它允许你创建线程局部变量。线程局部变量是指每个线程都有自己独立的变量副本&#xff0c;互不干扰。ThreadLocal 主要用于解决多线程环境下共享数据的线程安全性问题。 基本用法 创建 ThreadLocal 变量 Th…

开源云原生网关Linux Traefik本地部署结合内网穿透远程访问

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

一文带你了解UI自动化测试框架

PythonSeleniumUnittestDdtHTMLReport分布式数据驱动自动化测试框架结构 1、Business&#xff1a;公共业务模块&#xff0c;如登录模块&#xff0c;可以把登录模块进行封装供调用 ------login_business.py from Page_Object.Common_Page.login_page import Login_Page from H…

六. 函数

基本使用 ts与js一样拥有具名函数和匿名函数两种函数类型。但是ts的函数需要提前定义好参数类型以及函数的返回值类型。 具名函数 function add(num1: number, num2: number):number {return num1 num2 }匿名函数 匿名函数的定义相对麻烦&#xff0c;我们需要提前定义函数的…

ubuntu22 安装 cuda12.0

本文是先安装显卡驱动后进行的操作 查看显卡驱动支持CUDA的最新版本12.0 nvidia-smi 检查gcc版本 gcc -v 查看系统支持的gcc版本 https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html 选择对应的安装cuda命令 https://developer.nvidia.com/cuda-too…

工业级路由器在货运物流仓储管理中的应用

工业级路由器在货运物流仓储管理中扮演着重要的角色&#xff0c;为整个物流系统提供了稳定可靠的网络连接和数据传输支持。下面将从以下几个方面介绍工业级路由器在货运物流仓储管理中的应用。 实时监控和追踪&#xff1a;工业级路由器通过与各种传感器、监控设备和物联网设备的…

【论文阅读】深度学习方法在数字岩石技术中的应用进展

【论文名称】Advances in the application of deep learning methods to digital rock technology 深度学习方法在数字岩石技术中的应用进展 【论文来源】EI检索 【作者单位】长江大学地球物理与油气资源学院、加拿大阿尔伯塔大学土木与环境工程系、东北石油大学地球科学学院、…

【剑指offer|图解|数组】寻找文件副本 + 螺旋遍历二维数组

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、剑指offer每日一练 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️寻找文件副本(题目难度&#xff1a;简单)1.1 题目1.2 示例1.3 限制1.4 解题思路一c代…

微信网页授权步骤说明

总览 引导用户进入授权页面同意授权&#xff0c;获取code通过code换取网页授权access_token&#xff08;与基础支持中的access_token不同&#xff09;如果需要&#xff0c;开发者可以刷新网页授权access_token&#xff0c;避免过期&#xff08;一般不需要&#xff09;通过网页…

高翔《自动驾驶与机器人中的SLAM技术》第九、十章载入静态地图完成点云匹配重定位

修改mapping.yaml文件中bag_path&#xff1a; 完成之后会产生一系列的点云文件以及Keyframe.txt文件&#xff1a; ./bin/run_frontend --config_yaml ./config/mapping 生成拼接的点云地图map.pcd文件 &#xff1a; ./bin/dump_map --pose_sourcelidar 。、 完成第一次优…

低代码开发:属于“美味膳食”还是“垃圾食品”

目录 引言低代码是什么&#xff1f;低代码的优点使用挑战未来展望最后 引言 随着数字化转型的迅猛发展&#xff0c;低代码开发平台逐渐成为了企业和开发者的关注焦点&#xff0c;尤其是前两年低代码的迅速火爆&#xff0c;来势汹汹&#xff0c;号称要让大部分程序员下岗的功能…

html2canvas库——前端实现基于DOM的截图

官网&#xff1a; html2canvas - Screenshots with JavaScript Github: https://github.com/niklasvh/html2canvas 资料&#xff1a; html2canvas使用教程-CSDN博客&#xff1a;https://blog.csdn.net/weixin_45917647/article/details/126250424 html2canvas实现浏览器…

双指针算法(一)

目录 移动零 复写零 快乐数 盛水最多的容器 双指针与单调性结合 有效三角形的个数 查找总价格为目标值的两个商品 两数之和 Ⅱ - 输入有序数组 双指针算法是通过定义两个指针不断单向移动来解决问题的一种算法。但双指针算法&#xff0c;是一个抽象的思想概念&#xf…

dockerfile,Docker镜像的创建

dockerfile&#xff1a;创建镜像&#xff0c;创建自定义的镜像。包括配置文件&#xff0c;挂载点&#xff0c;对外暴露的端口。设置环境变量。 docker的创建镜像的方式&#xff1a; 1、基于已有镜像进行创建。根据官方提供的镜像源&#xff0c;创建镜像&#xff0c;然后拉起容…

leetcode算法题:岛屿数量

leetcode算法题200 链接&#xff1a;https://leetcode.cn/problems/number-of-islands 题目 你一个由 ‘1’&#xff08;陆地&#xff09;和 ‘0’&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛…

Linux主机自动注册NPS客户端(脚本化)

参考官方对API使用方法的定义&#xff1a;https://ehang-io.github.io/nps/#/ 1、首先必须要在配置文件中开启 auth_key 并配置一个合适的密钥 2、修改脚本中的可变量参数&#xff0c;以适配自己的环境 #!/bin/bash # 脚本使用说明&#xff1a;# 脚本名称&#xff1a;npc_cr…

+0和不+0的性能差异

前几日&#xff0c;有群友转发了某位技术大佬的weibo。并在群里询问如下两个函数哪个执行的速度比较快&#xff08;weibo内容&#xff09;。 func g(n int, ch chan<- int) {r : 0for i : 0; i < n; i {r i}ch <- r 0 }func f(n int, ch chan<- int) {r : 0for …

基于Microchip 光伏逆变器方案

小编杂谈新能源已经完成了至少5期的博文了&#xff0c;Boss告诉小编&#xff0c;如果还不介绍我们的产品和方案&#xff0c;黄花菜都凉了&#xff0c;所以小编这期博文就重点介绍一下Microchip在储能上的产品介绍&#xff0c;重点聊聊Microchip储能中使用的光伏逆变器的解决方案…