springboot整合ES及其基本使用

Liang2003發表於2024-11-15

Springboot整合ElasticSearch

匯入依賴

        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>

注意一定要顯示指定ES版本,因為Springboot自帶ES的版本,而版本不匹配會引來其他問題

配置

在application.yml

elasticsearch:
  clusterName: es
  hosts: ES地址:9200
  scheme: http
  connectTimeOut: 1000 
  socketTimeOut: 30000
  connectionRequestTimeOut: 1000
  maxConnectNum: 100
  maxConnectNumPerRoute: 100
  # 有username和password就弄上去 

配置類

/**
 * restHighLevelClient 客戶端配置類
 */
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticsearchConfig {

    // es host ip 地址(叢集)
    private String hosts;
    // es使用者名稱
//    private String userName;
    // es密碼
//    private String password;
    // es 請求方式
    private String scheme;
    // es叢集名稱
    private String clusterName;
    // es 連線超時時間
    private int connectTimeOut;
    // es socket 連線超時時間
    private int socketTimeOut;
    // es 請求超時時間
    private int connectionRequestTimeOut;
    // es 最大連線數
    private int maxConnectNum;
    // es 每個路由的最大連線數
    private int maxConnectNumPerRoute;


    /**
     * 如果@Bean沒有指定bean的名稱,那麼這個bean的名稱就是方法名
     */
    @Bean(name = "restHighLevelClient")
    public RestHighLevelClient restHighLevelClient() {


        // 此處為單節點es
        HttpHost httpHost = HttpHost.create(hosts);
        // 構建連線物件
        RestClientBuilder builder = RestClient.builder(httpHost);

        // 設定使用者名稱、密碼
        //CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        //credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(userName,password));

        // 連線延時配置
        builder.setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setConnectTimeout(connectTimeOut);
            requestConfigBuilder.setSocketTimeout(socketTimeOut);
            requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
            return requestConfigBuilder;
        });
        // 連線數配置
        builder.setHttpClientConfigCallback(httpClientBuilder -> {
            httpClientBuilder.setMaxConnTotal(maxConnectNum);
            httpClientBuilder.setMaxConnPerRoute(maxConnectNumPerRoute);
//            httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            return httpClientBuilder;
        });

        return new RestHighLevelClient(builder);
    }
}

操作

透過RestHighLevelClient 類來操作,有個indices方法,可以執行建立索引庫,文件的增刪改查。

工具類

@Component
public class ESClient {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    /**
     * 建立索引庫
     * @param index 索引名
     * @param settings 設定的分片,備份分片數量
     * @param mappings 索引庫的結構
     */
    public boolean createIndex(String index, Settings.Builder settings, XContentBuilder mappings) throws IOException {

        CreateIndexRequest request = new CreateIndexRequest(index)
                .settings(settings)
                .mapping(mappings);

        return restHighLevelClient.indices().create(request, RequestOptions.DEFAULT).isAcknowledged();
    }

    /**
     * 建立索引
     * @param index
     * @param jsonMapping 索引庫結構
     * @return
     * @throws IOException
     */
    public CreateIndexResponse createIndex(String index, String jsonMapping) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(index);
        request.source(jsonMapping, XContentType.JSON);
        return restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
    }

    /**
     * 刪除索引庫
     * @param index 索引庫名
     */
    public boolean deleteIndex(String index) throws IOException {
        DeleteIndexRequest deleteRequest = new DeleteIndexRequest(index);
        AcknowledgedResponse response = restHighLevelClient.indices().delete(deleteRequest, RequestOptions.DEFAULT);
        return response.isAcknowledged();
    }


    /**
     * 建立文件 指定id
     * @param index 索引
     * @param id 文件id
     * @param jsonString 文件內容
     */
    public IndexResponse createDocument(String index, String id, String jsonString) throws IOException {
        IndexRequest request = new IndexRequest(index)
                .id(id)
                .source(jsonString, XContentType.JSON);
        return restHighLevelClient.index(request, RequestOptions.DEFAULT);
    }

    /**
     * 建立文件
     * @param index 索引
     * @param jsonString 文件內容
     */
    public IndexResponse createDocument(String index, String jsonString) throws IOException {
        IndexRequest request = new IndexRequest(index)
                .source(jsonString,XContentType.JSON);
        return restHighLevelClient.index(request, RequestOptions.DEFAULT);
    }

    /**
     * 獲取文件
     * @param index 索引庫
     * @param id 文件id
     */
    public String getDocument(String index, String id) throws IOException {
        GetRequest request = new GetRequest(index, id);
        return restHighLevelClient.get(request, RequestOptions.DEFAULT).getSourceAsString();
    }


    /**
     * 刪除文件
     * @param index 索引庫名
     * @param id 文件id
     */
    public boolean deleteDocument(String index, String id) throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(index, id);
        DocWriteResponse.Result result = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT).getResult();

        return result == DocWriteResponse.Result.DELETED;
    }

    /**
     * 更新文件
     * @param index 索引庫名稱
     * @param id 文件id
     * @param jsonString 更新的內容
     */
    public UpdateResponse updateDocument(String index, String id, String jsonString) throws IOException {
        UpdateRequest request = new UpdateRequest(index, id)
                .doc(jsonString, XContentType.JSON);
        return restHighLevelClient.update(request, RequestOptions.DEFAULT);
    }

    /**
     * 查詢文件
     * @param index 索引庫
     * @param query 查詢條件
     */
    public SearchResponse searchDocuments(String index, SearchSourceBuilder query) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        searchRequest.source(query);
        return restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    }

    /**
     * 批次插入,
     * @param index    索引庫名
     * @param dataList <id,data>文件列表
     * @return
     */
    //批次插入
    public <T> BulkResponse bulkCreateDocument(String index, List<Pair<String,T>> dataList) throws IOException {
        BulkRequest request = new BulkRequest();
        for(Pair<String, T> pair : dataList){
            request.add(new IndexRequest(index)
                    .id(pair.getKey())
                    .source(JSON.toJSONString(pair.getValue()), XContentType.JSON));
        }
        return restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
    }

    /**
     * 批次刪除
     * @param index  索引庫名
     * @param idList 需要刪除的文件id
     * @return
     */
    public BulkResponse bulkDeleteDocument(String index, List<String> idList) throws IOException {
        BulkRequest request = new BulkRequest();
        for(String id : idList){
            request.add(new DeleteRequest(index, id));
        }
        return restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
    }


}

使用


@SpringBootTest
public class EsTest {

    @Autowired
    private ESClient client;

    @Test
    public void createIndex() throws IOException {

        Settings.Builder settings = Settings.builder()
                .put("number_of_shards", 5) //分片數量
                .put("number_of_replicas", 1); //備份分片數量

        //構造mappings
        XContentBuilder mappings = JsonXContent.contentBuilder()
                .startObject() //這個相當於{
                    .startObject("properties") //當屬性名相當於 properties:{
                        .startObject("id")
                        .field("type", "long")
                        .endObject()
                        .startObject("title")
                        .field("type", "text")
                        .field("analyzer", "ik_max_word")
                        .endObject()
                        .startObject("price")
                        .field("type", "integer")
                        .endObject()
                    .endObject()
                .endObject(); //這個相當於}
        System.out.println(mappings);
        boolean success = client.createIndex("goods", settings, mappings);
        System.out.println(success);
    }

    @Test
    public void deleteIndex() throws IOException {
        boolean success = client.deleteIndex("goods");
        System.out.println(success);
    }


    @Test
    public void createDocument() throws IOException {

        for(int i=1;i<=10;i++){
            Goods goods = new Goods((long) i,"goods_"+i,20.0);
            client.createDocument("goods",goods.getId().toString(), JSON.toJSONString(goods));
        }
    }

    @Test
    public void getDocument() throws IOException {
        String source = client.getDocument("goods", "2");
        System.out.println(source);
    }

    @Test
    public void updateDocument() throws IOException {
        Goods goods = new Goods(1L, "goods_3", 30.0);
        IndexResponse response = client.createDocument("goods", "3", JSON.toJSONString(goods));
    }


    @Test
    public void deleteDocument() throws IOException {
        boolean success = client.deleteDocument("goods", "3");
        System.out.println(success);
    }


    @Test
    public void queryDocument() throws IOException {

        //SearchSourceBuilder構造搜尋條件
        SearchSourceBuilder queryBuilder = new SearchSourceBuilder();
        queryBuilder.query(QueryBuilders.termQuery("price", 20.0));

        SearchResponse response = client.searchDocuments("goods", queryBuilder);
        //返回的response有hit陣列,而每個hit中的source才是我們關心的資料
        response.getHits().forEach(hit -> System.out.println(hit.getSourceAsMap()));

    }


    @Test
    public void getAllDocument() throws IOException {
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        SearchResponse response = client.searchDocuments("goods", builder);
        response.getHits().forEach(hit -> System.out.println(hit.getSourceAsMap()));
    }

    @Test
    public void bulkCreateDocument() throws IOException {
        List<Pair<String,Goods>> list = new ArrayList<>();
        for(int i=11;i<=20;i++){
            Goods goods = new Goods((long) i, "goods_"+i, i*10.0);
            list.add(new Pair<>(String.valueOf(i),goods));
        }
        client.bulkCreateDocument("goods",list);
    }

    @Test
    public void bulkDeleteDocument() throws IOException {
        List<String> ids = new ArrayList<>();
        for(int i=11;i<=20;i++){
            ids.add(String.valueOf(i));
        }
        client.bulkDeleteDocument("goods", ids);
    }


}

相關文章