设为首页 加入收藏

TOP

java与es8实战之六:用JSON创建请求对象(比builder pattern更加直观简洁)(一)
2023-09-09 10:25:59 】 浏览:105
Tags:java es8 JSON builder pattern 加直观 简洁

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本文是《java与es8实战》系列的第六篇,经过前面的实战,咱们初步掌握了一些Java对ES的基本操作,通过发送请求对象(例如CreateIndexResponse)到ES服务端,达到操作ES的目的,但是细心的您可能发现了:请求对象可能很复杂,例如多层对象嵌套,那么用代码来创建这些请求对象也必然不会容易
  • 今天的文章,咱们先来体验用代码创建请求对象的不便之处,再尝试ES官方给我们提供的解决之道:用JSON创建请求对象
  • 接下来,咱们从一个假设的任务开始

任务安排

  • 现在咱们要创建一个索引,此索引记录的是商品信息
  1. 有一个副本(属于setting部分)
  2. 共三个分片(属于setting部分)
  3. 共三个字段:商品名称name(keyword),商品描述description(text),价格price(integer)(属于mapping部分)
  4. name字段值长为256,超出此长度的字段将不会被索引,但是会存储
  • 接下来,咱们在kibana上用JSON创建索引,再写代码创建相同索引,然后对比两种方式的复杂程度

kibana上创建索引

  • 如果在kibana上用json来创建,请求内容如下,索引名是product001
PUT product001
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword",
        "ignore_above": 256
      },
      "description": {
        "type": "text"
      },
      "price": {
        "type": "integer"
      }
    }
  }
}
  • 效果如下,符合预期
image-20220625110440090
  • 通过eshead观察,也是符合预期
image-20220625110708346
  • 可见基于JSON的操作简单明了,接下来看看创建相通索引的代码是什么样子

基于代码创建

  • 关于如何连接ES的代码并非本篇重点,而且前面的文章已有详细说明,就不多赘述了
  • 首先创建一个API,可以接受外部传来的Setting和Mapping设定,然后用这些设定来创建索引
    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @Override
    public void create(String name,
                       Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
                       Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn) throws IOException {
        elasticsearchClient
                .indices()
                .create(c -> c
                        .index(name)
                        .settings(settingFn)
                        .mappings(mappingFn)
                );
    }
  • 然后就是如何准备Setting和Mapping参数,再调用create方法完成创建,为了让代码顺利执行,我将调用create方法的代码写在单元测试类中,这样后面只需要执行单元测试即可调用create方法
@SpringBootTest
class EsServiceImplTest {

    @Autowired
    EsService esService;

    @Test
    void create() throws Exception {
        // 索引名
        String indexName = "product002";

        // 构建setting时,builder用到的lambda
        Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn = sBuilder -> sBuilder
                .index(iBuilder -> iBuilder
                        // 三个分片
                        .numberOfShards("3")
                        // 一个副本
                        .numberOfReplicas("1")
                );

        // 新的索引有三个字段,每个字段都有自己的property,这里依次创建
        Property keywordProperty = Property.of(pBuilder -> pBuilder.keyword(kBuilder -> kBuilder.ignoreAbove(256)));
        Property textProperty = Property.of(pBuilder -> pBuilder.text(tBuilder -> tBuilder));
        Property integerProperty = Property.of(pBuilder -> pBuilder.integer(iBuilder -> iBuilder));

        // // 构建mapping时,builder用到的lambda
        Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn = mBuilder -> mBuilder
                .properties("name", keywordProperty)
                .properties("description", textProperty)
                .properties("price", integerProperty);

        // 创建索引,并且指定了setting和mapping
        esService.create(indexName, settingFn, mappingFn);

    }
}
  • 由于Java API Client中所有对象都统一使用builder pattern的方式创建,这导致代码量略多,例如setting部分,除了setting自身要用Lambda表达式,设置分片和副本的代码也要用Lambda的形式传入,这种嵌套效果在编码中看起来还是有点绕的,阅读起来可能会有点不适应
  • 执行单元测试,如下图,未发生异常
image-20220625114226165
  • 用kibana查看新建的索引

image-20220625114553023

  • 最后,将product001和product002的mapping放在一起对比,可见一模一样
image-20220625114939286
  • 再用eshead对比分片和副本的效果,也是一模一样
image-20220625115042349

小结和感慨

  • 至此,可以得出结论:
  1. Java
首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java NIO 图解 Netty 服务端启动.. 下一篇18 个一线工作的常用 Shell 脚本..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目