前语

现在正在出一个Es专题系列教程, 篇幅会较多, 喜爱的话,给个重视❤️ ~

本节来给咱们讲一下在Springboot运用es进行文档操作~

本文偏实战一些,好了, 废话不多说直接开整吧~

文档操作

本节继续运用上节的项目,在api下新建DocApi类,为了便利演示,咱们运用之前建好的索引req_log

新增 & json

新增也很简单,下面是一个json方法新增的比如:

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { EsStudyApplication.class })
public class DocApi {
    /**
     * es 索引
     */
    public static final String index = "req_log";
    @Autowired
    private RestHighLevelClient client;
    /**
     * 新增 json方法
     * @throws IOException
     */
    @Test
    public void add() throws IOException {
        IndexRequest request = new IndexRequest(index);
        // 指定id
        request.id("1");
        String jsonString = "{" +
                "\"method\":\"POST\"," +
                "\"times\":\"60\"," +
                "\"path\":\"/api/post/1/update\"," +
                "\"created\":\"2023-02-28\"" +
                "}";
        request.source(jsonString, XContentType.JSON);
        // 可选项
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");
        client.index(request, RequestOptions.DEFAULT);
    }
}

那么怎么检查咱们新增的数据呢?除了之前给咱们讲的在kibana控制台运用查询句子之外,还有什么方法呢?下面教咱们一个更便利的方法,利用kibana的索引形式管理,能够很便利的检查和统计数据

  • 首先翻开设置页面

  • 点击索引形式管理

  • 创建索引形式

  • 然后到explore进行检查

咱们能够看到刚刚新增的数据现已被展示出来了

新增 & Map

  /**
     * 新增 map方法
     * @throws IOException
     */
    @Test
    public void add1() throws IOException {
        IndexRequest request = new IndexRequest(index);
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("method", "POST");
        jsonMap.put("times", "40");
        jsonMap.put("path", "/api/post/2/update");
        jsonMap.put("created", "2023-02-28");
        request.id("2").source(jsonMap);
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");
        client.index(request, RequestOptions.DEFAULT);
    }

新增 & Builder

  /**
     * 新增 builder
     * @throws IOException
     */
    @Test
    public void add2() throws IOException {
        IndexRequest request = new IndexRequest(index);
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.field("method", "POST");
            builder.field("times", "90");
            builder.field("path", "/api/post/3/update");
            builder.timeField("created", "2023-02-28");
        }
        builder.endObject();
        request.id("3").source(builder);
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");
        client.index(request, RequestOptions.DEFAULT);
    }

更新

更新与新增相似,唯一的差异在于request不同,这里只演示一个json方法的更新

 /**
     * 更新 json方法
     * 其它方法与新增相似 只不过request不一样
     * @throws IOException
     */
    @Test
    public void update() throws IOException {
        UpdateRequest request = new UpdateRequest(index, "1");
        String jsonString = "{" +
                "\"method\":\"POST\"," +
                "\"times\":\"60\"," +
                "\"path\":\"/api/post/1/update1\"," +
                "\"created\":\"2023-02-28\"" +
                "}";
        request.doc(jsonString, XContentType.JSON);
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");
        client.update(request, RequestOptions.DEFAULT);
    }

删去

删去更新简单,下面看一个比如:

 /**
     * 删去操作
     * @throws IOException
     */
    @Test
    public void delete() throws IOException {
        DeleteRequest request = new DeleteRequest(index, "1");
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");
        client.delete(request, RequestOptions.DEFAULT);
    }

查询 & 根据id

下面给咱们看一个查询的比如,这个比如比较简单,根据doc_id来查询,查询它是一个比较复杂的操作,所以本节不过多深入,下节给咱们讲,本节带咱们快速体会一下

 /**
     * 查询
     * @throws IOException
     */
    @Test
    public void fetch() throws IOException {
        GetRequest request = new GetRequest(index, "1");
        try {
            // 默认下 get 是同步履行
            GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
            // 获取索引称号
            String index = getResponse.getIndex();
            log.info("index >>>> {}", index); 
            // index >>>> req_log
            if(getResponse.isExists()) {
                // 获取version
                long version = getResponse.getVersion();
                log.info("version >>>> {}", version);
                 // version >>>> 4
                // 获取文档数据
                String sourceAsString = getResponse.getSourceAsString();
                log.info("sourceAsString >>>> {}", sourceAsString); 
                // sourceAsString >>>> {"path":"/api/post/1/update1","times":"60","method":"POST","created":"2023-02-28"}
                // map结构的文档
                Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
                log.info("sourceAsMap >>>> {}", sourceAsMap); 
                // {path=/api/post/1/update1, times=60, method=POST, created=2023-02-28}
                // byte[]格局
                byte[] sourceAsBytes = getResponse.getSourceAsBytes();
            }else {
                log.error("response is not exists");
            }
        } catch (ElasticsearchException e) {
            // 404 状况码处理
            if (e.status() == RestStatus.NOT_FOUND) {
                log.error(e.getMessage());
            }
        }
    }

查询还有一些可选项:

// request的一些可选参数:
// 禁用源检索,默认启用
request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
// 装备特定字段的源包含
String[] includes = new String[]{"method", "path"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext =
        new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
// 装备特定字段的源排除 互换一下
//        String[] includes = Strings.EMPTY_ARRAY;
//        String[] excludes = new String[]{"method", "path"};
// 在检索文档之前履行改写 默认 false
request.refresh(true);
// 版别
request.version(2);

查询 & Async

有时候咱们有异步获取的场景,怎么去做呢?下面看一个比如

 /**
     * 查询
     * @throws IOException
     */
    @Test
    public void fetchAsync() throws IOException {
        GetRequest request = new GetRequest(index, "1");
        // 异步履行
        client.getAsync(request, RequestOptions.DEFAULT, listener);
        // 阻塞一下线程
        for(;;){}
    }

监听listener:

 /**
     * 监听异步响应
     */
    ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
        @Override
        public void onResponse(GetResponse getResponse) {
            log.info("异步回调>>>>");
            // 获取索引称号
            String index = getResponse.getIndex();
            log.info("index >>>> {}", index); // index >>>> req_log
        }
        @Override
        public void onFailure(Exception e) {
            log.error(e.getMessage());
        }
    };

批量恳求 & bulk

这个跟咱们之前讲api相似,下面看个比如会更明白点:

  /**
     * 批量恳求
     * @throws IOException
     */
    @Test
    public void bulk() throws IOException {
        BulkRequest request = new BulkRequest();
        // 新增
        String jsonString = "{" +
                "\"method\":\"POST\"," +
                "\"times\":\"60\"," +
                "\"path\":\"/api/post/5/update\"," +
                "\"created\":\"2023-02-28\"" +
                "}";
        request.add(new IndexRequest(index).source(jsonString, XContentType.JSON));
        String jsonString1 = "{" +
                "\"method\":\"POST\"," +
                "\"times\":\"60\"," +
                "\"path\":\"/api/post/6/update\"," +
                "\"created\":\"2023-02-28\"" +
                "}";
        request.add(new IndexRequest(index).source(jsonString1, XContentType.JSON));
        // 删去
        request.add(new DeleteRequest(index, "3"));
        // 更新
        String jsonString2 = "{" +
                "\"method\":\"POST\"," +
                "\"times\":\"60\"," +
                "\"path\":\"/api/post/1/update1\"," +
                "\"created\":\"2023-02-28\"" +
                "}";
        request.add(new UpdateRequest(index, "1").doc(jsonString2, XContentType.JSON));
        client.bulk(request, RequestOptions.DEFAULT);
    }

在这个比如中,进行了增修改的操作,十分合适批量操作

结束语

下节带咱们看下怎么进行高级查询~

本着把自己知道的都告知咱们,如果本文对您有所协助,点赞+重视鼓励一下呗~

相关文章

  • 利用docker搭建es集群

  • 一起来学ElasticSearch(一)

  • 一起来学ElasticSearch(二)

  • 一起来学ElasticSearch(三)

  • 一起来学ElasticSearch(四)

  • 一起来学ElasticSearch(五)

  • 一起来学ElasticSearch(六)

  • 一起来学ElasticSearch(七)

  • 一起来学ElasticSearch(八)

  • 一起来学ElasticSearch(九)

  • 一起来学ElasticSearch(十)

  • 一起来学ElasticSearch之整合SpringBoot(一)

项目源码(源码已更新 欢迎star⭐️)

  • springboot-es-all: https://github.com/qiuChengleiy/springboot-es-all

往期并发编程内容引荐

  • Java多线程专题之线程与进程概述
  • Java多线程专题之线程类和接口入门
  • Java多线程专题之进阶学习Thread(含源码剖析)
  • Java多线程专题之Callable、Future与FutureTask(含源码剖析)
  • 面试官: 有了解过线程组和线程优先级吗
  • 面试官: 说一下线程的生命周期进程
  • 面试官: 说一下线程间的通讯
  • 面试官: 说一下Java的同享内存模型
  • 面试官: 有了解过指令重排吗,什么是happens-before
  • 面试官: 有了解过volatile关键字吗 说说看
  • 面试官: 有了解过Synchronized吗 说说看
  • Java多线程专题之Lock锁的运用
  • 面试官: 有了解过ReentrantLock的底层实现吗?说说看
  • 面试官: 有了解过CAS和原子操作吗?说说看
  • Java多线程专题之线程池的基本运用
  • 面试官: 有了解过线程池的工作原理吗?说说看
  • 面试官: 线程池是怎么做到线程复用的?有了解过吗,说说看
  • 面试官: 阻塞行列有了解过吗?说说看
  • 面试官: 阻塞行列的底层实现有了解过吗? 说说看
  • 面试官: 同步容器和并发容器有用过吗? 说说看
  • 面试官: CopyOnWrite容器有了解过吗? 说说看
  • 面试官: Semaphore在项目中有运用过吗?说说看(源码剖析)
  • 面试官: Exchanger在项目中有运用过吗?说说看(源码剖析)
  • 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
  • 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
  • 面试官: Phaser有了解过吗?说说看
  • 面试官: Fork/Join 有了解过吗?说说看(含源码剖析)
  • 面试官: Stream并行流有了解过吗?说说看

博客(阅览体会较佳)

  • 我的博客(阅览体会较佳)

  • 地址: github.com/qiuChenglei…

引荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

  • springboot-all

  • 地址: github.com/qiuChenglei…

  • SpringBoot系列教程合集

  • 一起来学SpringCloud合集

项目源码(源码已更新 欢迎star⭐️)

  • spring-cloud-all

  • SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 实现授权码形式的服务认证(一)

  • SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 实现授权码形式的服务认证(二)