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

2,674 阅读5分钟

前言

目前正在出一个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⭐️)

往期并发编程内容推荐

博客(阅读体验较佳)

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

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