Elasticsearch在java中的使用【同步MySQL資料】【模糊查詢】【程式碼】
阿新 • • 發佈:2022-06-01
環境準備
確認已經裝好了Elasticsearch【Elasticsearch安裝教程 - 部落格園】
參考教程
引入依賴
注意!!!
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的使用我將會再寫一個教程,如果有需要,請到我的部落格中去尋找阿巴阿巴,這個可以當作初版,或者說程式碼版