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

这篇具有很好参考价值的文章主要介绍了SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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


章节
第一章链接: 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依赖

	  <!--   springboot 依赖     -->
	   <parent>
	       <groupId>org.springframework.boot</groupId>
	       <artifactId>spring-boot-starter-parent</artifactId>
	       <version>2.5.7</version>
	       <relativePath/>
	   </parent>
	   <!--   elasticsearch依赖     -->
       <dependency>
           <groupId>co.elastic.clients</groupId>
           <artifactId>elasticsearch-java</artifactId>
           <version>8.1.0</version>
       </dependency>
       <dependency>
           <groupId>org.glassfish</groupId>
           <artifactId>jakarta.json</artifactId>
           <version>2.0.1</version>
       </dependency>

二、springboot集成实现

1.ElasticSearchConfig配置实现

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

@Configuration
public 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<HttpHost> httpHosts = Lists.newArrayList();
        String[] split = hosts.split(",");
        for (int i = 0; i < split.length; i++) {
            httpHosts.add(HttpHost.create(split[i]));
        }
        HttpHost[] httpHosts1 = httpHosts.toArray(new HttpHost[0]);
        RestClient client = RestClient
                .builder(httpHosts1)
                .setHttpClientConfigCallback(httpAsyncClientBuilder ->
                        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
@Component
public 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<String, Property> mapping) throws IOException {
        CreateIndexResponse createIndexResponse = client.indices().create(c -> {
            c.index(indexName).mappings(mappings -> mappings.properties(mapping));
            return c;
        });
        return createIndexResponse.acknowledged();
    }

//    public Map<String, Property> buildMapping( Map<String, String> propertyKeys) {
//        Map<String, Property> documentMap = new HashMap<>();
//        for (Map.Entry<String, String> 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<String, Property> 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<DocumentPartESDto> searchDocument(String indexName, String id) {

        try {
            GetResponse<DocumentPartESDto> 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
@AllArgsConstructor
public 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<DocumentParagraph> search(String indexName, String query,int top) {
        List<DocumentParagraph> documentParagraphs = Lists.newArrayList();
        try {
            SearchResponse<DocumentParagraph> 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<DocumentParagraph> 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<DocumentParagraph> search(String indexName, String query, List<String> categoryId,int top) {
        List<DocumentParagraph> documentParagraphs = Lists.newArrayList();
        List<FieldValue> 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<DocumentParagraph> 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("<em>")
                                            .postTags("</em>")
                                    )
                            )
                            .from(0)
                            .size(top)
                    , DocumentParagraph.class
            );
            for (Hit<DocumentParagraph> 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<DocumentParagraph> hit) {
        DocumentParagraph paragraph = hit.source();
        try {
            Map<String, List<String>> highlight = hit.highlight();
            List<String> 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<String, List<String>> highlight = hit.highlight();
            List<String> list = highlight.get("content");
            String join = StringUtils.join(list, "");
            if (StringUtils.isNotBlank(join)) {
                paragraph.setContent(join);
            }

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

参数介绍
ndexName:为索引名称
id:文档id

  public List<DocumentParagraph> searchDocumentByDocId(String indexName, String id) {
        List<DocumentParagraph> documentParagraphs = Lists.newArrayList();
        try {
            SearchResponse<DocumentParagraph> search = client.search(s -> s
                    .index(indexName)
                    .query(q -> q
                            .term(t -> t
                                    .field("docId")
                                    .value(id)
                            )
                    ), DocumentParagraph.class
            );
            for (Hit<DocumentParagraph> 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<Query> 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<DocumentParagraph> 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<DocumentParagraph> objs) {
        try {
            List<BulkOperation> 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<DocumentPartESDto> 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());
        }
    }
}

总结

以上就是SpringBoot集成Elasticsearch数据库内容,项目已经经过测试,主要类全部都在上面。大家可以参考文章来源地址https://www.toymoban.com/news/detail-563376.html

到了这里,关于SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch8.x版本Java客户端Elasticsearch Java API Client中常用API练习

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

    2024年04月11日
    浏览(36)
  • java(springboot)对接elasticsearch8+

    注:jackson包es只用到了databind,之所以全部引用是因为actuator用到了其他,只升级一个会 导致版本冲突 注:因为没有用springboot自身的es插件所以健康检查检测不到es状态,关闭es检测 上边创建索引是定制的加了特殊mapping,正常这样

    2024年02月16日
    浏览(33)
  • java-springboot整合ElasticSearch8.2复杂查询

    近期有大数据项目需要用到es,而又是比较新的es版本,网上也很少有8.x的java整合教程,所有写下来供各位参考。 首先 1.导包: 2.客户端连接代码EsUtilConfigClint: 一开始按照其他博主的方法,长时间连接不操作查询再次调用查询时会报错timeout,所以要设置RequestConfigCallback 3

    2024年02月11日
    浏览(43)
  • Elasticsearch8常用查询api,java ElasticsearchClient写法和原生Rest DSL写法

    Java Client Rest Api Java Client Rest Api Java Client Rest Api Java Client Rest Api ? 用来匹配任意字符, * 用来匹配零个或者多个字符。 Java Client Rest Api Java Client Rest Api Java Client Java Client Rest Api

    2024年02月08日
    浏览(45)
  • 最新版ES8的client API操作 Elasticsearch Java API client 8.0

    作者:ChenZhen 本人不常看网站消息,有问题通过下面的方式联系: 邮箱:1583296383@qq.com vx: ChenZhen_7 我的个人博客地址:https://www.chenzhen.space/🌐 版权:本文为博主的原创文章,本文版权归作者所有,转载请附上原文出处链接及本声明。📝 如果对你有帮助,请给一个小小的s

    2024年02月04日
    浏览(34)
  • ElasticSearch8 - SpringBoot整合ElasticSearch

    springboot 整合 ES 有两种方案,ES 官方提供的 Elasticsearch Java API Client 和 spring 提供的 [Spring Data Elasticsearch](Spring Data Elasticsearch) 两种方案各有优劣 Spring:高度封装,用着舒服。缺点是更新不及时,有可能无法使用 ES 的新 API ES 官方:更新及时,灵活,缺点是太灵活了,基本是一

    2024年03月25日
    浏览(85)
  • 【搜索引擎2】实现API方式调用ElasticSearch8接口

    1、理解ElasticSearch各名词含义 ElasticSearch对比Mysql Mysql数据库 Elastic Search Database 7.X版本前有Type,对比数据库中的表,新版取消了 Table Index Row Document Column mapping Elasticsearch是使用Java开发的,8.1版本的ES需要JDK17及以上版本;es默认带有JDK,如果安装es环境为java8,则会默认使用自带

    2024年04月17日
    浏览(30)
  • SpringBoot连接ElasticSearch8.*

    系统中需要使用到ElasticSearch进行内容检索,因此需要搭建SpringBoot + ElasticSearch的环境。

    2024年02月16日
    浏览(35)
  • springboot整合elasticsearch8

    1.引入maven依赖 2.application.yml添加配置 3.编写config文件 启动demo项目,通过控制台日志查看是否能够正常连接es。 4.在DemoApplicationTests编写简单测试操作es。

    2024年02月12日
    浏览(39)
  • es Elasticsearch 六 java api spirngboot 集成es

    目录 Java restApi Springboot 集成es 新增-同步 新增-异步 增删改查流程 _bulk 批量操作 新增-同步 新增-异步 增删改查流程 创建请求、2.执行、3.查看返回结果     _bulk 批量操作 ok 持续更新

    2024年02月10日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包