前言
目前正在出一个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⭐️)
往期并发编程内容推荐
- 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并行流有了解过吗?说说看
博客(阅读体验较佳)
推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)
项目源码(源码已更新 欢迎star⭐️)
- spring-cloud-all
- SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 实现授权码模式的服务认证(一)
- SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 实现授权码模式的服务认证(二)