1. 程式人生 > 實用技巧 >ElasticSearch入門(整合SpringBoot)

ElasticSearch入門(整合SpringBoot)

ElasticSearch入門

學習自 @狂神說java 的B站教程,以下為自身實踐文件 如需瞭解更多可以去看他視訊 @狂神說java

1.概述

Elasticsearch是一個基於Lucene(java)的搜尋伺服器。它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面,區別於solr的webservice。

2.安裝、啟動

jdk1.8(最低)、ElasticSearch客戶端、介面工具(Kibana)

2.1 ES客戶端

官網地址 https://www.elastic.co/cn/downloads/

  • windows下 解壓即可使用
  • 啟動 elasticsearch-7.7.0\bin\elasticsearch.bat 訪問地址 localhost:9200
#跨域配置  elasticsearch-7.7.0\config\elasticsearch.yml  增加如下程式碼
http.cors.enabled: true
http.cors.allow-origin: "*"

2.2 ES視覺化工具 ES Head

官網地址 https://github.com/mobz/elasticsearch-head

#啟動需要nodejs環境 啟動命令   	訪問地址  localhost:9100
cd D:\sde\elasticsearch\elasticsearch-head-master
npm install
npm run start

2.3 ES視覺化工具 Kibana

官網地址 https://www.elastic.co/cn/downloads/

  • windows下 解壓即可使用
  • 啟動 kibana-7.7.1-windows-x86_64\bin 訪問地址 localhost:5601
#漢化 kibana-7.7.1-windows-x86_64\config\kibana.yml   增加如下程式碼
i18n.locale: "zh-CN"

3. IK分詞器

官網地址 https://github.com/medcl/elasticsearch-analysis-ik/releases

  • 解壓到 D:\sde\elasticsearch\elasticsearch-7.7.0\plugins\analysis-ik 目錄沒有新建analysis-ik 目錄名稱不重要,隨意起

  • 檢查是否載入分詞器

cd D:\sde\elasticsearch\elasticsearch-7.7.0\bin
elasticsearch-plugin list
  • 演算法 ik_smart(最少切分) ik_max_word(最細粒度切分) 及用kibana校驗 預設keywork standard
GET _analyze
{
  "analyzer": "ik_max_word",
  "text": ["美國民主黨"]
}
GET _analyze
{
"analyzer": "ik_smart",
"text": ["美國民主黨"]
}
  • 擴充字典(人名、網路流行語)
<!--elasticsearch-7.7.0\plugins\analysis-ik\config\IKAnalyzer.cfg.xml   可定義自己的字典檔案.dic 字尾-->
<entry key="ext_dict">xxx.dic</entry>

4. Kibana 基本語法 API

method url desc
PUT localhost:9200/索引名稱/型別名稱/文件id 建立文件(指定文件id)
POST localhost:9200/索引名稱/型別名稱 建立文件(隨機id)
POST localhost:9200/索引名稱/_update/文件id 修改文件
DELETE localhost:9200/索引名稱/型別名稱/文件id 刪除文件 by id
GET localhost:9200/索引名稱/型別名稱/文件id 查詢文件 by id
POST localhost:9200/索引名稱/_search 查詢所有文件

4.1 新建

#建立空庫
PUT /test2
{
    
}
#建立索引 及 規定欄位型別
PUT /test3
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text"
      },
      "age":{
        "type": "integer"
      },
      "birth":{
        "type": "date"
      }
    }
  }
}
#建立資料
PUT /wanghl/_doc/2
{
  "name":"花木蘭",
  "age":67,
  "tags":["戰士","上單","女"]
}

4.2 刪除

#刪除索引
DELETE test2
#刪除文件
DELETE test1/_doc/3

4.3修改

#修改文件
POST /test1/_update/4
{
   "doc":{
     "name":"紅桃A"
   }
}

4.4 查詢

#獲取索引庫
GET test3
#獲取文件by文件id
GET wanghl/_doc/2
#根據屬性查詢  簡寫
GET wanghl/_search?q=name:李
#構建式查詢   
#_source    欄位過濾   不寫預設 select  *
# from  size   分頁
GET /wanghl/_search
{
  "query": {
    "match": {
      "tags": "男"
    }
  },
  "_source": ["name","tags"], 
  "from":0,
  "size":1
}
#多條件查詢   must 相當於 and     should 相當於 or     
GET wanghl/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "tags": "男 下路"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "age": "3"
          }
        }
      ]
    }
  }
}
# 查詢過濾  +  高亮顯示
GET wanghl/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "tags": "男"
          }
        }
      ] ,
      "filter": [
        {
          "range": {
            "age": {
              "gte": 10,
              "lte": 200
            }
          }
        }
      ]  
    }
  },
  "highlight": {
    "pre_tags": "<font>",
    "post_tags": "</font>", 
    "fields": {
      "tags": {}
    }
  }
}

5 SpringBoot整合 ES

  1. pom檔案新增依賴
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  1. 註冊ES client物件
package com.nesc.esapi.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;

/**
 * 定義高版本ES例項物件
 * @author wanghl
 * @date 2020/7/17 9:23
 **/
@Configuration
public class ElasticSearchClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")
                )
        );
        return client;
    }
}

  1. Junit測試程式碼
package com.nesc.esapi;

import com.alibaba.fastjson.JSONObject;
import com.nesc.esapi.domain.User;
import lombok.SneakyThrows;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.ArrayList;

/**
 * ES client api測試
 */
@SpringBootTest
class EsApiApplicationTests {

    @Autowired
    RestHighLevelClient restHighLevelClient;

    /**
     * 新建索引
     * @throws Exception
     */
    @Test
    void testCreateIndex() throws IOException {
        //建立請求
        CreateIndexRequest request = new CreateIndexRequest("testapi");
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request,RequestOptions.DEFAULT);
    }

    /**
     * 查詢索引
     * @throws IOException
     */
    @Test
    void testExistIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("testapi");
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    /**
     * 刪除索引
     * @throws IOException
     */
    @Test
    void testDeleteIndex() throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("testapi");
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.out.println(delete);
    }

    /**
     * 建立文件
     * @throws IOException
     */
    @Test
    void testCreateDocument() throws IOException {
        IndexRequest indexRequest = new IndexRequest("testapi");
        User user = new User("張飛","射手");
        IndexRequest source = indexRequest.source(JSONObject.toJSONString(user), XContentType.JSON);
        IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(index.toString());
    }

    /**
     * 文件是否存在
     * @throws IOException
     */
    @Test
    void testExistDocument() throws IOException {
        //testapi 索引中     是否存在 1 的文件
        GetRequest getRequest = new GetRequest("testapi", "1");
        boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    /**
     * 獲取文件資訊
     * @throws IOException
     */
    @Test
    void testGetDocument() throws IOException {
        GetRequest getRequest = new GetRequest("testapi", "gBd0W3MBYL0QvcF5Z9tv");
        GetResponse documentFields = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(documentFields.getSource());
    }

    /**
     * 獲取文件資訊
     * @throws IOException
     */
    @Test
    void testUpdatDocument() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("testapi", "jxeBW3MBYL0QvcF5idvD");
        User user = new User("張飛","坦克");
        updateRequest.doc(JSONObject.toJSONString(user),XContentType.JSON);
        UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(update.status());
    }

    /**
     * 刪除文件資訊
     * @throws IOException
     */
    @Test
    void testDeleteDocument() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest("testapi", "jxeBW3MBYL0QvcF5idvD");
        DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(delete.status());
    }

    /**
     * 查詢文件
     */
    @Test
    void testSearchDocument() throws IOException {
        SearchRequest searchRequest = new SearchRequest("testapi");
        //匹配欄位
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("username", "李白");
        //構建查詢器
        searchRequest.source(new SearchSourceBuilder().query(matchQueryBuilder));
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(searchResponse.getHits().getTotalHits());
    }
}