ElasticSearch 详解(四)

发布于 2021-10-23  96 次阅读


整合 SpringBoot 框架

添加依赖

新建 SpringBoot 项目,导入 Spring Boot DevTools、Lombok、Spring Configuration Processor、SpringWeb 和 Spring Data ElasticSearch 依赖。最后再手动添加 fastjson 依赖。

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>

ES 配置类

package ml.guest997.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
    }
}

实体类

package ml.guest997.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
    private String name;
    private int age;
}

索引操作

创建索引

package ml.guest997;

import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;

@SpringBootTest
class SpringbootEsApplicationTests {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Test
    void createIndex() throws IOException {
        //创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("guest997");
        //客户端执行请求,请求后获得响应。
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(createIndexResponse);
    }

}
ElasticSearch 详解(四)插图

判断索引是否存在

@Test
void existsIndex() throws IOException {
    //获取索引请求
    GetIndexRequest request = new GetIndexRequest("guest997");
    //客户端执行请求,请求后获得响应。
    boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
    System.out.println(exists);
}
//结果为 true

删除索引

@Test
void deleteIndex() throws IOException {
    //删除索引请求
    DeleteIndexRequest request = new DeleteIndexRequest("guest997");
    //客户端执行请求,请求后获得响应。
    AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
    System.out.println(delete.isAcknowledged());
}
//结果为 true

文档操作

创建文档

@Test
void addDocument() throws IOException {
    User user = new User("guest997", 18);
    IndexRequest indexRequest = new IndexRequest("guest997_index");
    //PUT /guest997_index/_doc/1
    indexRequest.id("1");
    indexRequest.timeout(TimeValue.timeValueSeconds(1));
    indexRequest.timeout("1s");
    //将数据放入请求
    indexRequest.source(JSON.toJSONString(user), XContentType.JSON);
    //客户端执行请求,请求后获得响应。
    IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    //打印响应信息
    System.out.println(indexResponse.toString());
    System.out.println(indexResponse.status());
}
/*结果为
IndexResponse[index=guest997_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
CREATED
*/

判断文档是否存在

@Test
void existsDocument() throws IOException {
    //GET /guest997_index/_doc/1
    GetRequest getRequest = new GetRequest("guest997_index", "1");
    //关闭检索_source 和存储的字段,只需要判断是否存在,这样就提高了效率。
    getRequest.fetchSourceContext(new FetchSourceContext(false));
    getRequest.storedFields("_none_");
    boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
    System.out.println(exists);
}
//结果为 true

获取文档

@Test
void getDocument() throws IOException {
    GetRequest getRequest = new GetRequest("guest997_index", "1");
    GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
    System.out.println(getResponse.getSourceAsString());
}
//结果为 {"age":18,"name":"guest997"}

更新文档

@Test
void updateRequest() throws IOException {
    //POST /guest997_index/_doc/1/_update
    UpdateRequest updateRequest = new UpdateRequest("guest997_index", "1");
    updateRequest.timeout("1s");
    User user = new User("guest997", 66);
    //将数据放入 doc 中,跟之前是一样的。
    updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
    UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
    System.out.println(updateResponse.status());
}
//结果为 OK

删除文档

@Test
void deleteRequest() throws IOException {
    //DELETE /guest997_index/_doc/1
    DeleteRequest deleteRequest = new DeleteRequest("guest997_index", "1");
    deleteRequest.timeout("1s");
    DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
    System.out.println(deleteResponse.status());
}
//结果为 OK

批量插入数据

@Test
void testBulkRequest() throws IOException {
    BulkRequest bulkRequest = new BulkRequest();
    bulkRequest.timeout("10s");
    List<User> userList = new ArrayList<>();
    userList.add(new User("guest99701", 18));
    userList.add(new User("guest99702", 19));
    userList.add(new User("guest99703", 20));
    userList.add(new User("guest99704", 21));
    userList.add(new User("guest99705", 22));
    //批量处理数据
    for (int i = 0; i < userList.size(); i++) {
        //批量删除或修改也是能够在这实现的
        bulkRequest.add(new IndexRequest("guest997_index")
                .id("" + (i + 1))
                .source(JSON.toJSONString(userList.get(i)), XContentType.JSON)
        );
    }
    BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    System.out.println(bulk.hasFailures());     //是否执行失败
}
//结果为 false

复杂查询

@Test
void testSearch() throws IOException {
    SearchRequest searchRequest = new SearchRequest("guest997_index");
    //查询条件可以使用 SearchSourceBuilder 来实现
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    //精确匹配
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "guest99701");
    //将 TermQueryBuilder 传给 SearchSourceBuilder,其它类似的还有 HighlightBuilder 和 MatchAllQueryBuilder 等,都是之前进行操作的命令。 
    sourceBuilder.query(termQueryBuilder);
    sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
    //将数据放入请求
    searchRequest.source(sourceBuilder);
    //客户端执行请求,请求后获得响应。
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    System.out.println(JSON.toJSONString(searchResponse));
    for (SearchHit hit : searchResponse.getHits()) {
        System.out.println(hit.getSourceAsMap());
    }
}
/*结果为
{"clusters":{"fragment":true,"skipped":0,"successful":0,"total":0},"failedShards":0,"fragment":false,"hits":{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"guest99701","age":18},"sourceAsString":"{\"age\":18,\"name\":\"guest99701\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}},"internalResponse":{"fragment":true,"numReducePhases":1},"numReducePhases":1,"profileResults":{},"shardFailures":[],"skippedShards":0,"successfulShards":1,"timedOut":false,"took":{"days":0,"daysFrac":6.944444444444444E-8,"hours":0,"hoursFrac":1.6666666666666667E-6,"micros":6000,"microsFrac":6000.0,"millis":6,"millisFrac":6.0,"minutes":0,"minutesFrac":1.0E-4,"nanos":6000000,"seconds":0,"secondsFrac":0.006,"stringRep":"6ms"},"totalShards":1}
{name=guest99701, age=18}
*/