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. 结束语

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

相关推荐
一次旅行20 小时前
【效率秘籍】Shell 函数+别名组合拳,让 80% 的重复命令变 1 个字母
大数据·elasticsearch·搜索引擎
暖和_白开水20 小时前
数据分析agent(九):es_client_manager.py 和分词器ik_max_word问题
elasticsearch·数据分析·c#
码农学院21 小时前
Elasticsearch构建汽车零配件智能搜索与匹配系统
大数据·elasticsearch·汽车
troyzhxu1 天前
列表查询的 GraphQL —— 一行代码终结你的 if-else 地狱!
java·springboot·graphql
Elastic 中国社区官方博客2 天前
不到 5 分钟完成本地部署:Jina embedding 模型现已支持本地部署
大数据·人工智能·elasticsearch·搜索引擎·embedding·jina
二进制流水搬运工2 天前
入职第一天拉了23个仓库,我写了个脚本解放双手
大数据·elasticsearch·搜索引擎
Elasticsearch2 天前
在不到一小时内将 Datadog Kubernetes 仪表板迁移到 Elastic Observability
elasticsearch
.柒宇.2 天前
Elasticsearch 核心概念与系统架构详解
elasticsearch·系统架构
风行無痕2 天前
单机Elasticsearch 8.19.18安全升级到9.4.3的过程
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客2 天前
使用重新设计的 AutoOps 更快地进行 Elasticsearch 问题排查
大数据·运维·前端·人工智能·elasticsearch·搜索引擎·全文检索