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

Springboot整合elasticsearch详解 封装模版 仓库方法 如何在linux里安装elasticsearch

目录

版本

下载地址

ElasticSearch频繁报503错误

开放 9300 和 9200 两个端口

测试联通性

改动包装类

elasticsearchTemplate

getAllRespRepository

封装elasticsearchService

业务逻辑


版本

首先要对应版本

这是我在官网找到的版本信息

一定要 springboot 和 es 相互对应

下载地址

Past Releases of Elastic Stack Software | Elastic

ElasticSearch频繁报503错误

# 开启跨域访问支持,默认为false
http.cors.enabled: true
# 跨域访问允许的域名地址
http.cors.allow-origin: "*"
# 通过为 cluster.initial_master_nodes 参数设置符合主节点条件的节点的 IP 地址来引导启动集群
cluster.initial_master_nodes: ["node-1"]

开放 9300 和 9200 两个端口

关于ElasticSearch的9200和9300端口区别

9200作为Http协议,主要用于外部通讯

9300作为Tcp协议,jar之间就是通过tcp协议通讯

ES集群之间是通过9300进行通讯

测试联通性

linux 上启动服务

使用客户端 es-client

改动包装类

要使其变为 elasticsearch 可以识别的包装类

@Document 类注解中标注其索引(在 elasticsearch 中指的是表名)、

@Id 主键注解

@Field 字段注解中打上标识 表示elasticsearch中可能要进行全文搜索的字段

package work.dduo.ans.model.vo.response;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "sentences")
public class GetAllContentResp {

    @Id
    private Integer id;

    @Field(type = FieldType.Text) // elasticsearch中可能要进行全文搜索的字段
    private String content;

    private Date createTime;

    @Field(type = FieldType.Text) // elasticsearch中可能要进行全文搜索的字段
    private String from;

    private String hot;

    private String other1;

    private String other2;

    private String other3;
}

elasticsearchTemplate

elasticsearchTemplate 是 Java 提供的模版工具类

我们主要用其 search 方法来查询

getAllRespRepository

存储库

类似于 mybatis

我们通过一个类继承 ElasticsearchRepository

来直接调用父类方法中的增删改查方法

package work.dduo.ans.elasticsearch.repository;

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import work.dduo.ans.model.vo.response.GetAllContentResp;

// 该接口提供了基本的CRUD操作。
public interface GetAllRespRepository extends ElasticsearchRepository<GetAllContentResp, Integer> {

}

注意我们要将包装类和主键类型作为参数传入

封装elasticsearchService

package work.dduo.ans.elasticsearch.service;

import org.elasticsearch.index.query.*;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import work.dduo.ans.elasticsearch.repository.GetAllRespRepository;
import work.dduo.ans.model.vo.response.GetAllContentResp;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ElasticsearchService {

    @Autowired
    private ElasticsearchOperations elasticsearchTemplate;

    @Autowired
    private GetAllRespRepository getAllRespRepository;

    /**
     * 更新数据到elasticsearch
     *
     * @param getAllResp
     * @return
     */
    public List<GetAllContentResp> saveProduct(List<GetAllContentResp> getAllResp) {
        //  把传入的数据 存入elasticsearch
        return (List<GetAllContentResp>) getAllRespRepository.saveAll(getAllResp);
    }

    /**
     * 单字符串全文查询,支持分页和排序 查询包括字符串的所有数据 所有字段
     *
     * @param queryString 查询字符串
     * @param page        页码
     * @param size        每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> fullTextSearch(String queryString, int page, int size) {
        // 构建查询条件
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(queryString);
        // 构建搜索查询,设置分页和排序
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withPageable(PageRequest.of(page, size))
                .withSort(SortBuilders.fieldSort("id").order(SortOrder.ASC)) // 按照id排序 正序
                .build();
        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);
        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

    /**
     * 某字段按字符串模糊查询 只查询指定字段
     *
     * @param field 字段名
     * @param value 查询值
     * @param page  页码
     * @param size  每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> fuzzySearchByField(String field, String value, int page, int size) {
        // 构建模糊查询条件
        QueryBuilder queryBuilder = QueryBuilders.matchQuery(field, value);
        // 构建搜索查询,设置分页
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withPageable(PageRequest.of(page, size))
                .build();
        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);
        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

    /**
     * PhraseMatch 查询(短语匹配)
     *
     * @param field  字段名
     * @param phrase 短语
     * @param slop   允许的最大间隔
     * @param page   页码
     * @param size   每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> phraseMatchSearch(String field, String phrase, int slop, int page, int size) {
        // 构建短语匹配查询条件
        QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery(field, phrase).slop(slop);
        // 构建搜索查询,设置分页
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withPageable(PageRequest.of(page, size))
                .build();
        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);
        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

    /**
     * Term 查询(精确查询)
     *
     * @param field 字段名
     * @param value 查询值
     * @param page  页码
     * @param size  每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> termSearch(String field, Object value, int page, int size) {
        // 构建精确查询条件
        QueryBuilder queryBuilder = QueryBuilders.termQuery(field, value);
        // 构建搜索查询,设置分页
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withPageable(PageRequest.of(page, size))
                .build();
        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);
        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

    /**
     * multi_match 多个字段匹配某字符串
     *
     * @param fields 字段数组
     * @param value  查询值
     * @param page   页码
     * @param size   每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> multiMatchSearch(String[] fields, String value, int page, int size) {
        // 构建多字段匹配查询条件
        QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(value, fields);
        // 构建搜索查询,设置分页
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withPageable(PageRequest.of(page, size))
                .build();
        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);
        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

    /**
     * 完全包含查询
     *
     * @param field              字段名
     * @param value              查询值
     * @param operator           操作符(如 AND、OR)
     * @param minimumShouldMatch 最少匹配百分比
     * @param page               页码
     * @param size               每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> exactMatchSearch(String field, String value, String operator, String minimumShouldMatch, int page, int size) {
        // 构建匹配查询条件
        QueryBuilder queryBuilder = QueryBuilders.matchQuery(field, value)
                .operator(Operator.fromString(operator))
                .minimumShouldMatch(minimumShouldMatch);
        // 构建搜索查询,设置分页
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withPageable(PageRequest.of(page, size))
                .build();
        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);
        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

    /**
     * 合并查询(boolQuery) 并集
     *
     * @param mustField    必须匹配的字段
     * @param mustValue    必须匹配的值
     * @param filterField  过滤字段
     * @param filterValue  过滤值
     * @param shouldField  可选匹配的字段
     * @param shouldValues 可选匹配的值数组
     * @param page         页码
     * @param size         每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> boolQuerySearch(String mustField, String mustValue, String filterField, Object filterValue, String shouldField, List<Object> shouldValues, int page, int size) {
        // 构建布尔查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 添加 must 条件
        boolQuery.must(QueryBuilders.matchQuery(mustField, mustValue));
        // 添加 filter 条件
        boolQuery.filter(QueryBuilders.termQuery(filterField, filterValue));
        // 添加 should 条件
        for (Object shouldValue : shouldValues) {
            boolQuery.should(QueryBuilders.termQuery(shouldField, shouldValue));
        }
        // 构建搜索查询,设置分页
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQuery)
                .withPageable(PageRequest.of(page, size))
                .build();
        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);
        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

    /**
     * 某两个字段按字符串模糊查询 只查询指定字段
     *
     *
     * @param field1 第一个字段名
     * @param value1 第一个查询值
     * @param field2 第二个字段名
     * @param value2 第二个查询值
     * @param page   页码
     * @param size   每页数量
     * @return 查询结果列表
     */
    public List<GetAllContentResp> fuzzySearchByTwoFields(String field1, String value1, String field2, String value2, int page, int size) {
        // 构建第一个字段的模糊查询条件
        MatchQueryBuilder queryBuilder1 = QueryBuilders.matchQuery(field1, value1);
        // 构建第二个字段的模糊查询条件
        MatchQueryBuilder queryBuilder2 = QueryBuilders.matchQuery(field2, value2);

        // 使用 bool 查询将两个查询条件组合起来 并集
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
//                .should(queryBuilder1)
//                .should(queryBuilder2);

        // 使用 bool 查询将两个查询条件组合起来 交集
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(queryBuilder1)
                .must(queryBuilder2);


        // 构建搜索查询,设置分页
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(PageRequest.of(page, size))
                .build();

        // 执行查询
        SearchHits<GetAllContentResp> searchHits = elasticsearchTemplate.search(searchQuery, GetAllContentResp.class);

        // 提取查询结果
        return searchHits.getSearchHits().stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
    }

}

业务逻辑

写入功能

同步 es 的数据

    /**
     * 更新数据到elasticsearch
     *
     * @param getAllResp
     * @return
     */
    public List<GetAllContentResp> saveProduct(List<GetAllContentResp> getAllResp) {
        //  把传入的数据 存入elasticsearch
        return (List<GetAllContentResp>) getAllRespRepository.saveAll(getAllResp);
    }

搜索功能

客制化搜索

    /**
     * 查询句子数据
     *
     * @param queryWordsResp
     * @return
     */
    @Override
    public List<GetAllContentResp> queryWords(QueryWordsResp queryWordsResp) {
        // 根据传入的参数是匹配不同的查询类型
        if (StrUtil.isBlank(queryWordsResp.getContent()) && StrUtil.isBlank(queryWordsResp.getFrom())) {
            // 传了两个空值进来 走缓存->走数据库
            return tSentencesMapper.getAll();
        } else if (StrUtil.isBlank(queryWordsResp.getFrom())) {
            // 只传了content 走elasticsearch 模糊查询
            String content = queryWordsResp.getContent();
            List<GetAllContentResp> results = elasticsearchService.fuzzySearchByField("content", content, 0, 10);
            return results;
        } else if (StrUtil.isBlank(queryWordsResp.getContent())) {
            // 只穿了from 走elasticsearch 模糊查询
            String from = queryWordsResp.getFrom();
            // 注意英文名称难以分词 就会出现不能模糊查询的缺点
            List<GetAllContentResp> results = elasticsearchService.fuzzySearchByField("from", from, 0, 10);
            return results;
        } else {
            // 两个字段都有数值 走elasticsearch
            List<GetAllContentResp> results = elasticsearchService.fuzzySearchByTwoFields(
                    "content", queryWordsResp.getContent(),
                    "from", queryWordsResp.getFrom(),
                    0, 10);
            return results;
        }
    }

http://www.kler.cn/a/601490.html

相关文章:

  • 从零开始实现 C++ TinyWebServer 构建响应 HttpResponse类详解
  • linux-------------进程概念(中)
  • ideaIU-2023.2.5.exe install (IntelliJ_IDEA_IU_2023.2.5)
  • 宝塔面板安装docker flarum失败,请先安装依赖应用: [‘mysql‘]:5/8
  • MongoDB不支持事务
  • 24、web前端开发之CSS3(一)
  • iPhone 16如何翻译文档?文档翻译技巧、软件推荐
  • 第五天 开始Unity Shader的学习之旅之Unity中的基础光照之漫反射光照模型
  • “thrust“ has no member “device“
  • OpenEMMA: 基于多模态大语言模型的端到端开源自动驾驶框架
  • linux如何释放内存缓存
  • WPS的PPT智能图形增加项目
  • 解锁PyPDF2:轻松驾驭PDF文件的Python库
  • dell 台式机 电脑 纽扣电池 如何取下?
  • SSE底层实现?SSE 和 websocket的区别?
  • WPF 浅述ToolTipService.ShowOnDisabled
  • 头歌实践教学平台--【数据库概论】--SQL
  • 微信小程序面试内容整理-如何优化小程序的启动速度?
  • HWHVV护网入门基础知识
  • VSCODE右下角切换环境没用