springboot3.x集成Elasticsearch8.5.3

1. 前言

项目基础为springboot3.0.2,目标是实现Elasticsearch的自定义高亮分页查询,网上提供的方法都是通过继承ElasticsearchRepository实现相关的查询,但是当我查询条件过多且复杂的时候方法命名会非常长,所以暂时弃用,投奔之前用过的spring-boot-starter-data-elasticsearch(主要使用的还是spring-data-elasticsearch5.0.1)。

由于spring-data-elasticsearch5.0.1版本中弃用了ElasticsearchRestTemplate类以及HighlightBuilder,高亮查询就变得异常麻烦。

2. 依赖与参数配置

2.1 pom.xml

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  <version>3.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-queryparser -->
<dependency>
  <groupId>org.apache.lucene</groupId>
  <artifactId>lucene-queryparser</artifactId>
  <version>8.11.2</version>
</dependency>

2.2 application.yml

yml 复制代码
spring:
  elasticsearch:
    uris: xxx
    username: xxxx
    password: xxxxx

3. 代码实现

java 复制代码
@Data
@Document(indexName = "user")
public class User {
    @Id
    private String id;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String name;
    @Field(type = FieldType.Date)
    private Date bir;
	@Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String content;
}
java 复制代码
@Service
@RequiredArgsConstructor
public class EsService {
    private final ElasticsearchTemplate restTemplate;

    /**
     * 初始化es序列
     */
    public boolean initIndex() {
        IndexOperations indexOperations = restTemplate.indexOps(User.class);
        if (!indexOperations.exists()) {
            indexOperations.create();
            Document mapping = indexOperations.createMapping();
            indexOperations.putMapping(mapping);
            return true;
        }
        return false;
    }

    /**
     * 初始化es数据
     *
     * @throws IOException
     */
    public void initEsData() {
        // 查询获取用户信息
        restTemplate.save(users);
    }


    /**
     * 分页查询数据
     *
     * @param keyword
     * @param pageNo
     * @param pageSize
     * @throws IOException
     */
    @Highlight(
            fields = {
                    @HighlightField(name = "field1"),
                    @.HighlightField(name = "field12"),
                    @HighlightField(name = "field13")
            },
            parameters = @HighlightParameters(
                    preTags = "<span style='color:#799ed9'>",
                    postTags = "</span>",
                    fragmentSize = 30,
                    numberOfFragments = 3,
                    requireFieldMatch = false
            )
    )// 高亮配置信息
    public PageInfo<User> searchEs(String keyword, Integer pageNo, Integer pageSize) {
        PageInfo<User> pageInfo = new PageInfo<>();
        if (pageNo <= 0) {
            pageNo = 1;
        }
        if (pageSize <= 0) {
            pageSize = 10;
        }
        pageInfo.setPageNo(pageNo);
        pageInfo.setPageSize(pageSize);
        // 分页数据
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, Sort.Direction.DESC, "publishDate");

        // 条件查询
        SimpleQueryStringQuery queryBuilder = null;
        if (StringUtils.isNotBlank(keyword)) {
            keyword = QueryParser.escape(keyword);
            keyword = "\"" + keyword + "\"";
            queryBuilder = new SimpleQueryStringQuery.Builder().fields("field1", "field2")
                    .query(keyword).analyzer("ik_max_word").build(); // 查询条件
        }
        SimpleQueryStringQuery finalQueryBuilder = queryBuilder;
        NativeQueryBuilder builder = NativeQuery.builder();
        if (queryBuilder != null) {
            builder = builder.withQuery(q -> q.simpleQueryString(finalQueryBuilder));
        }
        // 创建一个HighlightQuery实例,指定要高亮的字段
        Method method = getMethod(EsService.class, "searchEs");
        if (method != null) {
            Highlight highlight = method.getAnnotation(Highlight.class);
            HighlightQuery highlightQuery = new HighlightQuery(
                    org.springframework.data.elasticsearch.core.query.highlight.Highlight.of(highlight),
                    User.class);
            builder = builder.withHighlightQuery(highlightQuery);
        }

        Query query = builder.withPageable(pageable).build();
        SearchHits<User> search = restTemplate.search(query, User.class);
        List<SearchHit<User>> searchHits = search.getSearchHits();

        long totalHits = search.getTotalHits();
        if (totalHits <= 0) {
            return pageInfo;
        }
        pageInfo.setCount(totalHits);
        List<User> list = new ArrayList<>();
        // 设置高亮数据
        for (SearchHit<User> hit : searchHits) {
            User content = hit.getContent();
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(content));
            Map<String, List<String>> highlightFields = hit.getHighlightFields();
            if (highlightFields.isEmpty()) {
                list.add(content);
                continue;
            }
            for (Map.Entry<String, List<String>> entry : highlightFields.entrySet()) {
                StringBuffer stringBuffer = new StringBuffer();
                for (int i = 0; i < entry.getValue().size(); i++) {
                    if (i > 0) {
                        stringBuffer.append(",");
                    }
                    stringBuffer.append(entry.getValue().get(i));
                }
                jsonObject.put(entry.getKey(), stringBuffer.toString());
            }
            content = JSONObject.parseObject(jsonObject.toJSONString(), User.class);
            list.add(content);
        }
        pageInfo.setList(list);
        return pageInfo;
    }

    /**
     * 获取方法
     *
     * @param clz
     * @param methodName
     * @return
     */
    private Method getMethod(Class clz, String methodName) {
        Method[] methods = clz.getMethods();
        for (Method method : methods) {
            if (!method.getName().equals(methodName)) {
                continue;
            }
            return method;
        }
        return null;
    }
}

4. 结束语

本文通过一些非常规手段实现对应的高亮分页查询;仅供参考,如有更好的方式请留言指导,谢谢各位。

相关推荐
LUCIAZZZ5 小时前
JVM之内存管理(一)
java·jvm·spring·操作系统·springboot
Kakaxiii9 小时前
【2025最新】gitee+pycharm完成项目的上传与管理
elasticsearch·pycharm·gitee
不学会Ⅳ19 小时前
【吃透 Elasticsearch 的核心原理】学习步骤
大数据·学习·elasticsearch
完美世界的一天1 天前
ES面试题系列「一」
大数据·elasticsearch·搜索引擎·面试·全文检索
好吃的肘子2 天前
ElasticSearch入门详解
java·大数据·elasticsearch·搜索引擎·云原生
LUCIAZZZ2 天前
JVM之内存管理(二)
java·jvm·后端·spring·操作系统·springboot
极小狐2 天前
如何从极狐GitLab 容器镜像库中删除容器镜像?
java·linux·开发语言·数据库·python·elasticsearch·gitlab
A-花开堪折2 天前
RK3568-OpenHarmony(1) : OpenHarmony 5.1的编译
大数据·elasticsearch·搜索引擎
斯普信专业组3 天前
Elasticsearch内存管理与JVM优化:原理剖析与最佳实践
大数据·jvm·elasticsearch
天上掉下来个程小白3 天前
缓存套餐-01.Spring Cache入门案例
java·redis·spring·缓存·springboot·springcache