目錄
- 一、ES簡介
- 1、網址
- 2、基本概念
- 1、Index(索引)
- 2、Type(類型)
- 3、Document(文檔)
- 4、倒排索引機制
- 4.1 正向索引和倒排索引
- 4.2 正向索引
- 4.3 倒排索引
- 3、相關軟件及下載地址
- 3.1 Kibana簡介
- 3.2 logstash簡介
- 二、Docker安裝ES
- 1、下載鏡像文件
- 2、創建實例
- 1、ElasticSearch
- 2、Kibana
- 三、初步檢索
- 1、_cat
- 2、索引一個文檔(保存)
- 3、查詢文檔
- 4、更新文檔
- 5、刪除文檔&索引
- 6、bulk 批量 API
- 7、樣本測試數據
- 四、進階檢索
- 1、SearchAPI
- 1)、檢索信息
- 2、Query DSL((domain-specific language 領域特定語言)
- 1)、基本語法格式
- 2)、返回部分字段
- 3)、match【匹配查詢】
- 4)、match_phrase【短語匹配】
- 5)、multi_match【多字段匹配】
- 6)、bool【復合查詢】
- 7)、filter【結果過濾】
- 8)、term
- 3、Mapping
- 1)、字段類型
- 2)、映射
- 3)、新版本改變
- 4、分詞
- 1)、安裝 ik 分詞器
- 2)、測試分詞器
- 3)、調整虛擬機內存大小
- 4)、安裝nginx
- 5)、自定義詞庫
- 五、Elasticsearch-Rest-Client
- 1、Rest客戶端選型
- 1)、9300:TCP
- 2)、9200:HTTP
- 2、創建檢索服務
- 3、SpringBoot 整合
- 4、配置
- 5、使用
一、ES簡介
1、網址
https://www.elastic.co/cn/what-is/elasticsearch
Elastic 的底層是開源庫 Lucene。但是,你沒法直接用 Lucene,必須自己寫代碼去調用它的接口。Elastic 是 Lucene 的封裝,提供了 REST API 的操作接口,開箱即用。
REST API:天然的跨平臺。
官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html
社區中文:
https://es.xiaoleilu.com/index.html
http://doc.codingdict.com/elasticsearch/0/
開源的 Elasticsearch 是目前全文搜索引擎的首選。
它可以快速地儲存、搜索和分析海量數據
2、基本概念
1、Index(索引)
動詞,相當于 MySQL 中的 insert;
名詞,相當于 MySQL 中的 Database
2、Type(類型)
在 Index(索引)中,可以定義一個或多個類型。
類似于 MySQL 中的 Table;每一種類型的數據放在一起;
3、Document(文檔)
保存在某個索引(Index)下,某種類型(Type)的一個數據(Document),文檔是 JSON 格式的,Document 就像是 MySQL 中的某個 Table 里面的內容;
4、倒排索引機制
4.1 正向索引和倒排索引
正向索引與倒排索引,這是在搜索領域中非常重要的兩個名詞,正向索引通常用于數據庫中,在搜索引擎領域使用的最多的就是倒排索引,我們根據如下兩個網頁來對這兩個概念進行闡述:
html1
我愛我的祖國,我愛編程
html2
我愛編程,我是個快樂的小碼農
4.2 正向索引
假設我們使用mysql的全文檢索,會對如上兩句話分別進行分詞處理,那么預計得到的結果如下:
我 愛 愛我 祖國 我的祖國 編程 愛編程 我愛編程
我 我愛 愛 編程 愛編程 我愛編程 快樂 碼農 小碼農
假設我們現在使用正向索引搜索 編程 這個詞,那么會到第一句話中去查找是否包含有 編程
這個關鍵詞,如果有則加入到結果集中;第二句話也是如此。假設現在有成千上百個網頁,每個網頁非常非常的分詞,那么搜索的效率將會非常非常低些。
4.3 倒排索引
倒排索引是按照分詞與文檔進行映射,我們來看看如果按照倒排索引的效果:
如果采用倒排索引的方式搜索 編程
這個詞,那么會直接找到關鍵詞中查找到 編程
,然后查找到對應的文檔,這就是所謂的倒排索引。
3、相關軟件及下載地址
Elasticsearch: https://www.elastic.co/cn/start
Kibana: https://www.elastic.co/cn/start
Logstash: https://www.elastic.co/cn/downloads/logstash
3.1 Kibana簡介
Kibana是世界上最受歡迎的開源日志分析平臺ELK Stack中的“K” ,它為用戶提供了一個工具,用于在存儲于Elasticsearch集群中的日志數據進行檢索,可視化和構建儀表板。
Kibana的核心功能是數據查詢和分析。使用各種方法,用戶可以搜索Elasticsearch中索引的數據,以查找其數據中的特定事件或字符串,以進行根本原因分析和診斷。基于這些查詢,用戶可以使用Kibana的可視化功能,允許用戶使用圖表,表格,地理圖和其他類型的可視化以各種不同的方式可視化數據。
3.2 logstash簡介
Logstash是一個開源的服務器端數據處理管道,可以同時從多個數據源獲取數據,并對其進行轉換,然后將其發送到你最喜歡的“存儲”。創建于2009年,于2013年被elasticsearch收購。
二、Docker安裝ES
1、下載鏡像文件
docker pull elasticsearch:7.4.2 存儲和檢索數據
docker pull kibana:7.4.2 可視化檢索數據
2、創建實例
1、ElasticSearch
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
chmod -R 777 /mydata/elasticsearch/ 保證權限
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
以后再外面裝好插件重啟即可;
特別注意:
-e ES_JAVA_OPTS=“-Xms64m -Xmx256m” \ 測試環境下,設置 ES 的初始內存和最大內存,否則導致過大啟動不了 ES,生產環境也需要指定一下初始內存和最大內容,要不然會全部占用服務器的內存。
/mydata/elasticsearch 下面的權限必須設置為777,要不然會啟動失敗。
如果啟動失敗可以看下日志:docker logs CONTAINER ID
2、Kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 \
-d kibana:7.4.2
http://192.168.56.10:9200
一定改為自己虛擬機的地址
三、初步檢索
1、_cat
GET /_cat/nodes:查看所有節點
GET /_cat/health:查看 es 健康狀況
GET /_cat/master:查看主節點
GET /_cat/indices:查看所有索引 show databases;
2、索引一個文檔(保存)
保存一個數據,保存在哪個索引的哪個類型下,指定用哪個唯一標識
PUT customer/external/1;在 customer 索引下的 external 類型下保存 1 號數據為
PUT customer/external/1
{ "name": "John Doe"
}
PUT 和 POST 都可以,
POST 新增。如果不指定 id,會自動生成 id。指定 id 就會修改這個數據,并新增版本號。
PUT 可以新增可以修改。PUT 必須指定 id;由于 PUT 需要指定 id,我們一般都用來做修改操作,不指定 id 會報錯。
3、查詢文檔
GET customer/external/1
結果:
{ "_index": "customer", //在哪個索引
"_type": "external", //在哪個類型
"_id": "1", //記錄 id
"_version": 2, //版本號
"_seq_no": 1, //并發控制字段,每次更新就會+1,用來做樂觀鎖
"_primary_term": 1, //同上,主分片重新分配,如重啟,就會變化
"found": true, "_source": { //真正的內容
"name": "John Doe"
}
}
更新攜帶 ?if_seq_no=0&if_primary_term=1
4、更新文檔
POST customer/external/1/_update
{ "doc":{ "name": "John Doew"
}
}
或者
POST customer/external/1
{ "name": "John Doe2"
}
或者
PUT customer/external/1
{ "name": "John Doe"
}
? 不同:POST 操作會對比源文檔數據,如果相同不會有什么操作,文檔 version 不增加
PUT 操作總會將數據重新保存并增加 version 版本;
帶_update 對比元數據如果一樣就不進行任何操作。
看場景;
對于大并發更新,不帶 update;
對于大并發查詢偶爾更新,帶 update;對比更新,重新計算分配規則。
? 更新同時增加屬性
POST customer/external/1/_update
{ “doc”: { “name”: “Jane Doe”, “age”: 20 }
}
PUT 和 POST 不帶_update 也可以。
5、刪除文檔&索引
DELETE customer/external/1
DELETE customer
6、bulk 批量 API
POST customer/external/_bulk
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
語法格式:
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
復雜實例:
POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }}
{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
{ "doc" : {"title" : "My updated blog post"} }
bulk API 以此按順序執行所有的 action(動作)。如果一個單個的動作因任何原因而失敗,它將繼續處理它后面剩余的動作。當 bulk API 返回時,它將提供每個動作的狀態(與發送的順序相同),所以您可以檢查是否一個指定的動作是不是失敗了。
7、樣本測試數據
我準備了一份顧客銀行賬戶信息的虛構的 JSON 文檔樣本。每個文檔都有下列的 schema(模式):
{ "account_number": 0, "balance": 16623, "firstname": "Bradshaw", "lastname": "Mckenzie", "age": 29, "gender": "F", "address": "244 Columbus Place", "employer": "Euron", "email": "bradshawmckenzie@euron.com", "city": "Hobucken", "state": "CO"
}
https://github.com/elastic/elasticsearch/blob/master/docs/src/test/resources/accounts.json?raw=true 導入測試數據
POST bank/account/_bulk
測試數據
四、進階檢索
1、SearchAPI
ES 支持兩種基本方式檢索 :
? 一個是通過使用 REST request URI 發送搜索參數(uri+檢索參數)
? 另一個是通過使用 REST request body 來發送它們(uri+請求體)
1)、檢索信息
? 一切檢索從_search 開始
GET bank/_search 檢索 bank 下所有信息,包括 type 和 docs
GET bank/_search?q=*&sort=account_number:asc 請求參數方式檢索
響應結果解釋:
took - Elasticsearch 執行搜索的時間(毫秒)
time_out - 告訴我們搜索是否超時
_shards - 告訴我們多少個分片被搜索了,以及統計了成功/失敗的搜索分片
hits - 搜索結果
hits.total - 搜索結果
hits.hits - 實際的搜索結果數組(默認為前 10 的文檔)
sort - 結果的排序 key(鍵)(沒有則按 score 排序)
score 和 max_score –相關性得分和最高得分(全文檢索用)
? uri+請求體進行檢索
GET bank/_search
{ "query": { "match_all": {}
},"sort": [
{ "account_number": { "order": "desc"
}
}
]
}
HTTP 客戶端工具(POSTMAN),get 請求不能攜帶請求體,我們變為 post 也是一樣的我們 POST 一個 JSON 風格的查詢請求體到 _search API。
需要了解,一旦搜索的結果被返回,Elasticsearch 就完成了這次請求,并且不會維護任何服務端的資源或者結果的 cursor(游標).
2、Query DSL((domain-specific language 領域特定語言)
1)、基本語法格式
Elasticsearch 提供了一個可以執行查詢的 Json 風格的 DSL(domain-specific language 領域特定語言)。這個被稱為 Query DSL。該查詢語言非常全面,并且剛開始的時候感覺有點復雜,真正學好它的方法是從一些基礎的示例開始的。
? 一個查詢語句 的典型結構
{
QUERY_NAME: {
ARGUMENT: VALUE, ARGUMENT: VALUE,... }
}
? 如果是針對某個字段,那么它的結構如下:
{
QUERY_NAME: {
FIELD_NAME: {
ARGUMENT: VALUE, ARGUMENT: VALUE,... }
}
}
GET bank/_search
{ "query": { "match_all": {}
},"from": 0, "size": 5, "sort": [
{ "account_number": { "order": "desc"
}
}
]
}
? query 定義如何查詢,
? match_all 查詢類型【代表查詢所有的所有】,es 中可以在 query 中組合非常多的查
詢類型完成復雜查詢
? 除了 query 參數之外,我們也可以傳遞其它的參數以改變查詢結果。如 sort,size
? from+size 限定,完成分頁功能
? sort 排序,多字段排序,會在前序字段相等時后續字段內部排序,否則以前序為準
2)、返回部分字段
GET bank/_search
{ "query": {
"match_all": {}
},"from": 0, "size": 5, "_source": ["age","balance"]
}
3)、match【匹配查詢】
? 基本類型(非字符串),精確匹配
GET bank/_search
{ "query": { "match": { "account_number": "20"
}
}
}
match 返回 account_number=20 的
? 字符串,全文檢索
GET bank/_search
{ "query": { "match": { "address": "mill"
}
}
}
最終查詢出 address 中包含 mill 單詞的所有記錄
match 當搜索字符串類型的時候,會進行全文檢索,并且每條記錄有相關性得分。
? 字符串,多個單詞(分詞+全文檢索)
GET bank/_search
{ "query": { "match": { "address": "mill road"
}
}
}
最終查詢出 address 中包含 mill 或者 road 或者 mill road 的所有記錄,并給出相關性得分
4)、match_phrase【短語匹配】
將需要匹配的值當成一個整體單詞(不分詞)進行檢索
GET bank/_search
{ "query": { "match_phrase": { "address": "mill road"
}
}
}
查出 address 中包含 mill road 的所有記錄,并給出相關性得分
5)、multi_match【多字段匹配】
GET bank/_search
{ "query": { "multi_match": { "query": "mill", "fields": ["state","address"]
}
}
}
state 或者 address 包含 mill
6)、bool【復合查詢】
bool 用來做復合查詢:
復合語句可以合并 任何 其它查詢語句,包括復合語句,了解這一點是很重要的。這就意味著,復合語句之間可以互相嵌套,可以表達非常復雜的邏輯。
? must:必須達到 must 列舉的所有條件
GET bank/_search
{ "query": { "bool": { "must": [
{ "match": { "address": "mill" } },
{ "match": { "gender": "M" } }
]
}
}
}
? should:應該達到 should 列舉的條件,如果達到會增加相關文檔的評分,并不會改變
查詢的結果。如果 query 中只有 should 且只有一種匹配規則,那么 should 的條件就會
被作為默認匹配條件而去改變查詢結果
GET bank/_search
{ "query": { "bool": { "must": [
{ "match": { "address": "mill" } }, { "match": { "gender": "M" } }
],"should": [
{"match": { "address": "lane" }}
]
}
}
}
? must_not 必須不是指定的情況
GET bank/_search
{ "query": { "bool": { "must": [
{ "match": { "address": "mill" } }, { "match": { "gender": "M" } }
],"should": [
{"match": { "address": "lane" }}
],"must_not": [
{"match": { "email": "baluba.com" }}
]
}
}
}
address 包含 mill,并且 gender 是 M,如果 address 里面有 lane 最好不過,但是 email 必
須不包含 baluba.com
7)、filter【結果過濾】
并不是所有的查詢都需要產生分數,特別是那些僅用于 “filtering”(過濾)的文檔。為了不
計算分數 Elasticsearch 會自動檢查場景并且優化查詢的執行。
GET bank/_search
{ "query": { "bool": { "must": [
{"match": { "address": "mill"}}
],"filter": { "range": { "balance": { "gte": 10000, "lte": 20000
}
}
}
}
}
}
8)、term
和 match 一樣。匹配某個屬性的值。全文檢索字段用 match,其他非 text 字段匹配用 term。
GET bank/_search
{ "query": { "bool": { "must": [
{"term": { "age": { "value": "28"
}
}}, {"match": { "address": "990 Mill Road"
}}
]
}
}
}
9)、aggregations(執行聚合)
聚合提供了從數據中分組和提取數據的能力。最簡單的聚合方法大致等于 SQL GROUP BY 和 SQL 聚合函數。在 Elasticsearch 中,您有執行搜索返回 hits(命中結果),并且同時返回聚合結果,把一個響應中的所有 hits(命中結果)分隔開的能力。這是非常強大且有效的,
您可以執行查詢和多個聚合,并且在一次使用中得到各自的(任何一個的)返回結果,使用一次簡潔和簡化的 API 來避免網絡往返。
? 搜索 address 中包含 mill 的所有人的年齡分布以及平均年齡,但不顯示這些人的詳情。
GET bank/_search
{ "query": { "match": { "address": "mill"
}
},"aggs": { "group_by_state": { "terms": { "field": "age"
}
},"avg_age": { "avg": {
"field": "age"
}
}
},"size": 0
}
size:0 不顯示搜索數據
aggs:執行聚合。聚合語法如下
"aggs": { "aggs_name 這次聚合的名字,方便展示在結果集中": { "AGG_TYPE 聚合的類型(avg,term,terms)": {}
}
},
復雜:
按照年齡聚合,并且請求這些年齡段的這些人的平均薪資
GET bank/account/_search
{ "query": { "match_all": {}
},"aggs": { "age_avg": { "terms": { "field": "age", "size": 1000
},"aggs": { "banlances_avg": { "avg": { "field": "balance"
}
}
}
}
}
,"size": 1000
}
復雜:查出所有年齡分布,并且這些年齡段中 M 的平均薪資和 F 的平均薪資以及這個年齡
段的總體平均薪資
GET bank/account/_search
{ "query": { "match_all": {}
},"aggs": { "age_agg": { "terms": { "field": "age", "size": 100
},"aggs": { "gender_agg": { "terms": { "field": "gender.keyword", "size": 100
},"aggs": { "balance_avg": { "avg": { "field": "balance"
}
}
}
},"balance_avg":{ "avg": { "field": "balance"
}
}
}
}
}
,"size": 1000
}
3、Mapping
1)、字段類型
2)、映射
Mapping(映射)
Mapping 是用來定義一個文檔(document),以及它所包含的屬性(field)是如何存儲和索引的。比如,使用 mapping 來定義:
? 哪些字符串屬性應該被看做全文本屬性(full text fields)。
? 哪些屬性包含數字,日期或者地理位置。
? 文檔中的所有屬性是否都能被索引(_all 配置)。
? 日期的格式。
? 自定義映射規則來執行動態添加屬性。
? 查看 mapping 信息:
GET bank/_mapping
? 修改 mapping 信息
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
3)、新版本改變
Es7 及以上移除了 type 的概念。
? 關系型數據庫中兩個數據表示是獨立的,即使他們里面有相同名稱的列也不影響使用,
但 ES 中不是這樣的。elasticsearch 是基于 Lucene 開發的搜索引擎,而 ES 中不同 type
下名稱相同的 filed 最終在 Lucene 中的處理方式是一樣的。
? 兩個不同 type 下的兩個 user_name,在 ES 同一個索引下其實被認為是同一個 filed,你必須在兩個不同的 type 中定義相同的 filed 映射。否則,不同 type 中的相同字段名稱就會在處理中出現沖突的情況,導致 Lucene 處理效率下降。
? 去掉 type 就是為了提高 ES 處理數據的效率。
Elasticsearch 7.x
? URL 中的 type 參數為可選。比如,索引一個文檔不再要求提供文檔類型。
Elasticsearch 8.x
? 不再支持 URL 中的 type 參數。
解決:
1)、將索引從多類型遷移到單類型,每種類型文檔一個獨立索引
2)、將已存在的索引下的類型數據,全部遷移到指定位置即可。詳見數據遷移
1、創建映射
1、創建索引并指定映射
PUT /my-index
{ "mappings": { "properties": {
"age": { "type": "integer" }, "email": { "type": "keyword" }, "name": { "type": "text" }
}
}
}
2、添加新的字段映射
PUT /my-index/_mapping
{ "properties": { "employee-id": { "type": "keyword", "index": false
}
}
}
3、更新映射
對于已經存在的映射字段,我們不能更新。更新必須創建新的索引進行數據遷移
4、數據遷移
先創建出 new_twitter 的正確映射。然后使用如下方式進行數據遷移
POST _reindex [固定寫法]
{ "source": { "index": "twitter"
},"dest": { "index": "new_twitter"
}
}
將舊索引的 type 下的數據進行遷移
POST _reindex
{ "source": {
"index": "twitter", "type": "tweet"
},"dest": { "index": "tweets"
}
}
4、分詞
一個 tokenizer(分詞器)接收一個字符流,將之分割為獨立的 tokens(詞元,通常是獨立的單詞),然后輸出 tokens 流。
例如,whitespace tokenizer 遇到空白字符時分割文本。它會將文本 “Quick brown fox!” 分割為 [Quick, brown, fox!]。
該 tokenizer(分詞器)還負責記錄各個 term(詞條)的順序或 position 位置(用于 phrase 短語和 word proximity 詞近鄰查詢),以及 term(詞條)所代表的原始 word(單詞)的 start(起始)和 end(結束)的 character offsets(字符偏移量)(用于高亮顯示搜索的內容)。
Elasticsearch 提供了很多內置的分詞器,可以用來構建 custom analyzers(自定義分詞器)。
1)、安裝 ik 分詞器
注意:不能用默認 elasticsearch-plugin install xxx.zip 進行自動安裝
https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v6.4.2 對應 es 版本安裝
進入 es 容器內部 plugins 目錄
docker exec -it 容器 id /bin/bash
wget
https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-anal
ysis-ik-7.4.2.zip
unzip 下載的文件
rm –rf *.zip
mv elasticsearch/ ik
可以確認是否安裝好了分詞器
cd ../bin
elasticsearch plugin list:即可列出系統的分詞器
因為容器里面只有核心的軟件,因此沒有wget,可以直接去外面的安裝wget,在外面下載wget,最好不要在容器里面下載,增加容器內容。
yum install wget
在外面解壓好上傳上去
容器一旦啟動,最好不要刪除里面的掛載目錄,要不然就需要重啟容器重新掛載一下目錄。
安裝好分詞器后,需要重新啟動一下容器,加載插件。
docker restart elasticsearch
2)、測試分詞器
使用默認
POST _analyze
{ "text": "我是中國人"
}
請觀察結果
使用分詞器
POST _analyze
{ "analyzer": "ik_smart", "text": "我是中國人"
}
請觀察結果
另外一個分詞器
ik_max_word
POST _analyze
{ "analyzer": "ik_max_word", "text": "我是中國人"
}
請觀察結果
能夠看出不同的分詞器,分詞有明顯的區別,所以以后定義一個索引不能再使用默認的 mapping 了,要手工建立 mapping, 因為要選擇分詞器。
3)、調整虛擬機內存大小
1、關閉虛擬機
2、打開設置里面的系統,調到3G。
3、然后無界面啟動虛擬機,再啟動容器。
4)、安裝nginx
先在mydata下面創建nginx目錄,以后所有的nginx文件都放到這個目錄下面
? 隨便啟動一個 nginx 實例,只是為了復制出配置
docker run -p 80:80 --name nginx -d nginx:1.10
本地沒有找到鏡像會自動下載并啟動
? 將容器內的配置文件拷貝到當前目錄(別忘了后面的點
):
docker container cp nginx:/etc/nginx .
nginx容器下的/etc/nginx目錄下的文件 拷貝到剛才創建的nginx文件夾下
? 修改文件名稱:mv nginx conf
把這個 conf 移動到/mydata/nginx 下
? 終止原容器:docker stop nginx
? 執行命令刪除原容器:docker rm $ContainerId
? 創建新的 nginx;執行以下命令
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
去nginx外部掛載目錄,html下,創建index.html,編寫html頁面,請求就能夠默認展示,說明nginx是ok的。(nginx會自動默認訪問html文件夾下面的內容,默認訪問index.html頁面,因此請求http://192.168.56.10:80,就是請求http://192.168.56.10/index.html,80是默認端口含,不展示
)
在nginx下面的html文件夾下面創建es文件夾,有關的es文件就放到里面,給 nginx 的 html 下面放的所有資源可以直接訪問;
http://192.168.56.10/es/fenci.txt
5)、自定義詞庫
修改/usr/share/elasticsearch/plugins/ik/config/中的 IKAnalyzer.cfg.xml
/usr/share/elasticsearch/plugins/ik/config
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 擴展配置</comment>
<!--用戶可以在這里配置自己的擴展字典 -->
<entry key="ext_dict"></entry>
<!--用戶可以在這里配置自己的擴展停止詞字典-->
<entry key="ext_stopwords"></entry>
<!--用戶可以在這里配置遠程擴展字典 -->
<entry key="remote_ext_dict">http://192.168.128.130/fenci/myword.txt</entry>
<!--用戶可以在這里配置遠程擴展停止詞字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
原來的 xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 擴展配置</comment>
<!--用戶可以在這里配置自己的擴展字典 -->
<entry key="ext_dict"></entry>
<!--用戶可以在這里配置自己的擴展停止詞字典-->
<entry key="ext_stopwords"></entry>
<!--用戶可以在這里配置遠程擴展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用戶可以在這里配置遠程擴展停止詞字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
按照遠程擴展字典的路徑利用 nginx 發布靜態資源,按照請求路徑,創建對應的文件夾以及文件,放在nginx 的 html 下
然后重啟 es 服務器,重啟 nginx。
修改es一直自動重啟,這樣修改配置,es就會自動重啟:
docker update elasticsearch --restart=always
在 kibana 中測試分詞效果
更新完成后,es 只會對新增的數據用新詞分詞。歷史數據是不會重新分詞的。如果想要歷史數據重新分詞。需要執行:
POST my_index/_update_by_query?conflicts=proceed
五、Elasticsearch-Rest-Client
1、Rest客戶端選型
1)、9300:TCP
? spring-data-elasticsearch:transport-api.jar;
? springboot 版本不同, transport-api.jar 不同,不能適配 es 版本
? 7.x 已經不建議使用,8 以后就要廢棄
2)、9200:HTTP
? JestClient:非官方,更新慢
? RestTemplate:模擬發 HTTP 請求,ES 很多操作需要自己封裝,麻煩
? HttpClient:同上
? Elasticsearch-Rest-Client:官方 RestClient,封裝了 ES 操作,API 層次分明,上手簡單
最終選擇 Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client)
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html
2、創建檢索服務
配置服務注冊和配置中心。
3、SpringBoot 整合
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
發現其中的依賴有6.4.3版本,因為我們是spring-boot下spring-boot-dependencies對es也做了版本管理
然后我們在子項目配置中引用的版本設置為7.4.2
刷新一下,就全部變成7.4.2了
4、配置
@Bean
RestHighLevelClient client() {
RestClientBuilder builder = RestClient.builder(new HttpHost("192.168.56.10", 9200, "http"));
return new RestHighLevelClient(builder);
}
5、使用
參照官方文檔:
@Test
void test1() throws IOException {
Product product = new Product();
product.setSpuName("華為");
product.setId(10L);
IndexRequest request = new IndexRequest("product").id("20")
.source("spuName","華為","id",20L);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(request.toString());
IndexResponse response2 = client.index(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
}