“ 閱讀完本文需要 5 分鍾。”
最近因為項目需要使用到 Elasticsearch,故而去學了一下,在此記錄一下。
一、搭建基礎環境和項目腳手架
打開 https://www.elastic.co/ 官網,下載 elasticSearch-6.3.2.zip 壓縮包,下載 kibana-6.3.2.zip 和 logstash-6.3.2.zip ,解壓縮到一個 elk 的文件夾下。idea 使用 spring.start.io 來創建一個springboot 項目,注意 elasticsearch 和 springboot 版本對應的關系, 這里選擇的是 Springboot 2.1.10.RELEASE,具體版本可以打開 https://mvnrepository.com/ 搜索 spring-boot-starter-data-elasticsearch 查看相關依賴,確定適合本機安裝的 es 版本。
二、關於 Elasticsearch 和 Kibana 以及 Logstash 基本介紹
Elasticsearch 用於全文搜索,使用了基於 Restful 的 API 交互方式訪問,它是一個文檔數據庫,可以對存儲的每個字段進行索引,可以將 mysql 中的數據同步至 es 集群中進行分詞處理,可以和 mysql 進行對比,
最新版本 7.7 發生了一些變動:es7的java代碼,只能使用 restclient。然后,個人綜合了一下,對於 java 編程,建議采用 High-level-rest-client 的方式操作 ES 集群
。官方 在 es7 刪除 type,並且 es6 時已經規定每一個index只能有一個 type。在 es7 中使用默認的_doc作為 type,官方說在 8.x 版本會徹底移除 type。
api 請求方式也發送變化,如獲得某索引的某ID的文檔:GET
index/_doc/id 其中 index 和 id 為具體的值。
es 的基本操作:
1、前提是必須安裝了相應版本 jdk, 啟動 bin\elasticsearch.bat,linux 環境下 bin\elasticsearch,訪問 localhost:9200 出現一串 json 字符串表示啟動成功;
2、啟動完 elasticsearch 后 再啟動 Kibana ,進入解壓目錄 .\bin\kibana.bat , linux 下 .\bin\kibana ,啟動成功的話。瀏覽器中訪問 localhost:5601 會出現操作界面,打開 dev-tools 頁面,下面進行索引的操作都在該頁面進行;
2、索引的基本操作:
新建 IndexName 唯一,不然報錯
PUT /blog{}
查詢索引:
GET _search
{
"query": {
"match_all": {}
}
}
條件查詢:
POST blog/_search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"problem_desp": " "
}
},
{
"match_phrase": {
"cloud_id": "abcd"
}
}
]
}
}
}
刪除索引慎操作會刪除當前索引的所有數據(類似於 mysql 中 drop database 操作):
DELETE /blog{}
3、es 基本分詞器 和 ik 分詞器介紹
分詞器介紹:
standard 支持中文,詞匯單元轉成小寫形式,采用單字切分
simple 非字母分詞器去掉
workspace 去掉空格不支持中文
language 不支持中文
POST _analyze
{
"analyzer": "standard",
"text": "我是中國人"
}
返回結果:
{
"tokens": [
{
"token": "我",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "是",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "中",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "國",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 3
},
{
"token": "人",
"start_offset": 5,
"end_offset": 6,
"type": "<IDEOGRAPHIC>",
"position": 4
}
]
}
它們對於中文的支持就好像一個老外講中文的感覺,所以國內 es 大神開發了中文分詞器 ik ,打開網址 https://github.com/medcl/elasticsearch-analysis-ik/releases 選擇你的 es 版本和對應的文件格式,下載完成以后在 es 的壓縮目錄下 plugins 文件夾下新建 ik 文件夾然后將下載的文件解壓出來全部復制到 ik 文件夾下,重啟 es 使之生效;
POST _analyze
{
"analyzer": "ik_smart",
"text": "我是中國人"
}
結果很智能,我是中國人,分為三個詞, 我、是、中國人
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "中國人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 2
}
]
}
或者使用 ik_max_word
POST _analyze
{
"analyzer": "ik_max_word",
"text": "我是中國人"
}
查詢結果和 ik_smart 對比一下:
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "中國人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 2
},
{
"token": "中國",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 3
},
{
"token": "國人",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 4
}
]
}
4、使用 Logstash 導入 mysql 數據到 es 中
導入數據的到 es 中的中間件有很多, 阿里巴巴出的 canal 、還有其他 go-elasticsearch 中間件,這里使用的是官方出的 Logstash ,logstash 的作用相當於一個管道用於流通數據。由於是 mysql 數據庫,進入 mysql 官網下載 jar 包,這里有個配置問題,關於 es 6.3.2 配置
logstash.conf 文件 和最新版本 es-7.7.0,es-6.3.2 將下好的 jar 文件放入 es 安裝目錄下,而 es-7.7.0 則可以將 jar 文件放入 logstash-7.7.0\logstash-core\lib\jars 目錄下,相應的 logstash.conf 配置文件發生改變
logstash-6.3.2 配置放在 bin 目錄下:
4.1、 全量
一次性把數據全部導入到 elasticsearch 中,例如初始化
4.2、 增量
包括三個方面:
- 插入數據
- 原有數據更新
- 原有數據刪除
input {
jdbc {
jdbc_connection_string => "jdbc:mysql://localhost:3306/demo"
# The user we wish to execute our statement as
jdbc_user => "root"
jdbc_password => "123456"
# The path to our downloaded jdbc driver
jdbc_driver_library => "D:\\elk\\logstash-6.3.2\\logstash-6.3.2\\mysql-connector-java-5.1.47.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
# our query
statement => "select * from tb_article where create_date < NOW() order by create_date DESC;"
}
}
output {
stdout { codec => json_lines }
elasticsearch {
"hosts" => "localhost:9200"
"index" => "blog"
document_type => "_doc"
document_id => "%{article_id}"
}
}
前提是 jar 放入 logstash-7.7.0\logstash-core\lib\jars ,logstash-7.7.0 配置放在 bin 目錄下:
input {
jdbc {
jdbc_connection_string => "jdbc:mysql://localhost:3306/demo"
# The user we wish to execute our statement as
jdbc_user => "root"
jdbc_password => "123456"
# The path to our downloaded jdbc driver
jdbc_driver_library => ""
jdbc_driver_class => "com.mysql.jdbc.Driver"
# our query
statement => "select * from tb_article where create_date > :sql_last_value and create_date < NOW() order by create_date DESC;"
}
}
output {
stdout { codec => json_lines }
elasticsearch {
"hosts" => "localhost:9200"
"index" => "blog"
document_type => "_doc"
document_id => "%{article_id}"
}
}
最后進入 logstash\bin 目錄執行,logstash -f logstash.conf ,如果配置正確會看到控制台打印出配置中的 sql 語句, sql 語句中的 :sql_last_value 指的是上次訪問的數據,
導入成功后在 dev-tools 執行如下命令
GET /blog/_stats
POST /blog/_search{}
三、es 集成 springboot 項目,項目地址 :https://github.com/blench/es_demo,具體代碼不做過多解釋,目前最新的 es-7.7 版本 springboot 還在更新不建議使用最新,項目中使用了 jpa 和 ElasticsearchRepository 來作為 mysql 和 es 訪問,出現了幾個小問題,
一是 es 查詢無數據:es 實體類配置,type ="_doc" 必須加上;
二是 json 關於對象空值報錯問題,加上 @JsonIgnore 或者 spring. jackson.serialization.fail-on-empty-beans = false
三是 springboot-2.3.3 使用 jpa 會報錯導致服務無法啟動,目前上網找了原因是 hiberate 的問題還沒有解決 todo,放棄高版本選擇低版本穩定的 springboot 版本。
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
serialization:
fail-on-empty-beans: false
@Document(indexName = "blog", type = "_doc", useServerConfiguration = true, createIndex = false)
最后比較一下 es 和 mysql 的區別:
| ElasticSearch |
MySQL |
| Index |
Database |
| Type |
Table |
| Document |
Row |
| Field |
Column |
| Mapping |
Schema |
| Everything is indexed |
Index |
| Query |
SQL |
| GET http://… |
select * from … |
| POST http://… |
update table set … |
關於 elk 基本的使用就到這里了, 更多有趣的 java 知識、面試經驗、leetcode 刷題歡迎關注我的微信公眾號

參考資料:
https://www.imooc.com/learn/1161
https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html
https://aijishu.com/a/1060000000015410
