1. 程式人生 > 其它 >Elasticsearch在java中的使用【同步MySQL資料】【模糊查詢】【程式碼】

Elasticsearch在java中的使用【同步MySQL資料】【模糊查詢】【程式碼】

環境準備

確認已經裝好了Elasticsearch【Elasticsearch安裝教程 - 部落格園

參考教程

參考自 關於在Java中簡單的將Mysql中的資料新增到es中並且定時同步更新 - CSDN

參考教程 Java中ElasticSearch的各種查詢(普通,模糊,字首,高亮,聚合,範圍) - CSDN

引入依賴

注意!!!

elasticsearch.version 要和自己安裝的版本協同

pom依賴程式碼

<properties>
     <elasticsearch.version>7.15.2</elasticsearch.version>
</properties>

<!-- ElasticSearch模糊查詢的依賴 fastJson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.36</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- 不知道這個是什麼依賴,但是教程說要要 -->
<!-- 注意以下依賴和 所安裝的 Elasticsearch 的版本協同 -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.15.2</version>
    <exclusions>
        <exclusion>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- client依賴 -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.15.2</version>
</dependency>
<!-- elasticsearch依賴 -->
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.15.2</version>
</dependency>
<!-- 依然不知道這是什麼依賴 -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.15.2</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

可能遇到的問題

  • fastjson 的版本報紅,不下載。

    可能是這個 fastjson 版本和 pom 檔案的別的設定衝突了,改一下 fastjson 版本就行

  • pom 檔案更新的時候報錯 Connot connect

    誰知道這是什麼問題啊【應該是我手賤又下載了個JDK導致的自動更新】

    可能是 jdk 環境被自動改了。File -- Setting -- Maven -- Importing -- 檢視 JDK for Inporting 的設定是否正確

建立配置類

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

// Elasticsearch的配置類【配置es連結】
@Configuration
public class ElasticSearchClientConfig
{
    // 這一段感覺應該是初始化了一個 RequestOptions 變數
    public static final RequestOptions COMMON_OPTIONS;
    static
    {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
        COMMON_OPTIONS = builder.build();
    }

    /**
     * 無賬號密碼登入
     * @return RestHighLevelClient
     */
    @Bean
    public static RestHighLevelClient restHighLevelClient()
    {
        // 叢集配置法
        RestHighLevelClient client = new RestHighLevelClient
                (RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
        return client;
    }
}

將資料庫的資料同步到ES

import com.alibaba.fastjson.JSONObject;
import com.placename.general.config.ElasticSearchClientConfig;
import com.placename.general.mapper.PogOfficialInfoMapper;
import com.placename.general.model.domain.PogOfficialInfo;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

@EnableScheduling // 定時器
@Component
public class ElasticsearchImpl
{
    @Autowired
    @Resource
    // 這個是要被同步的資料表所對應的Mapper
    private PogOfficialInfoMapper pogOfficialInfoMapper;

    // 定時器註解,每過去5秒執行這個方法
    @Scheduled(cron = "0/5 * * * * ?")
    public void Escalculating()
    {
        // 查詢 OfficialInfo 表中的所有資料,待會這些資料全部放在 es 裡
        List<PogOfficialInfo> list = pogOfficialInfoMapper.getall();

        // 呼叫高層物件
        // ElasticSearchClientConfig 為之前寫的 Elasticsearch 配置類,restHighLevelClient 是其中的靜態方法
        RestHighLevelClient client = ElasticSearchClientConfig.restHighLevelClient();

        // 儲存剛剛 list 裡獲得的物件
        for(PogOfficialInfo temp:list)
        {
            // 建立構造器指定index索引
            IndexRequest indexRequest = new IndexRequest("officialinfo");  // 索引的名字
            indexRequest.id(temp.getId().toString());

            // 建立批量操作的物件
            BulkRequest request = new BulkRequest();

            // 將查詢到的資料轉化為Json
            indexRequest.source(JSONObject.toJSONString(temp), XContentType.JSON);
            // Json資料放入批量操作物件中
            request.add(indexRequest);

            // 執行操作
            try
            {
                client.bulk(request,ElasticSearchClientConfig.COMMON_OPTIONS);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            System.out.println(temp);
        }
    }
}

Elasticsearch查詢示例

GET officialinfo/_search
{
  "query":{
    "match": {
      "content": {
        "query": "疫情 核酸",
        "operator": "or"
      }
    }
  }
}

使用Elasticsearch進行查詢

測試類測試

import com.placename.general.model.domain.PogOfficialInfo;
import org.apache.http.HttpHost;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.BeforeAll;
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;
import java.util.List;

@SpringBootTest
public class ElasticsearchApplicationTest
{
    // 連線客戶端
    @Autowired
    RestHighLevelClient client;

    @Test
    public void testClient() throws IOException
    {
        // 初始化客戶端
        // 正常操作應該是把這個方法加上 @Before 註解實現比較好
        System.out.println(client);
        HttpHost serverHost = new HttpHost("localhost",9200);
        client = new RestHighLevelClient(RestClient.builder(serverHost));

        /* // 驗證索引是否正常 - OK
        // 查詢索引資訊
        // GetIndexRequest("officialinfo") 中的 officialinfo 為索引名稱
        GetIndexRequest request = new GetIndexRequest("officialinfo");
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        // 獲取別名
        System.out.println(response.getAliases().toString());
        // 獲取預設設定
        System.out.println(response.getDefaultSettings().toString());
        // 獲取索引資訊
        System.out.println(response.getIndices().toString());
        // 獲取對映資訊
        System.out.println(response.getMappings().toString());
        */

        /*
        // 驗證文件是否正常 - OK
        // 文件查詢【查詢 id 為 1 的資料】
        // officialinfo 為索引名稱
        GetRequest request = new GetRequest().index("officialinfo").id("1");
        GetResponse response = client.get(request,RequestOptions.DEFAULT);
        System.out.println(response);
        */

        // 模糊查詢
        // 建立查詢request
        // officialinfo 為索引名稱
        SearchRequest request = new SearchRequest("officialinfo");
        // 這個request.type() 可能因為 Elasticsearch 版本的問題,已經不用了,如果用的話,會報錯
        // 【[types removal] Specifying types in search requests is deprecated."]】
        // request.types("text");
        // 指定查詢條件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 選擇模糊查詢匹配的模式是 and 還是 or
        // 也可以不加後面的 .operator(Operator.OR) ,如果不加,就是直接匹配
        builder.query(QueryBuilders.matchQuery("content","防疫 核酸").operator(Operator.OR));
        request.source(builder);
        // 執行查詢
        SearchResponse response = client.search(request,RequestOptions.DEFAULT);

        // 結果列印【為什麼用 Hit ,需要去看 Elasticsearch 查詢的結果,看結果很容易就明白了】
        for(SearchHit hit:response.getHits().getHits())
        {
            System.out.println(hit.getSourceAsMap());
        }

        // 銷燬客戶端 【同上,理論上應該用 @After 註解實現】
        if(client == null)
        {
            try
            {
                client.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

詳細的Elasticsearch的使用我將會再寫一個教程,如果有需要,請到我的部落格中去尋找阿巴阿巴,這個可以當作初版,或者說程式碼版