前言
目前正在出一个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);
}
在这个例子中,进行了增删改的操作,非常适合批量操作
结束语
下节带大家看下如何进行高级查询~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
项目源码(源码已更新 欢迎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并行流有了解过吗?说说看