一、ES簡(jiǎn)介
1、網(wǎng)址
https://www.elastic.co/cn/what-is/elasticsearch
Elastic 的底層是開源庫(kù) Lucene。但是,你沒法直接用 Lucene,必須自己寫代碼去調(diào)用它的接口。Elastic 是 Lucene 的封裝,提供了 REST API 的操作接口,開箱即用。
REST API:天然的跨平臺(tái)。
官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html
社區(qū)中文:
https://es.xiaoleilu.com/index.html
http://doc.codingdict.com/elasticsearch/0/
開源的 Elasticsearch 是目前全文搜索引擎的首選。
它可以快速地儲(chǔ)存、搜索和分析海量數(shù)據(jù)
2、基本概念
1、Index(索引)
動(dòng)詞,相當(dāng)于 MySQL 中的 insert;
名詞,相當(dāng)于 MySQL 中的 Database
2、Type(類型)
在 Index(索引)中,可以定義一個(gè)或多個(gè)類型。
類似于 MySQL 中的 Table;每一種類型的數(shù)據(jù)放在一起;
3、Document(文檔)
保存在某個(gè)索引(Index)下,某種類型(Type)的一個(gè)數(shù)據(jù)(Document),文檔是 JSON 格式的,Document 就像是 MySQL 中的某個(gè) Table 里面的內(nèi)容;
4、倒排索引機(jī)制
4.1 正向索引和倒排索引
正向索引與倒排索引,這是在搜索領(lǐng)域中非常重要的兩個(gè)名詞,正向索引通常用于數(shù)據(jù)庫(kù)中,在搜索引擎領(lǐng)域使用的最多的就是倒排索引,我們根據(jù)如下兩個(gè)網(wǎng)頁(yè)來對(duì)這兩個(gè)概念進(jìn)行闡述:
html1
我愛我的祖國(guó),我愛編程
html2
我愛編程,我是個(gè)快樂的小碼農(nóng)
4.2 正向索引
假設(shè)我們使用mysql的全文檢索,會(huì)對(duì)如上兩句話分別進(jìn)行分詞處理,那么預(yù)計(jì)得到的結(jié)果如下:
我 愛 愛我 祖國(guó) 我的祖國(guó) 編程 愛編程 我愛編程
我 我愛 愛 編程 愛編程 我愛編程 快樂 碼農(nóng) 小碼農(nóng)
假設(shè)我們現(xiàn)在使用正向索引搜索 編程 這個(gè)詞,那么會(huì)到第一句話中去查找是否包含有 編程
這個(gè)關(guān)鍵詞,如果有則加入到結(jié)果集中;第二句話也是如此。假設(shè)現(xiàn)在有成千上百個(gè)網(wǎng)頁(yè),每個(gè)網(wǎng)頁(yè)非常非常的分詞,那么搜索的效率將會(huì)非常非常低些。
4.3 倒排索引
倒排索引是按照分詞與文檔進(jìn)行映射,我們來看看如果按照倒排索引的效果:
如果采用倒排索引的方式搜索 編程
這個(gè)詞,那么會(huì)直接找到關(guān)鍵詞中查找到 編程
,然后查找到對(duì)應(yīng)的文檔,這就是所謂的倒排索引。
3、相關(guān)軟件及下載地址
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簡(jiǎn)介
Kibana是世界上最受歡迎的開源日志分析平臺(tái)ELK Stack中的“K” ,它為用戶提供了一個(gè)工具,用于在存儲(chǔ)于Elasticsearch集群中的日志數(shù)據(jù)進(jìn)行檢索,可視化和構(gòu)建儀表板。
Kibana的核心功能是數(shù)據(jù)查詢和分析。使用各種方法,用戶可以搜索Elasticsearch中索引的數(shù)據(jù),以查找其數(shù)據(jù)中的特定事件或字符串,以進(jìn)行根本原因分析和診斷。基于這些查詢,用戶可以使用Kibana的可視化功能,允許用戶使用圖表,表格,地理圖和其他類型的可視化以各種不同的方式可視化數(shù)據(jù)。
3.2 logstash簡(jiǎn)介
Logstash是一個(gè)開源的服務(wù)器端數(shù)據(jù)處理管道,可以同時(shí)從多個(gè)數(shù)據(jù)源獲取數(shù)據(jù),并對(duì)其進(jìn)行轉(zhuǎn)換,然后將其發(fā)送到你最喜歡的“存儲(chǔ)”。創(chuàng)建于2009年,于2013年被elasticsearch收購(gòu)。
二、Docker安裝ES
1、下載鏡像文件
docker pull elasticsearch:7.4.2 存儲(chǔ)和檢索數(shù)據(jù)
docker pull kibana:7.4.2 可視化檢索數(shù)據(jù)
2、創(chuàng)建實(shí)例
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/ 保證權(quán)限
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” \ 測(cè)試環(huán)境下,設(shè)置 ES 的初始內(nèi)存和最大內(nèi)存,否則導(dǎo)致過大啟動(dòng)不了 ES,生產(chǎn)環(huán)境也需要指定一下初始內(nèi)存和最大內(nèi)容,要不然會(huì)全部占用服務(wù)器的內(nèi)存。
/mydata/elasticsearch 下面的權(quán)限必須設(shè)置為777,要不然會(huì)啟動(dòng)失敗。
如果啟動(dòng)失敗可以看下日志: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
一定改為自己虛擬機(jī)的地址
三、初步檢索
1、_cat
GET /_cat/nodes:查看所有節(jié)點(diǎn)
GET /_cat/health:查看 es 健康狀況
GET /_cat/master:查看主節(jié)點(diǎn)
GET /_cat/indices:查看所有索引 show databases;
2、索引一個(gè)文檔(保存)
保存一個(gè)數(shù)據(jù),保存在哪個(gè)索引的哪個(gè)類型下,指定用哪個(gè)唯一標(biāo)識(shí)
PUT customer/external/1;在 customer 索引下的 external 類型下保存 1 號(hào)數(shù)據(jù)為
PUT customer/external/1
{ "name": "John Doe"
}
PUT 和 POST 都可以,
POST 新增。如果不指定 id,會(huì)自動(dòng)生成 id。指定 id 就會(huì)修改這個(gè)數(shù)據(jù),并新增版本號(hào)。
PUT 可以新增可以修改。PUT 必須指定 id;由于 PUT 需要指定 id,我們一般都用來做修改操作,不指定 id 會(huì)報(bào)錯(cuò)。
3、查詢文檔
GET customer/external/1
結(jié)果:
{ "_index": "customer", //在哪個(gè)索引
"_type": "external", //在哪個(gè)類型
"_id": "1", //記錄 id
"_version": 2, //版本號(hào)
"_seq_no": 1, //并發(fā)控制字段,每次更新就會(huì)+1,用來做樂觀鎖
"_primary_term": 1, //同上,主分片重新分配,如重啟,就會(huì)變化
"found": true, "_source": { //真正的內(nèi)容
"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 操作會(huì)對(duì)比源文檔數(shù)據(jù),如果相同不會(huì)有什么操作,文檔 version 不增加
PUT 操作總會(huì)將數(shù)據(jù)重新保存并增加 version 版本;
帶_update 對(duì)比元數(shù)據(jù)如果一樣就不進(jìn)行任何操作。
看場(chǎng)景;
對(duì)于大并發(fā)更新,不帶 update;
對(duì)于大并發(fā)查詢偶爾更新,帶 update;對(duì)比更新,重新計(jì)算分配規(guī)則。
? 更新同時(shí)增加屬性
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" }
語(yǔ)法格式:
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
復(fù)雜實(shí)例:
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 以此按順序執(zhí)行所有的 action(動(dòng)作)。如果一個(gè)單個(gè)的動(dòng)作因任何原因而失敗,它將繼續(xù)處理它后面剩余的動(dòng)作。當(dāng) bulk API 返回時(shí),它將提供每個(gè)動(dòng)作的狀態(tài)(與發(fā)送的順序相同),所以您可以檢查是否一個(gè)指定的動(dòng)作是不是失敗了。
7、樣本測(cè)試數(shù)據(jù)
我準(zhǔn)備了一份顧客銀行賬戶信息的虛構(gòu)的 JSON 文檔樣本。每個(gè)文檔都有下列的 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 導(dǎo)入測(cè)試數(shù)據(jù)
POST bank/account/_bulk
測(cè)試數(shù)據(jù)
四、進(jìn)階檢索
1、SearchAPI
ES 支持兩種基本方式檢索 :
? 一個(gè)是通過使用 REST request URI 發(fā)送搜索參數(shù)(uri+檢索參數(shù))
? 另一個(gè)是通過使用 REST request body 來發(fā)送它們(uri+請(qǐng)求體)
1)、檢索信息
? 一切檢索從_search 開始
GET bank/_search 檢索 bank 下所有信息,包括 type 和 docs
GET bank/_search?q=*&sort=account_number:asc 請(qǐng)求參數(shù)方式檢索
響應(yīng)結(jié)果解釋:
took - Elasticsearch 執(zhí)行搜索的時(shí)間(毫秒)
time_out - 告訴我們搜索是否超時(shí)
_shards - 告訴我們多少個(gè)分片被搜索了,以及統(tǒng)計(jì)了成功/失敗的搜索分片
hits - 搜索結(jié)果
hits.total - 搜索結(jié)果
hits.hits - 實(shí)際的搜索結(jié)果數(shù)組(默認(rèn)為前 10 的文檔)
sort - 結(jié)果的排序 key(鍵)(沒有則按 score 排序)
score 和 max_score –相關(guān)性得分和最高得分(全文檢索用)
? uri+請(qǐng)求體進(jìn)行檢索
GET bank/_search
{ "query": { "match_all": {}
},"sort": [
{ "account_number": { "order": "desc"
}
}
]
}
HTTP 客戶端工具(POSTMAN),get 請(qǐng)求不能攜帶請(qǐng)求體,我們變?yōu)?post 也是一樣的我們 POST 一個(gè) JSON 風(fēng)格的查詢請(qǐng)求體到 _search API。
需要了解,一旦搜索的結(jié)果被返回,Elasticsearch 就完成了這次請(qǐng)求,并且不會(huì)維護(hù)任何服務(wù)端的資源或者結(jié)果的 cursor(游標(biāo)).
2、Query DSL((domain-specific language 領(lǐng)域特定語(yǔ)言)
1)、基本語(yǔ)法格式
Elasticsearch 提供了一個(gè)可以執(zhí)行查詢的 Json 風(fēng)格的 DSL(domain-specific language 領(lǐng)域特定語(yǔ)言)。這個(gè)被稱為 Query DSL。該查詢語(yǔ)言非常全面,并且剛開始的時(shí)候感覺有點(diǎn)復(fù)雜,真正學(xué)好它的方法是從一些基礎(chǔ)的示例開始的。
? 一個(gè)查詢語(yǔ)句 的典型結(jié)構(gòu)
{
QUERY_NAME: {
ARGUMENT: VALUE, ARGUMENT: VALUE,... }
}
? 如果是針對(duì)某個(gè)字段,那么它的結(jié)構(gòu)如下:
{
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 中組合非常多的查
詢類型完成復(fù)雜查詢
? 除了 query 參數(shù)之外,我們也可以傳遞其它的參數(shù)以改變查詢結(jié)果。如 sort,size
? from+size 限定,完成分頁(yè)功能
? sort 排序,多字段排序,會(huì)在前序字段相等時(shí)后續(xù)字段內(nèi)部排序,否則以前序?yàn)闇?zhǔn)
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 當(dāng)搜索字符串類型的時(shí)候,會(huì)進(jìn)行全文檢索,并且每條記錄有相關(guān)性得分。
? 字符串,多個(gè)單詞(分詞+全文檢索)
GET bank/_search
{ "query": { "match": { "address": "mill road"
}
}
}
最終查詢出 address 中包含 mill 或者 road 或者 mill road 的所有記錄,并給出相關(guān)性得分
4)、match_phrase【短語(yǔ)匹配】
將需要匹配的值當(dāng)成一個(gè)整體單詞(不分詞)進(jìn)行檢索
GET bank/_search
{ "query": { "match_phrase": { "address": "mill road"
}
}
}
查出 address 中包含 mill road 的所有記錄,并給出相關(guān)性得分
5)、multi_match【多字段匹配】
GET bank/_search
{ "query": { "multi_match": { "query": "mill", "fields": ["state","address"]
}
}
}
state 或者 address 包含 mill
6)、bool【復(fù)合查詢】
bool 用來做復(fù)合查詢:
復(fù)合語(yǔ)句可以合并 任何 其它查詢語(yǔ)句,包括復(fù)合語(yǔ)句,了解這一點(diǎn)是很重要的。這就意味著,復(fù)合語(yǔ)句之間可以互相嵌套,可以表達(dá)非常復(fù)雜的邏輯。
? must:必須達(dá)到 must 列舉的所有條件
GET bank/_search
{ "query": { "bool": { "must": [
{ "match": { "address": "mill" } },
{ "match": { "gender": "M" } }
]
}
}
}
? should:應(yīng)該達(dá)到 should 列舉的條件,如果達(dá)到會(huì)增加相關(guān)文檔的評(píng)分,并不會(huì)改變
查詢的結(jié)果。如果 query 中只有 should 且只有一種匹配規(guī)則,那么 should 的條件就會(huì)
被作為默認(rèn)匹配條件而去改變查詢結(jié)果
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【結(jié)果過濾】
并不是所有的查詢都需要產(chǎn)生分?jǐn)?shù),特別是那些僅用于 “filtering”(過濾)的文檔。為了不
計(jì)算分?jǐn)?shù) Elasticsearch 會(huì)自動(dòng)檢查場(chǎng)景并且優(yōu)化查詢的執(zhí)行。
GET bank/_search
{ "query": { "bool": { "must": [
{"match": { "address": "mill"}}
],"filter": { "range": { "balance": { "gte": 10000, "lte": 20000
}
}
}
}
}
}
8)、term
和 match 一樣。匹配某個(gè)屬性的值。全文檢索字段用 match,其他非 text 字段匹配用 term。
GET bank/_search
{ "query": { "bool": { "must": [
{"term": { "age": { "value": "28"
}
}}, {"match": { "address": "990 Mill Road"
}}
]
}
}
}
9)、aggregations(執(zhí)行聚合)
聚合提供了從數(shù)據(jù)中分組和提取數(shù)據(jù)的能力。最簡(jiǎn)單的聚合方法大致等于 SQL GROUP BY 和 SQL 聚合函數(shù)。在 Elasticsearch 中,您有執(zhí)行搜索返回 hits(命中結(jié)果),并且同時(shí)返回聚合結(jié)果,把一個(gè)響應(yīng)中的所有 hits(命中結(jié)果)分隔開的能力。這是非常強(qiáng)大且有效的,
您可以執(zhí)行查詢和多個(gè)聚合,并且在一次使用中得到各自的(任何一個(gè)的)返回結(jié)果,使用一次簡(jiǎn)潔和簡(jiǎn)化的 API 來避免網(wǎng)絡(luò)往返。
? 搜索 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 不顯示搜索數(shù)據(jù)
aggs:執(zhí)行聚合。聚合語(yǔ)法如下
"aggs": { "aggs_name 這次聚合的名字,方便展示在結(jié)果集中": { "AGG_TYPE 聚合的類型(avg,term,terms)": {}
}
},
復(fù)雜:
按照年齡聚合,并且請(qǐng)求這些年齡段的這些人的平均薪資
GET bank/account/_search
{ "query": { "match_all": {}
},"aggs": { "age_avg": { "terms": { "field": "age", "size": 1000
},"aggs": { "banlances_avg": { "avg": { "field": "balance"
}
}
}
}
}
,"size": 1000
}
復(fù)雜:查出所有年齡分布,并且這些年齡段中 M 的平均薪資和 F 的平均薪資以及這個(gè)年齡
段的總體平均薪資
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 是用來定義一個(gè)文檔(document),以及它所包含的屬性(field)是如何存儲(chǔ)和索引的。比如,使用 mapping 來定義:
? 哪些字符串屬性應(yīng)該被看做全文本屬性(full text fields)。
? 哪些屬性包含數(shù)字,日期或者地理位置。
? 文檔中的所有屬性是否都能被索引(_all 配置)。
? 日期的格式。
? 自定義映射規(guī)則來執(zhí)行動(dòng)態(tài)添加屬性。
? 查看 mapping 信息:
GET bank/_mapping
? 修改 mapping 信息
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
3)、新版本改變
Es7 及以上移除了 type 的概念。
? 關(guān)系型數(shù)據(jù)庫(kù)中兩個(gè)數(shù)據(jù)表示是獨(dú)立的,即使他們里面有相同名稱的列也不影響使用,
但 ES 中不是這樣的。elasticsearch 是基于 Lucene 開發(fā)的搜索引擎,而 ES 中不同 type
下名稱相同的 filed 最終在 Lucene 中的處理方式是一樣的。
? 兩個(gè)不同 type 下的兩個(gè) user_name,在 ES 同一個(gè)索引下其實(shí)被認(rèn)為是同一個(gè) filed,你必須在兩個(gè)不同的 type 中定義相同的 filed 映射。否則,不同 type 中的相同字段名稱就會(huì)在處理中出現(xiàn)沖突的情況,導(dǎo)致 Lucene 處理效率下降。
? 去掉 type 就是為了提高 ES 處理數(shù)據(jù)的效率。
Elasticsearch 7.x
? URL 中的 type 參數(shù)為可選。比如,索引一個(gè)文檔不再要求提供文檔類型。
Elasticsearch 8.x
? 不再支持 URL 中的 type 參數(shù)。
解決:
1)、將索引從多類型遷移到單類型,每種類型文檔一個(gè)獨(dú)立索引
2)、將已存在的索引下的類型數(shù)據(jù),全部遷移到指定位置即可。詳見數(shù)據(jù)遷移
1、創(chuàng)建映射
1、創(chuàng)建索引并指定映射
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、更新映射
對(duì)于已經(jīng)存在的映射字段,我們不能更新。更新必須創(chuàng)建新的索引進(jìn)行數(shù)據(jù)遷移
4、數(shù)據(jù)遷移
先創(chuàng)建出 new_twitter 的正確映射。然后使用如下方式進(jìn)行數(shù)據(jù)遷移
POST _reindex [固定寫法]
{ "source": { "index": "twitter"
},"dest": { "index": "new_twitter"
}
}
將舊索引的 type 下的數(shù)據(jù)進(jìn)行遷移
POST _reindex
{ "source": {
"index": "twitter", "type": "tweet"
},"dest": { "index": "tweets"
}
}
4、分詞
一個(gè) tokenizer(分詞器)接收一個(gè)字符流,將之分割為獨(dú)立的 tokens(詞元,通常是獨(dú)立的單詞),然后輸出 tokens 流。
例如,whitespace tokenizer 遇到空白字符時(shí)分割文本。它會(huì)將文本 “Quick brown fox!” 分割為 [Quick, brown, fox!]。
該 tokenizer(分詞器)還負(fù)責(zé)記錄各個(gè) term(詞條)的順序或 position 位置(用于 phrase 短語(yǔ)和 word proximity 詞近鄰查詢),以及 term(詞條)所代表的原始 word(單詞)的 start(起始)和 end(結(jié)束)的 character offsets(字符偏移量)(用于高亮顯示搜索的內(nèi)容)。
Elasticsearch 提供了很多內(nèi)置的分詞器,可以用來構(gòu)建 custom analyzers(自定義分詞器)。
1)、安裝 ik 分詞器
注意:不能用默認(rèn) elasticsearch-plugin install xxx.zip 進(jìn)行自動(dòng)安裝
https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v6.4.2 對(duì)應(yīng) es 版本安裝
進(jìn)入 es 容器內(nèi)部 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
可以確認(rèn)是否安裝好了分詞器
cd ../bin
elasticsearch plugin list:即可列出系統(tǒng)的分詞器
因?yàn)槿萜骼锩嬷挥泻诵牡能浖虼藳]有wget,可以直接去外面的安裝wget,在外面下載wget,最好不要在容器里面下載,增加容器內(nèi)容。
yum install wget
在外面解壓好上傳上去
容器一旦啟動(dòng),最好不要?jiǎng)h除里面的掛載目錄,要不然就需要重啟容器重新掛載一下目錄。
安裝好分詞器后,需要重新啟動(dòng)一下容器,加載插件。
docker restart elasticsearch
2)、測(cè)試分詞器
使用默認(rèn)
POST _analyze
{ "text": "我是中國(guó)人"
}
請(qǐng)觀察結(jié)果
使用分詞器
POST _analyze
{ "analyzer": "ik_smart", "text": "我是中國(guó)人"
}
請(qǐng)觀察結(jié)果
另外一個(gè)分詞器
ik_max_word
POST _analyze
{ "analyzer": "ik_max_word", "text": "我是中國(guó)人"
}
請(qǐng)觀察結(jié)果
能夠看出不同的分詞器,分詞有明顯的區(qū)別,所以以后定義一個(gè)索引不能再使用默認(rèn)的 mapping 了,要手工建立 mapping, 因?yàn)橐x擇分詞器。
3)、調(diào)整虛擬機(jī)內(nèi)存大小
1、關(guān)閉虛擬機(jī)
2、打開設(shè)置里面的系統(tǒng),調(diào)到3G。
3、然后無(wú)界面啟動(dòng)虛擬機(jī),再啟動(dòng)容器。
4)、安裝nginx
先在mydata下面創(chuàng)建nginx目錄,以后所有的nginx文件都放到這個(gè)目錄下面
? 隨便啟動(dòng)一個(gè) nginx 實(shí)例,只是為了復(fù)制出配置
docker run -p 80:80 --name nginx -d nginx:1.10
本地沒有找到鏡像會(huì)自動(dòng)下載并啟動(dòng)
? 將容器內(nèi)的配置文件拷貝到當(dāng)前目錄(別忘了后面的點(diǎn)
):
docker container cp nginx:/etc/nginx .
nginx容器下的/etc/nginx目錄下的文件 拷貝到剛才創(chuàng)建的nginx文件夾下
? 修改文件名稱:mv nginx conf
把這個(gè) conf 移動(dòng)到/mydata/nginx 下
? 終止原容器:docker stop nginx
? 執(zhí)行命令刪除原容器:docker rm $ContainerId
? 創(chuàng)建新的 nginx;執(zhí)行以下命令
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下,創(chuàng)建index.html,編寫html頁(yè)面,請(qǐng)求就能夠默認(rèn)展示,說明nginx是ok的。(nginx會(huì)自動(dòng)默認(rèn)訪問html文件夾下面的內(nèi)容,默認(rèn)訪問index.html頁(yè)面,因此請(qǐng)求http://192.168.56.10:80,就是請(qǐng)求http://192.168.56.10/index.html,80是默認(rèn)端口含,不展示
)
在nginx下面的html文件夾下面創(chuàng)建es文件夾,有關(guān)的es文件就放到里面,給 nginx 的 html 下面放的所有資源可以直接訪問;
http://192.168.56.10/es/fenci.txt
5)、自定義詞庫(kù)
修改/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 擴(kuò)展配置</comment>
<!--用戶可以在這里配置自己的擴(kuò)展字典 -->
<entry key="ext_dict"></entry>
<!--用戶可以在這里配置自己的擴(kuò)展停止詞字典-->
<entry key="ext_stopwords"></entry>
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展字典 -->
<entry key="remote_ext_dict">http://192.168.128.130/fenci/myword.txt</entry>
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展停止詞字典-->
<!-- <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 擴(kuò)展配置</comment>
<!--用戶可以在這里配置自己的擴(kuò)展字典 -->
<entry key="ext_dict"></entry>
<!--用戶可以在這里配置自己的擴(kuò)展停止詞字典-->
<entry key="ext_stopwords"></entry>
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展停止詞字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
按照遠(yuǎn)程擴(kuò)展字典的路徑利用 nginx 發(fā)布靜態(tài)資源,按照請(qǐng)求路徑,創(chuàng)建對(duì)應(yīng)的文件夾以及文件,放在nginx 的 html 下
然后重啟 es 服務(wù)器,重啟 nginx。
修改es一直自動(dòng)重啟,這樣修改配置,es就會(huì)自動(dòng)重啟:
docker update elasticsearch --restart=always
在 kibana 中測(cè)試分詞效果
更新完成后,es 只會(huì)對(duì)新增的數(shù)據(jù)用新詞分詞。歷史數(shù)據(jù)是不會(huì)重新分詞的。如果想要?dú)v史數(shù)據(jù)重新分詞。需要執(zhí)行:
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 已經(jīng)不建議使用,8 以后就要廢棄
2)、9200:HTTP
? JestClient:非官方,更新慢
? RestTemplate:模擬發(fā) HTTP 請(qǐng)求,ES 很多操作需要自己封裝,麻煩
? HttpClient:同上
? Elasticsearch-Rest-Client:官方 RestClient,封裝了 ES 操作,API 層次分明,上手簡(jiǎn)單
最終選擇 Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client)
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html
2、創(chuàng)建檢索服務(wù)
配置服務(wù)注冊(cè)和配置中心。
3、SpringBoot 整合
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
發(fā)現(xiàn)其中的依賴有6.4.3版本,因?yàn)槲覀兪莝pring-boot下spring-boot-dependencies對(duì)es也做了版本管理
然后我們?cè)谧禹?xiàng)目配置中引用的版本設(shè)置為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);
}
文章來源:http://www.zghlxwxcb.cn/news/detail-651404.html
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) {
}
}
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-651404.html
到了這里,關(guān)于商城-學(xué)習(xí)整理-高級(jí)-全文檢索-ES(九)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!