springboot——集成elasticsearch进行搜索并高亮关键词

2023-11-19

目录

1.elasticsearch概述

3.springboot集成elasticsearch

4.实现搜索并高亮关键词


1.elasticsearch概述

(1)是什么:

Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。

Lucene 可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。但Lucene 只是一个基于java下的库,需要使用 Java 并要将其集成到你的应用中才可进行使用。而Elasticsearch 则是基于Lucene 下实现的开源搜索引擎。

Elasticsearch 基于分布式进行实时文件存储,每个字段都被索引并可被搜索,并可进行实时分析。同事由于基于分布式,可以扩展到上百台服务器,处理PB级结构化或非结构化数据。

(2)核心概念:

elasticsearch可归类于NoSQL的一种,其主要包含index(索引)、type(类型,elasticsearch 7.x后已被舍弃)、Document(文档)、Fields(字段)。

类比于MySQL如下:

其实现的核心在于倒排索引: 指的是将文档内容中的单词作为索引,将包含该词的文档 ID 作为记录。

一般的sql中都是正排索引,即以表中的唯一标识id作为索引,通过主键索引找到文档其他内容(具体请参考mysql存储结构)。

而elasticsearch通过关键字作为索引反向找到文档ID,可以高效的实现全文检索。

如我们有以下两条记录:

id content writer
1 这是一条测试数据,测试elasticsearch seven
2 这是第二条、测试数据,试一下elasticsearch搜索 seven

以上两条数据,在mysql中id为主键,当我们以elasticsearch以关键词搜索去搜查所有和elasticsearch有关的content时,在没有为content建索引的情况下,无法走主键索引,mysql会进行全表检索,效率一般。

而elasticsearch中会为content建立倒排索引,根据content找到对应的id,返回搜索结果,效率快鱼mysql。并且,整个搜索过程中我们不需要做任何文本的模糊匹配。

(3)应用场景:

ElasticSearch作为一个便于使用的分布式全文搜索引擎,常被用于各种搜索场景中:

  • 维基百科,百度等搜索引擎,对关键词和内容概要进行匹对,并对搜索的关键词进行高亮。
  • 电商平台,对关键词和商品名称、标题进行匹配,并对对搜索的关键词进行高亮。
  • 论坛,对关键词和帖子内容及评论等快速匹配,并对搜索关键词进行高亮。

总之言之, ElasticSearch是一个优秀的检索工具,可以对各类内容进行快速检索,并返回结果:

(检索关键词并进行高亮)

一般情况我们会在数据存入数据库前,把需要检索的字段作为ElasticSearch的索引和需要返回的数据存入ElasticSearch(比如电商平台达到商品标题),然后在搜索时使用ElasticSearch进行全文检索,快速返回相关结果。

3.springboot集成elasticsearch

下面对springboot集成elasticsearch进行演示:

pom依赖文件:

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.6.1</elasticsearch.version>
    </properties>

    <dependencies>
        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>
        <!-- ElasticSearch -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- lombok 需要安装插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

此处需要注意的是springboot自带的ElasticSearch版本为6.8.5 ,如果你使用的是其他版本的ElasticSearch请注意指定版本号。

config配置文件,对ElasticSearch进行连接:

@Configuration
public class ElasticSearchConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1",9200,"http")
                )
        );
        return client;
    }
}

至此,我们皆可以通过 RestHighLevelClient 对ElasticSearch进行使用

4.实现搜索并高亮关键词

下面对 ElasticSearch进行使用,进行查询并高亮关键词。

首先我们建立索引:user,并存入以下数据:

然后,我们在业务类编写查询方法:

//查询
    public List<User> searchUserByKeyword(String keyword,int pageNo,int pageSize) throws IOException {
        if (pageNo<=1){
            pageNo=1;
        }
        //条件查询
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //分页
        searchSourceBuilder.from(pageNo);
        searchSourceBuilder.size(pageSize);

        //匹配关键词(类似于模糊查询)
        //MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("sign",keyword);
        //组合查询
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //and查询,所有条件都要符合;    or查询可以使用queryBuilder.should
        queryBuilder.must(QueryBuilders.matchQuery("sign",keyword));
        queryBuilder.must(QueryBuilders.matchQuery("statue","use"));
        //精确匹配
        //TermQueryBuilder queryBuilder = QueryBuilders.termQuery("sign",keyword);
        searchSourceBuilder.query(queryBuilder);

        //设置高亮
        //highlightBuilder.requireFieldMatch(false);   //只需要高亮第一个
        searchSourceBuilder.highlighter(new HighlightBuilder().field("sign"));

        //执行
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //解析结果
        List<User> list = new ArrayList<>();
        for (SearchHit hit: response.getHits().getHits()){
            //解析高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField sign = highlightFields.get("sign");
            //获取原字段
            Map<String, Object> oldUser = hit.getSourceAsMap();
            //将高亮替换原字段内容
            StringBuilder stringBuilder = new StringBuilder();
            if (sign!=null){
                Text[] texts = sign.fragments();
                for (Text t:texts){
                    stringBuilder.append(t);
                }
                log.info("替换:"+stringBuilder);
                oldUser.put("sign",stringBuilder.toString());
            }

            User user = JSONObject.parseObject(hit.getSourceAsString(),User.class);
            user.setSign(oldUser.get("sign").toString());
            list.add(user);
        }
       return list;
    }

ElasticSearch的match配置是拆字匹配,即关键词为“测试”,那么会查询出所有目标字段中包含“测”和“试”任一字符的结果;若为“java”则不会对字母进行拆分,会保持整个单词完整。

上述代码需要注意的是,高亮的字段必须是查询的字段,才可以对查询的关键词进行高亮处理,否则高亮字段会为空。

编写controller进行测试:

@RestController
public class SearchController {

    @Resource
    private SearchService searchService;

    @GetMapping("/test")
    public List<User> test(@RequestParam("keyword")String keyword) throws IOException {
        return searchService.searchUserByKeyword(keyword,0,5);
    }
}

结果:

成功查询所有sign包含java关键词且statue为use的用户,并对java关键词进行高亮(em标签,需要使用html进行解析)。

拓展:

(1)ElasticSearch还可以对搜索结果进行排序:

searchSourceBuilder.sort("age");

上述代码即根据age字段对搜索结果进行排序。

(2)过滤查询条件:

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //过滤statue!=use的数据
        queryBuilder.filter(QueryBuilders.matchPhraseQuery("statue","use"));
        //过滤age不大于20的数据
        queryBuilder.filter(QueryBuilders.rangeQuery("age").gt(20));

具体还有很多查询条件,具体可参考ElasticSearch官网文档。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot——集成elasticsearch进行搜索并高亮关键词 的相关文章

  • 如何从 WifiP2pDeviceList 获取 wifi direct 设备名称

    我想在执行请求对等点时获取 wi fi direct 名称 这是我的代码 if WifiP2pManager WIFI P2P PEERS CHANGED ACTION equals action Log d tag success dis
  • 使用 AbstractTableModel 获取 JTable 中选定的行

    我有一个JTable using AbstractTableModel我在哪里有一个JCheckBox在第一列中用于选择行 现在 我需要从已检查的表中获取选定的行 现在 我按顺序从第一行遍历到最后一行并获取所有选择的行 如下所示 List
  • 将 spring-security 与 spring-webflux 结合使用时禁用 WebSession 创建

    我正在使用 Rest api 运行无状态 spring boot 应用程序 并希望按照所述禁用 WebSessions 的创建https www baeldung com spring security session https www
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • 使用 Spring Data REST 处理自定义异常 (i18n)

    我正在使用 Spring Boot 1 5 4 和 Spring JPA Spring Data REST HATEOAS 我正在寻找一种最佳实践 Spring 方式 来自定义异常 Spring Data REST 正在管理添加 i18n
  • 无法实例化接收器 com.parse.GcmBroadcastReceiver

    我正在编写一个使用 GCM 通知和解析推送的离子应用程序 这个应用程序正在使用这些插件 com ionic keyboard 1 0 3 Keyboard com phonegap plugins PushPlugin 2 4 0 Push
  • 如何识别 Java 中的不可变对象

    在我的代码中 我正在创建一个对象集合 这些对象将由各种线程以只有在对象不可变的情况下才安全的方式访问 当尝试将新对象插入到我的集合中时 我想测试它是否是不可变的 如果不是 我将抛出异常 我能做的一件事是检查一些众所周知的不可变类型 priv
  • firebase推送通知错误Spring Boot服务器端

    我正在尝试从 Spring Boot 服务器端发送通知到客户端 android 服务器运行良好 一切都很好 2020 09 01 08 13 07 691 INFO 18941 restartedMain e DevToolsPropert
  • 如果基于 Spring 注解的控制器位于 jar 文件内,则该控制器无法工作

    我的子模块中有一些基于注释的控制器 这些模块作为 jar 文件部署 jar 文件中基于注释的控制器未加载到 spring 配置中 我使用 Eclipse 中的导出实用程序手动导出 jar 文件 有人遇到过这个问题吗 当您使用 Eclipse
  • 正确使用 JDBC 连接池 (Glassfish)

    我需要在 Java Web 服务中作为会话 bean 实现数据库连接 但我不确定我这样做是否正确 我创建了一个类 public final class SQLUtils private static DataSource m ds null
  • 用 java 编写解释器时的 switch 或 if 语句

    当前的作业需要我编写一个程序 以一种非常微小且基本的编程语言 行为有点像 FORTRAN 来读取包含指令的文件并执行这些指令 基本上它是我猜的语言的简单解释器 它是完全线性的 所有语句都是按顺序定义的 并且只有字符串和整数变量 我需要查找和
  • 如何将自定义日志处理程序添加到 Google App Engine?

    我正在尝试向我的 java 应用程序添加自定义日志处理程序 我已经实现了一个扩展 java util Logging Handler 类的 InnerLogger 类 在我的logging properties中声明为处理程序 handle
  • Java 唤醒休眠线程

    我阅读了其他帖子 但没有找到我正在寻找的确切答案 所以我希望有人能给出一些澄清 我有一个将运行一段时间的程序 我有一些在后台运行的线程来执行各种任务 为了简单起见 让我们考虑 3 个线程 ThreadA每 10 秒执行一次任务 其中Thre
  • Java 泛型:如何为泛型类型指定类类型?

    我有一个 POJO 指定为 MyClass u where U是泛型类型参数 我正在尝试编写一个接受类引用的实用方法Class u
  • 战争库中的罐子爆炸

    我们可以将分解的 jar 文件放入 war web inf 库中吗 它在 JBOSS 4 2 中对我不起作用 我收到以下错误并且无法部署应用程序 Caused by javax management RuntimeOperationsExc
  • Google Cloud Messaging - 立即收到或长时间延迟收到的消息

    我在大学最后一年的项目中使用谷歌云消息传递 一切正常 但我在使用 GCM 时遇到了一些麻烦 通常 消息要么几乎立即传递 要么有很大的延迟 我读过这篇文章 但我真的认为它不适用于这种情况 GCM 通常会在消息发送后立即传送消息 然而 这并不总
  • 如果抛出RuntimeException,是否可以将其作为异常捕获?

    如果我有一个try抛出一个块RuntimException子类 可以是后续的catch块将其捕获为Exception 具体来说 public class MyAppException extends RuntimeException In
  • JMockit - 初始化问题

    当我使用以下测试时 我收到警告 警告 JMockit 是按需初始化的 这可能会导致某些测试失败 请检查文档以获取更好的初始化方法 这是我的测试实现 package test import static mockit Mockit impor
  • Integer.parseInt 引发的 NumberFormatException

    嘿 我在学校上编码课 但老师没有很好地解释 所以我们必须在网上查找我所做的信息 但我无法找到代码中的错误 你能帮我吗 char end s do System out println Tipo de boleto char boleto c
  • 如何使用剪辑来减少绘画时间?

    我正在尝试使用 Clip 来减少 CPU 负载 但剪辑在屏幕上留下了一些我似乎无法摆脱的垃圾 另外 打开和关闭剪辑似乎对 CPU 负载没有影响 在任一情况下 大部分时间似乎都花在重绘管理器和绘制缓冲图像上 import static jav

随机推荐

  • IDEA中web项目c3p0-config.xml文件的配置及存放目录

    IDEA中web项目c3p0 config xml文件的配置及存放目录 今天在IDEA上折腾了很长一段时间 始终连接不上数据库 日志总是说找不到mysql 这是我的测试代码 Test public void fun2 throws SQLE
  • windows下java swt实现操作redis的客户端工具

    原文 windows下java swt实现操作redis的客户端工具 源代码下载地址 http www zuidaima com share 1902705862708224 htm redisclient 1 0 正式发布 适用于多个 R
  • ip广播系统服务器软件,【网络广播服务器软件IP网络广播软件数字广播软件】 - 太平洋安防网...

    参数说明 品牌 万凯wankai 详细描述 具备 版权局颁发的计算机软件 标准TCP IP网络协议 安装于连接以太网的计算机 IP广播的网络终端具有 立的ID号与IP地址 可以单 接收服务器的个性化定时播放节目 定时播放的操作 可以通过电脑
  • Hibernate之inverse和cascade详解

    继Hibernate学习笔记整理之后 发现inverse和cascade这两个属性在配置过程中比较含糊 仔细比较一下是有些地方比较像 所以很容易搞糊涂 借助此文来阐述下inverse和cascade的区别 什么是inverse 默认值为fa
  • centos8安装postgresql步骤

    1 安装源 1 sudo yum y install epel release 2 postgresql官网发布的postgresql对应的安装源 sudo yum install y https download postgresql o
  • There are multiple modules with names that only differ in casing.

    问题 在 npm run dev 后 控制台出现警告 没有出现链接 但是在浏览器上直接输入地址http localhost 8080 又可显示界面 There are multiple modules with names that onl
  • 华为机试HJ55 挑7

    HJ55 挑7 Python 题目 解题思路 代码 结果 题目 解题思路 1 多组输入 需要循环 2 循环查找到输入数值即可 字符串查找用in 能否整除 求余后判断是否 0 3 最后打印找到的数字的列表长度 代码 def func n in
  • 逐行对比LLaMA2和LLaMA模型源代码

    几个小时前 2023年7月18日 Meta发布了允许商用的开源模型LLaMA2 笔者逐行对比了LLaMA2模型源代码 和LLaMA相比 几乎没有改动 细节如下 是否改动 LLaMA2 LLaMA 模型整体构架 无 Transformer T
  • 面试必考真题

    1 输入一个链表 反转链表后 输出新链表的表头 package com csu marden public class Demo1 public static void main String args Node head new Node
  • 解决“17: 错误:程序中有游离的‘\240’,\302’

    参考链接 https blog csdn net asuphy article details 54602426 执行如下命令即可 sed i s o240 o302 g dy haikang test cpp
  • Invalid bound statement (not found):

    BUG描述 在执行动态SQL出现问题 原因 mapper接口中的方法名和mapper xml中的id标签不一致 解决方案 修改mapper接口中的方法名 使其对应到mapper xml中的id标签 参考资料
  • openssl的x509命令简单入门

    openssl的x509命令简单入门 openssl是一个强大的开源工具包 它能够完成完成各种和ssl有关的操作 命令说明 openssl help 会得到如下的提示 openssl Error help is an invalid com
  • 数据库常用命令之外键(foreign key)之多对一(总结,基础)

    我是小白 刚接触MySQL不久 现阶段正在学习 为此在CSDN上留下自己的学习笔记 如果有错误的地方还请大家见谅 评论或者私发我错误地方哦 谢谢大家 嘿嘿 此篇将记录外键的相关知识 上篇内容为对一张表的约束条件 传送门 创建表的完整性语法
  • golang基础教程

    目录 golang基础教程 一 环境搭建 golang基础教程 二 开发规范及API golang基础教程 三 变量与数据类型概述 golang基础教程 四 基本数据类型 golang基础教程 五 基本数据类型的转换 golang基础教程
  • 缺少nodejs环境,请在设置中配置nodejs的安装路径 - HBuilder - uniapp

    HBuilder运行uni app项目 点击 运行到 提示 缺少nodejs环境 请在设置中配置nodejs的安装路径 解决办法 找到工具 设置 运行配置 node运行配置 运行终端类型 选择 内置 外部 如果已经配置过 关闭编译器 重新打
  • Unity_如何使相机视角一直跟随角色移动

    实例代码如下 using System Collections using System Collections Generic using UnityEngine 相机视角跟踪 public class FollowTarget Mono
  • QHash & QMap 的顺序问题 (***)

    QT关联容器QMap QHash的Key值自动排序问题 对QMap中的key进行自定义排序 如何取消QMap自动排序 让QMap按照插入的顺序排列 通过插入顺序循环QHash QMap QHash插入后的显示顺序以及记录插入顺序的数据结构
  • OpenGL图形管线和坐标变换

    1 OpenGL 渲染管线 OpenGL渲染管线分为两大部分 模型观测变换 ModelView Transformation 和投影变换 Projection Transformation 做个比喻 计算机图形开发就像我们照相一样 目的就是
  • 最实用的chrome插件

    前言 说真的第一次看到CSDN这个插件的时候并没有感觉特别吸引我的地方 因为我个人安装了好多的插件 第二次看到CSDN插件还是因为广告上说的参赛拿奖 其实我的动机也不是很纯o o 插件地址 CSDN插件 走起 对于谷歌的插件安装方式很多 可
  • springboot——集成elasticsearch进行搜索并高亮关键词

    目录 1 elasticsearch概述 3 springboot集成elasticsearch 4 实现搜索并高亮关键词 1 elasticsearch概述 1 是什么 Elasticsearch 是位于 Elastic Stack 核心