小工具知识网

当前位置: 首页 > 行业知识 > SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)

行业知识

SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)

2026-11-03 22:19:52 来源:互联网转载

SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)


文章目录

  • SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)
    • @[TOC]
    • 前言
    • 一、项目依赖
    • 二、springboot集成实现
      • 1.ElasticSearchConfig配置实现
      • 2.elasticsearch工具类
      • 3.定义一个ES存储数据结构体
      • 4.elasticsearch查询工具类
        • 4.1.查询满足条件的数据
        • 4.2.查询某些分组下满足条件的数据
        • 4.3.查询某个文档的数据并高亮显示关键词
        • 4.4.查询多条件OR匹配查询
        • 5.elasticsearch增删工具类
          • 5.1.批量增加数据
          • 5.2.批量删除数据
          • 5.调用测试实现
          • 总结

���节

()

第一章链接: SpringBoot集成Elasticsearch7.x(1)|(增删改查功能实现)

第二章链接: SpringBoot集成Elasticsearch7.x(2)|(复杂查询)

()

第三章链接: SpringBoot集成Elasticsearch7.x(3)|(aggregations之指标聚合查询)

第四章链接: SpringBoot集成Elasticsearch7.x(4)|(aggregations之分桶聚合查询)

第五章链接: SpringBoot集成Elasticsearch7.x(5)|(term、match、match_phrase区别)

第六章链接: SpringBoot集成Elasticsearch8.x(6)|(新版本Java API Client使用)

第七章链接: SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)

第八章链接:SpringBoot集成Elasticsearch8.x(8)|(新版本Java API Client的Painless语言脚本script使用)

前言

在Es7.15版本之后,es官方将它的高级客户端RestHighLevelClient标记为弃用状态。同时推出了全新的java API客户端Elasticsearch Java API Client,该客户端也将在Elasticsearch8.0及以后版本中成为官方推荐使用的客户端。

一、项目依赖

这里没有应用springboot版本自带elasticsearch依赖,自带的版本应该是7.x的,所以单独引入了elasticsearch8.x依赖

            org.springframework.boot       spring-boot-starter-parent       2.5.7                               co.elastic.clients           elasticsearch-java           8.1.0                         org.glassfish           jakarta.json           2.0.1       

二、springboot集成实现

1.ElasticSearchConfig配置实现

注入elasticsearch客户端,此处兼容了es的集群模式配置格式http://ip1:9200、http://ip2:9200

@Configurationpublic class ElasticSearchConfig {    @Value("${es.hosts}")    private String hosts;    @Value("${es.name:elastic}")    private String name;    @Value("${es.password:aimind}")    private String password;    @Bean    public ElasticsearchClient docqaElasticsearchClient() {        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(name, password));        List httpHosts = Lists.newArrayList();        String[] split = hosts.split(",");        for (int i = 0; i                         httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider).setKeepAliveStrategy((response, context) -> 180 * 1000))                .build();        ElasticsearchTransport transport = new RestClientTransport(client, new JacksonJsonpMapper());        return new ElasticsearchClient(transport);    }}

2.elasticsearch工具类

ElasticsearchHandle工具类主要是封装elasticsearch的索引,数据对应的一些增删改查方法

@Slf4j@Componentpublic class ElasticsearchHandle {    @Autowired    private ElasticsearchClient client;    /**     * 判断索引是否存在     *     * @param indexName     * @return     * @throws IOException     */    public boolean hasIndex(String indexName) throws IOException {        BooleanResponse exists = client.indices().exists(d -> d.index(indexName));        return exists.value();    }    /**     * 删除索引     *     * @param indexName     * @throws IOException     */    public boolean deleteIndex(String indexName) throws IOException {        DeleteIndexResponse response = client.indices().delete(d -> d.index(indexName));        return true;    }    /**     * 创建索引     *     * @param indexName     * @return     * @throws IOException     */    public boolean createIndex(String indexName) {        try {            CreateIndexResponse indexResponse = client.indices().create(c -> c.index(indexName));        } catch (IOException e) {            log.error("索引创建失败:{}", e.getMessage());            throw new ExploException(HttpCode.INDEX_CREATE_ERROR, "创建索引失败");        }        return true;    }    /**     * 创建索引,不允许外部直接调用     *     * @param indexName     * @param mapping     * @throws IOException     */    private boolean createIndex(String indexName, Map mapping) throws IOException {        CreateIndexResponse createIndexResponse = client.indices().create(c -> {            c.index(indexName).mappings(mappings -> mappings.properties(mapping));            return c;        });        return createIndexResponse.acknowledged();    }//    public Map buildMapping( Map propertyKeys) {//        Map documentMap = new HashMap();//        for (Map.Entry propertyKey : propertyKeys.entrySet()) {//            String type = getIndxPropType(propertyKey.getValue());//            String key = propertyKey.getKey();//            log.info("属性:{}类型:{}", key, type);//            if (type.equals("text")) {//                documentMap.put(key, Property.of(property ->//                                property.keyword(KeywordProperty.of(p ->// p.index(true)//                                        )//                                )//                        )//                );//            } else if (type.equals("date")) {//                documentMap.put(key, Property.of(property ->//                                property.date(DateProperty.of(p ->// p.index(true).format("yyyy-MM-dd HH:mm:ss.SSS")//                                        )//                                )//                        )//                );//            } else if (type.equals("long")) {//                documentMap.put(key, Property.of(property ->//                                property.long_(LongNumberProperty.of(p ->// p.index(true)//                                        )//                                )//                        )//                );//            } else if (type.equals("integer")) {//                documentMap.put(key, Property.of(property ->//                                property.integer(//                                        IntegerNumberProperty.of(p ->// p.index(false)//                                        )//                                )//                        )//                );//            } else {//                documentMap.put(key, Property.of(property ->//                                property.object(//                                        ObjectProperty.of(p ->// p.enabled(true)//                                        )//                                )//                        )//                );//            }//        }//        return documentMap;//    }    /**     * 重新创建索引,如果已存在先删除     *     * @param indexName     * @param mapping     */    public void reCreateIndex(String indexName, Map mapping) {        try {            if (this.hasIndex(indexName)) {                this.deleteIndex(indexName);            }        } catch (IOException e) {            e.printStackTrace();            throw new ExploException(HttpCode.INDEX_DELETE_ERROR, "删除索引失败");        }        try {            this.createIndex(indexName, mapping);        } catch (IOException e) {            e.printStackTrace();            throw new ExploException(HttpCode.INDEX_CREATE_ERROR, "重新创建索引失败");        }    }    /**     * 新增数据     *     * @param indexName     * @throws IOException     */    public boolean insertDocument(String indexName, Object obj, String id) {        try {            IndexResponse indexResponse = client.index(i -> i                    .index(indexName)                    .id(id)                    .document(obj));            return true;        } catch (IOException e) {            log.error("数据插入ES异常:{}", e.getMessage());            throw new ExploException(HttpCode.ES_INSERT_ERROR, "ES新增数据失败");        }    }    /**     * 查询数据     *     * @param indexName     * @param id     * @return     */    public GetResponse searchDocument(String indexName, String id) {        try {            GetResponse getResponse = client.get(g -> g                            .index(indexName)                            .id(id)                    , DocumentPartESDto.class            );            return getResponse;        } catch (IOException e) {            log.error("查询ES异常:{}", e.getMessage());            throw new ExploException(HttpCode.ES_SEARCH_ERROR, "查询ES数据失败");        }    }    /**     * 删除数据     *     * @param indexName     * @param id     * @return     */    public boolean deleteDocument(String indexName, String id) {        try {            DeleteResponse deleteResponse = client.delete(d -> d                    .index(indexName)                    .id(id)            );        } catch (IOException e) {            log.error("删除Es数据异常:{}", e.getMessage());            throw new ExploException(HttpCode.ES_DELETE_ERROR, "数据删除失败");        }        return true;    }}

3.定义一个ES存储数据结构体

定义一个实体,用于向ES中存储数据

@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class DocumentPartESDto {    private String id;    private String docId;    private String kgId;    private String content;    private String type;}

4.elasticsearch查询工具类

由于我们使用大多情况是查询的场景,这里我来完善查询的一些方法

4.1.查询满足条件的数据

参数介绍

ndexName:为索引名称

query:查询的内容

top :查询条数

   public List search(String indexName, String query,int top) {        List documentParagraphs = Lists.newArrayList();        try {            SearchResponse search = client.search(s -> s                            .index(indexName)                            .query(q -> q                                    .match(t -> t                                            .field("content")                                            .query(query)                                    ))                            .from(0)                            .size(top)//                    .sort(f -> f.field(o -> o.field("docId").order(SortOrder.Desc)))                    , DocumentParagraph.class            );            for (Hit hit : search.hits().hits()) {                DocumentParagraph pd = hit.source();                documentParagraphs.add(pd);            }        } catch (IOException e) {            log.error("查询ES异常:{}", e.getMessage());            throw new ExploException(HttpCode.ES_SEARCH_ERROR, "查询ES数据失败");        }        return documentParagraphs;    }

4.2.查询某些分组下满足条件的数据

参数介绍

ndexName:为索引名称

query:查询的内容

categoryId: 查询那些类别下的数据

top :查询条数

 public List search(String indexName, String query, List categoryId,int top) {        List documentParagraphs = Lists.newArrayList();        List values = new ArrayList();        for (String id : categoryId) {            values.add(FieldValue.of(id));        }        Query categoryQuery = TermsQuery.of(t -> t.field("categoryId.keyword").terms(new TermsQueryField.Builder()                .value(values).build()        ))._toQuery();        try {            SearchResponse search = client.search(s -> s                            .index(indexName)                            .query(q -> q                                    .bool(b -> b                                            .must(categoryQuery                                            )                                            .should(sh -> sh     .match(t -> t             .field("content")             .query(query)     )                                            )                                    )                            )                              .highlight(h -> h                                    .fields("content", f -> f                                            .preTags("")                                            .postTags("")                                    )                            )                            .from(0)                            .size(top)                    , DocumentParagraph.class            );            for (Hit hit : search.hits().hits()) {                DocumentParagraph pd = hit.source();                documentParagraphs.add(pd);            }        } catch (IOException e) {            log.error("查询ES异常:{}", e.getMessage());            throw new ExploException(HttpCode.ES_SEARCH_ERROR, "查询ES数据失败");        }        return documentParagraphs;    }/*** 高亮数据提取*/    private DocumentParagraph highLight(Hit hit) {        DocumentParagraph paragraph = hit.source();        try {            Map highlight = hit.highlight();            List list = highlight.get("content");            String join = StringUtils.join(list, "");            if (StringUtils.isNotBlank(join)) {                paragraph.setContent(join);                paragraph.setScore(hit.score());            }        } catch (Exception e) {            log.error("获取ES高亮数据异常:{}", e.getMessage());        }        return paragraph;    }/***解析高亮数据*/ Map highlight = hit.highlight();            List list = highlight.get("content");            String join = StringUtils.join(list, "");            if (StringUtils.isNotBlank(join)) {                paragraph.setContent(join);            }

4.3.查询某个文档的数据并高亮显示关键词

参数介绍

ndexName:为索引名称

id:文档id

  public List searchDocumentByDocId(String indexName, String id) {        List documentParagraphs = Lists.newArrayList();        try {            SearchResponse search = client.search(s -> s                    .index(indexName)                    .query(q -> q                            .term(t -> t                                    .field("docId")                                    .value(id)                            )                    ), DocumentParagraph.class            );            for (Hit hit : search.hits().hits()) {                DocumentParagraph pd = hit.source();                documentParagraphs.add(pd);            }        } catch (IOException e) {            log.error("查询ES异常:{}", e.getMessage());            throw new ExploException(HttpCode.ES_SEARCH_ERROR, "查询ES数据失败");        }        return documentParagraphs;    }

4.4.查询多条件OR匹配查询

参数介绍

docNo:文档编号

docTitle:文档标题

docContext:文档内容

输入参数:query

实现查询上述字段中含有query关键词操作,

类似于: docNo like query or docTitlelike query or docContextlike query

 List list = Lists.newArrayList();        list.add(MatchQuery.of(t -> t.field("docNo").query(query).boost(1.2F))._toQuery());        list.add(MatchQuery.of(t -> t.field(" docTitle ").query(query).boost(1.5F))._toQuery());        list.add(MatchQuery.of(t -> t.field("docContext ").query(query).boost(1.8F))._toQuery());        try {            SearchResponse search = client.search(s -> s                            .index(indexName)                            .query(q -> q                                    .bool(b -> b                                            .should(list)                                    )                            )                            .from(0)                            .size(top)                    , DocumentParagraph.class            );

5.elasticsearch增删工具类

批量增删也是常见类型

5.1.批量增加数据

参数介绍

ndexName:为索引名称

objs:插入实体

     public boolean batchInsertDocument(String indexName, List objs) {        try {            List bulkOperationArrayList = new ArrayList();            for (DocumentParagraph obj : objs) {                bulkOperationArrayList.add(BulkOperation.of(o -> o.index(i -> i.document(obj))));            }            BulkResponse bulkResponse = client.bulk(b -> b.index(indexName).operations(bulkOperationArrayList));            return true;        } catch (IOException e) {            log.error("数据插入ES异常:{}", e.getMessage());            throw new ExploException(HttpCode.ES_INSERT_ERROR, "ES新增数据失败");        }    }

5.2.批量删除数据

删除文章下的所有数据

参数介绍

ndexName:为索引名称

docId:文章id

    public Boolean deleteDocument(String indexName, String docId) {        try {            client.deleteByQuery(d -> d                    .index(indexName)                    .query(q -> q                            .term(t -> t                                    .field("docId")                                    .value(docId)                            )                    )            );        } catch (IOException e) {            log.error("查询ES异常:{}", e.getMessage());        }        return true;    }

5.调用测试实现

实现索引的创建以及数据的存储查询示例

@Api(tags = {"ES操作"})@RestController@RequestMapping("/es")public class TestEsCurdCtrl {    @Autowired    public ElasticsearchHandle elasticsearchHandle;    @ApiOperation(value = "添加es文件", notes = "添加es文件")    @GetMapping(value = "/add")    public ResponseHandle deleteDocument(@RequestParam(value = "id") String id) {        DocumentPartESDto doc = DocumentPartESDto.builder()                .id(id)                .docId(id)                .content("这是文本内容" + id)                .type("doc")                .build();        elasticsearchHandle.insertDocument("doc", doc, id);        return ResponseHandle.SUCCESS("成功");    }    @ApiOperation(value = "查询es文件", notes = "查询es文件")    @GetMapping(value = "/search")    public ResponseHandle searchDocument(@RequestParam(value = "id") String id) {        GetResponse doc = elasticsearchHandle.searchDocument("doc", id);        DocumentPartESDto docDto = doc.source();        return ResponseHandle.SUCCESS(docDto);    }    @ApiOperation(value = "创建索引", notes = "创建索引")    @GetMapping(value = "/index")    public ResponseHandle createIndex(@RequestParam(value = "indexName") String indexName) {        elasticsearchHandle.createIndex(indexName);        return ResponseHandle.SUCCESS("成功");    }   /**     * 创建mapping索引     *     * @param indexName     */         public static String esmappingV2 = "{\"properties\":{\"docId\":{\"type\":\"keyword\"},\"docName\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\",\"search_analyzer\":\"ik_smart\",\"copy_to\":\"all\"},\"categoryId\":{\"type\":\"keyword\"},\"libVersionList\":{\"type\":\"keyword\"},\"content\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\",\"search_analyzer\":\"ik_smart\",\"copy_to\":\"all\"},\"title\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\",\"search_analyzer\":\"ik_smart\",\"copy_to\":\"all\"},\"all\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\",\"search_analyzer\":\"ik_smart\"}}}";    public void createIndexAndMapping(String indexName)  {        try {            JsonpMapper mapper = client._transport().jsonpMapper();            JsonParser parser = mapper.jsonProvider().createParser(new StringReader(esmappingV2));            client.indices().create(c -> c.                    index(indexName)                    .mappings(TypeMapping._DESERIALIZER.deserialize(parser, mapper))            );        } catch (Exception e) {            if (StringUtils.contains(e.getMessage(), "resource_already_exists_exception")) {                log.warn("索引存在不创建");                return;            }            log.error("es新增mapping索引异常:{}", e.getMessage());            throw new SkynetException(HttpCode.ES_INDEX_ERROR.code(), HttpCode.ES_INDEX_ERROR.message());        }    }}

总结

上一篇:光纤服务器怎么联网使用?

下一篇:真正云服务器怎么用手机?