spring boot 3使用 elasticsearch 提供搜索建议

业务场景

用户输入内容,快速返回建议,示例效果如下
在这里插入图片描述

技术选型

  • spring boot 3
  • elasticsearch server 7.17.4
  • spring data elasticsearch 5.0.1
  • elasticsearch-java-api 8.5.3

pom.xml

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

yml

spring:
  elasticsearch:
    uris: http://127.0.0.1:9200
  data:
    elasticsearch:
      repositories:
        enabled: true

实体类

为了启动时候自己创建相关的index,以及存储搜索内容


import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.CompletionField;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.core.suggest.Completion;

/**
 * 业务搜索建议
 * @author chunyang.leng
 * @date 2023-08-21 14:24
 */
@Document(indexName = "biz_suggest")
public class BizSuggestDocument {

    @Id
    private Long id;

    /**
     * 标题,可以用于纠错,不参与搜索建议
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String name;

    /**
     * 自动补全标题,搜索建议使用的对象
     */
    @CompletionField(analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private Completion completionName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Completion getCompletionName() {
        return completionName;
    }

    public void setCompletionName(Completion completionName) {
        this.completionName = completionName;
    }
}

搜索结果对象


/**
 * 搜索建议返回对象
 * @author chunyang.leng
 * @date 2023-08-21 19:02
 */
public class SuggestVO {
    /**
     * 数据id
     */
    private Long id;

    /**
     * 内容
     */
    private String text;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

搜索业务层

  • 数据导入时候,因为有数据格式要求,必须使用实体类进行写入

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.CompletionSuggester;
import co.elastic.clients.elasticsearch.core.search.Suggester;
import co.elastic.clients.elasticsearch.core.search.Suggestion;
import co.elastic.clients.elasticsearch.core.search.TermSuggester;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author chunyang.leng
 * @date 2023-08-18 18:29
 */
@Component
public class SuggestionServiceImpl implements SuggestionService {
    /**
     * 搜索建议 key
     */
    private static final String SUGGEST_TAG = "suggest_query";

    /**
     * 纠错key
     */
    private static final String TERM_TAG = "suggest_team";
    @Autowired
    private ElasticsearchClient elasticsearchClient;

    /**
     * 根据 关键词,返回搜索建议
     *
     * @param match 搜索关键词
     * @return 搜索建议,10条
     */
    @Override
    public List<SuggestVO> suggest(String match) throws IOException {
        SearchRequest completionSuggestSearchRequest = new SearchRequest
            .Builder()
            .suggest(
                new Suggester
                    .Builder()
                    .suggesters(SUGGEST_TAG, builder -> builder.prefix(match)
                        .completion(new CompletionSuggester
                            .Builder()
                            .field("completionName")
                            .size(10)
                            .build()
                        )
                    )
                    .build())
            .build();

        SearchResponse<BizSuggestDocument> completionSuggestSearch = elasticsearchClient.search(completionSuggestSearchRequest, BizSuggestDocument.class);

        Map<String, List<Suggestion<BizSuggestDocument>>> suggest = completionSuggestSearch.suggest();

        List<Suggestion<BizSuggestDocument>> suggestions = suggest.get(SUGGEST_TAG);

        return suggestions
            .parallelStream()
            .flatMap(x -> x.completion()
                .options()
                .stream()
                .map(o -> {
                      // 原始数据对象,如果有需要,可以对其进行操作
                    BizSuggestDocument source = o.source();
                    
                   
                    String text = o.text();
                    String idValue = o.id();
                    Long id = Long.valueOf(idValue);
                    SuggestVO vo = new SuggestVO();
                    vo.setId(id);
                    vo.setText(text);
                    return vo;
                }))
            .collect(Collectors.toList());
    }
}

导入数据


import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.suggest.Completion;

/**
 * @author chunyang.leng
 * @date 2023-08-21 18:09
 */
@SpringBootTest
public class EsTest {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Test
    public void test() {
        BizSuggestDocument document = new BizSuggestDocument();
        document.setId(1L);
        document.setName("飞翔的世界");

        String[] s = "你的世界1.0,我的世界2.0".split(",");
        Completion completion = new Completion(s);
        completion.setWeight(10);
        document.setCompletionName(completion);
        elasticsearchTemplate.save(document);


        BizSuggestDocument document2 = new BizSuggestDocument();
        document2.setId(2L);
        document2.setName("路人甲乙丙");

        String[] s2 = "你的滑板鞋1.0,我的滑板鞋2.0".split(",");
        Completion completion1 = new Completion(s2);
        completion1.setWeight(5);
        document2.setCompletionName(completion1);
        elasticsearchTemplate.save(document2);
    }
}

POSTMAN 测试结果如下

在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

牛客OJ 把字符串转换成整数

⭐️ 题目描述 &#x1f31f; O链接 https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId13&&tqId11202&rp6&ru/activity/oj&qru/ta/coding-interviews/question-ranking 思路&#xff1a; 首先需要检查第一位是否有符号位&#x…

用Idea把SpringBoot项目打包镜像上传至docker

1、设置docker把2375端口开起来 命令查看docker装在哪里 vim docker.service 新增 -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock 2、配置Dockerfile 我在跟pom同一层 3、配置docker-maven-plugin <plugin><groupId>com.spotify</groupId><arti…

Fegin异步情况丢失上下文问题

在微服务的开发中&#xff0c;我们经常需要服务之间的调用&#xff0c;并且为了提高效率使用异步的方式进行服务之间的调用&#xff0c;在这种异步的调用情况下会有一个严重的问题&#xff0c;丢失上文下 通过以上图片可以看出异步丢失上下文的原因是不在同一个线程&#xff0c…

Redis数据结构之Set

Set 类型是一个无序并唯一的键值集合&#xff0c;它的存储顺序不会按照插入的先后顺序进行存储。Redis 中集合是通过哈希表实现的&#xff0c;所以添加&#xff0c;删除&#xff0c;查找的复杂度都是 O(1)。相对于列表&#xff0c;集合也有两个特点&#xff1a;无序、不可重复 …

spring之Spring测试与集成

Spring测试与集成 摘要引言词汇解释详细介绍单元测试和集成测试单元测试和集成测试编写单元测试和集成测试代码单元测试示例集成测试示例 Spring Test和JUnit简介编写使用Spring Test和JUnit的测试代码UserService示例单元测试示例 使用Spring Test和JUnit 注意事项总结参考资料…

【WebSocket】前端使用WebSocket实时通信

目录 前言什么是WebSocketWebSocket的工作原理WebSocket与HTTP的关系HTTP建立持久化连接WebSocket类封装 前言 最近写项目&#xff0c;需要实现消息通知和实时聊天的功能&#xff0c;就去了解了一些关于websocket的知识&#xff0c;总结如下。 什么是WebSocket WebSocket 是一…

5.8.webrtc事件处理基础知识

在之前的课程中呢&#xff0c;我向你介绍了大量web rtc线程相关内容&#xff0c;今天呢&#xff0c;我们来看一下线程事件处理的基本知识。首先&#xff0c;我们要清楚啊&#xff0c;不同的平台处理事件的API是不一样的&#xff0c;这就如同我们当时创建线程是类似的&#xff0…

第12步---MySQL的JDBC操作

第12步---MySQL的JDBC操作 1.概述 采用Java API 的方式实现数据之间的操作。 根据不同的数据库采用了不同的驱动&#xff0c;接口是一致的。 下载的地址 MySQL :: Download MySQL Connector/J (Archived Versions) 2.执行流程 注册驱动 创建连接 执行sql语句的对象 结果…

Kaggle回归问题Mercedes——Benz Greener Manufacturing

目录 前言1 题目介绍2 数据清洗3 数据可视化分析4 模型训练5 源码 前言 这是我在大三选修课的课程设计&#xff0c;内容参考了Kaggle上高赞的代码&#xff0c;有详细批注&#xff0c;整体比较基础&#xff0c;结构相对完整&#xff0c;便于初学者学习。这个是一个回归问题&…

MAC电脑外放没有声音解决方案

烦人呐&#xff0c;我的mac外接显示屏幕&#xff0c;显示器没有音频输出&#xff0c;需要mac笔记本的音频输出&#xff0c;但是经常打开后&#xff0c;mac没有声音输出&#xff0c;需要重启电脑才能生效。亲测一下方法有效&#xff0c;请参考&#xff1a; 文章目录 一、短期方案…

17.4 【Linux】systemctl 针对 timer 的配置文件

有时候&#xff0c;某些服务你想要定期执行&#xff0c;或者是开机后执行&#xff0c;或者是什么服务启动多久后执行等等的。在过去&#xff0c;我们大概都是使用 crond 这个服务来定期处理&#xff0c; 不过&#xff0c;既然现在有一直常驻在内存当中的 systemd 这个好用的东西…

无涯教程-PHP - 常量数组

现在可以使用 define()函数定义数组常量。在PHP 5.6中&#xff0c;只能使用 const 关键字定义它们。 <?php//define a array using define functiondefine(animals, [dog,cat,bird]);print(animals[1]); ?> 它产生以下浏览器输出- cat PHP - 常量数组 - 无涯教程网无…

excel逻辑函数篇1

1、AND(logical1,[logical2],…)&#xff1a;用于测试所有条件是否均为TRUE 检查所有参数均为true&#xff0c;如果是则返回true 2、OR(logical1,[logical2],…)&#xff1a;用于测试是否有为TRUE的条件 如果任意参数值为true&#xff0c;即返回true&#xff1b;只有当所有参数…

673. 最长递增子序列的个数

673. 最长递增子序列的个数 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;方法一&#xff1a;动态规划方法二&#xff1a;贪心 前缀和 二分查找 参考代码&#xff1a;__673最长递增子序列的个数__动态规划__673最长递增子序列的个数__贪心_前缀和_二分查找…

ChatGPT 随机动态可视化图表分析

动态可视化图表分析实例如下图&#xff1a; 这样的动态可视化图表可以使用ChatGPT OpenAI 来实现。 给ChatGPT发送指令&#xff1a; 你现在是一个数据分析师&#xff0c;请使用HTML&#xff0c;JS&#xff0c;Echarts&#xff0c;来完成一个动态条形图&#xff0c;条形图方向横…

汽车电子笔记之:AUTOSA架构下的OS概述

目录 1、实时操作系统&#xff08;RTOS&#xff09; 2、OSEK操作系统 2.1、OSEK概述 2.2、OSEK处理等级 2.3、OSEK任务符合类 2.4、OSEK优先级天花板模式 3、AUTOSAR OS 3.1、 AUTOSAR OS对OSEK OS的继承和扩展 3.2、AUTOSAR OS的调度表 3.3、AUTOSAR OS的时间保护 3…

OS 内核级线程

用户级线程是两个栈&#xff0c;核心级线程是两套栈&#xff0c;用户栈和内核栈 用户级是并发&#xff08;同时触发、交替执行&#xff09;&#xff0c;这个是并行&#xff08;同时触发可以同时执行&#xff09; 进入内核的唯一方式是中断 根据TCB的切换&#xff0c;实现内核…

C++11特性详解

一、简介 在C11标准出来之前&#xff0c;一直是C98/03标准占引领地位&#xff0c;而C98/03标准是C98标准在2003年将存在的一些漏洞进行了修复&#xff0c;但并没有核心语法的改动。相比于C98/03&#xff0c;C11则带来了数量可观的变化&#xff0c;其中包含了约140个新特性&…

深度学习处理文本(NLP)

文章目录 引言1. 反向传播1.1 实例流程实现1.2 前向传播1.3 计算损失1.4 反向传播误差1.5 更新权重1.6 迭代1.7 BackPropagation & Adam 代码实例 2. 优化器 -- Adam2.1 Adam解析2.2 代码实例 3. NLP任务4. 神经网络处理文本4.1 step1 字符数值化4.2 step 2 矩阵转化为向量…

HTML基础知识点

目录 ​编辑一、使用 vscode 二、研究代码的特点 三、HTML 常见标签 注释标签 标题标签 段落标签 换行标签 格式化标签 图片标签 超链接标签 表格标签 列表标签 表单标签&#xff1a; form 标签 input标签&#xff1a; select textarea标签&#xff1a; 无语…