ElasticSearch探索之路(六)实战:环境搭建、REST、CRUD、Search
文章目錄
- 環(huán)境搭建
- 搭建Elasticsearch環(huán)境
- 搭建Kibana環(huán)境
- 基本操作
- RESTful
- CRUD
- 創(chuàng)建索引
- 插入文檔
- 查詢(xún)文檔
- 更新文檔
- 刪除文檔和索引
- Search
- 查詢(xún)方式
- URL + 參數(shù)
- URL + QueryDSL
- match 匹配
- match 匹配查詢(xún)
- match_all 全部匹配
- match_phase 短語(yǔ)匹配
- multi_match 多字段匹配
- term 精確查詢(xún)
- 布爾查詢(xún)(復(fù)合查詢(xún))
- Filter 過(guò)濾器
- Aggregations 聚合
環(huán)境搭建
搭建Elasticsearch環(huán)境
下載docker鏡像
docker pull elasticsearch:7.4.2映射配置文件
# 配置映射文件夾 mkdir -p /mydata/elasticsearch/config mkdir -p /mydata/elasticsearch/data# 設(shè)置文件夾權(quán)限任何用戶(hù)可讀可寫(xiě) chmod 777 /mydata/elasticsearch -R# 配置 http.host echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml啟動(dòng)容器
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.type"="single-node" \ # 設(shè)置為單節(jié)點(diǎn) -e ES_JAVA_OPTS="-Xms64m -Xmx128m" \ # 設(shè)置啟動(dòng)時(shí)ES的初始內(nèi)存以及最大內(nèi)存 -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訪問(wèn)ES服務(wù),http://127.0.0.1:9200/
得到相應(yīng)體如下:
{"name" : "de85ed684243","cluster_name" : "elasticsearch","cluster_uuid" : "UeIP1PrXT2OFd7FlEEl3hQ","version" : {"number" : "7.4.2","build_flavor" : "default","build_type" : "docker","build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96","build_date" : "2019-10-28T20:40:44.881551Z","build_snapshot" : false,"lucene_version" : "8.2.0","minimum_wire_compatibility_version" : "6.8.0","minimum_index_compatibility_version" : "6.0.0-beta1"},"tagline" : "You Know, for Search" }可以通過(guò)/_cat來(lái)獲取節(jié)點(diǎn)信息
# 訪問(wèn)http://82.157.127.173:9200/_cat# 屬性列表 /_cat/allocation /_cat/shards /_cat/shards/{index} /_cat/master /_cat/nodes /_cat/tasks /_cat/indices /_cat/indices/{index} /_cat/segments /_cat/segments/{index} /_cat/count /_cat/count/{index} /_cat/recovery /_cat/recovery/{index} /_cat/health /_cat/pending_tasks /_cat/aliases /_cat/aliases/{alias} /_cat/thread_pool /_cat/thread_pool/{thread_pools} /_cat/plugins /_cat/fielddata /_cat/fielddata/{fields} /_cat/nodeattrs /_cat/repositories /_cat/snapshots/{repository} /_cat/templates搭建Kibana環(huán)境
下載docker鏡像
docker pull kibana:7.4.2啟動(dòng)容器
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.0.128:9200 -p 5601:5601 -d kibana:7.4.2訪問(wèn)Kibana服務(wù),http://127.0.0.1:5601/
基本操作
RESTful
一種軟件架構(gòu)風(fēng)格,而不是標(biāo)準(zhǔn),只是提供了一組設(shè)計(jì)原則和約束條件。它主要用于客戶(hù)端和服務(wù)器交互類(lèi)的軟件。基于這個(gè)風(fēng)格設(shè)計(jì)的軟件可以更簡(jiǎn)潔,更有層次,更易于實(shí)現(xiàn)緩存等機(jī)制。
ES的基本REST命令:
| PUT | localhost:9200/索引名稱(chēng)/類(lèi)型名稱(chēng)/文檔id | 創(chuàng)建文檔(指定文檔id) |
| GET | localhost:9200/索引名稱(chēng)/類(lèi)型名稱(chēng)/文檔id | 通過(guò)文檔id查詢(xún)文檔 |
| POST | localhost:9200/索引名稱(chēng)/類(lèi)型名稱(chēng) | 創(chuàng)建文檔(隨機(jī)文檔id) |
| POST | localhost:9200/索引名稱(chēng)/類(lèi)型名稱(chēng)/文檔id/_update | 修改文檔 |
| POST | localhost:9200/索引名稱(chēng)/類(lèi)型名稱(chēng)/_search | 查詢(xún)所有數(shù)據(jù) |
| DELETE | localhost:9200/索引名稱(chēng)/類(lèi)型名稱(chēng)/文檔id | 刪除文檔 |
CRUD
創(chuàng)建索引
在創(chuàng)建索引時(shí),我們可以聲明字段與數(shù)據(jù)類(lèi)型的映射
請(qǐng)求:
PUT /test0 {"mappings":{"properties":{"name":{"type":"text"},"author":{"type":"text"}}} }響應(yīng):
{"acknowledged": true,"shards_acknowledged": true,"index": "test0" }即使如果我們沒(méi)有配置類(lèi)型,ES也會(huì)根據(jù)字段的內(nèi)容來(lái)自行推導(dǎo)。
注意??:由于索引具有不變性,我們只能進(jìn)行追加而不能更改已經(jīng)存在的映射字段,必須創(chuàng)建新的索引后進(jìn)行數(shù)據(jù)遷移。
POST _reindex {"source": {"index": "test0"},"dest": {"index": "test1"} }插入文檔
PUT和POST都可以插入文檔:
- POST:如果不指定 id,自動(dòng)生成 id。如果指定 id,則修改這條記錄,并新增版本號(hào)。
- PUT:必須指定 id,如果沒(méi)有這條記錄,則新增,如果有,則更新。
示例:在 test1 索引下的books類(lèi)型中保存標(biāo)識(shí)為 1 的文檔。
請(qǐng)求:
PUT /test1/books/1 {"name":"three days to see","author" : "Daniel Defoe" }響應(yīng):
{"_index": "test", //索引"_type": "book", //類(lèi)型"_id": "1", //id"_version": 1, //版本號(hào)"result": "updated", //操作類(lèi)型"_shards": { //分片"total": 2,"successful": 1,"failed": 0},"_seq_no": 1, //并發(fā)控制字段,每次更新就會(huì)+1,用來(lái)做樂(lè)觀鎖"_primary_term": 1 //同上,主分片重新分配,如重啟,就會(huì)變化 }查詢(xún)文檔
示例:查詢(xún)test1索引下的books類(lèi)型中保存標(biāo)識(shí)為 1 的文檔的內(nèi)容。
請(qǐng)求:
GET /test1/books/1響應(yīng):
{"_index": "test1","_type": "books","_id": "1","_version": 1,"_seq_no": 0,"_primary_term": 1,"found": true,"_source": {"name": "three days to see","author": "Daniel Defoe"} }更新文檔
使用POST命令,在ID后面加_update,并把需要修改的內(nèi)容放入doc屬性中
示例:更新test1 索引下的books類(lèi)型中保存標(biāo)識(shí)為 1 的文檔的內(nèi)容。
請(qǐng)求:
POST /test1/books/1/_update {"doc" : {"name":"three days to see","author" : "Daniel Defoe","country" : "England"} }響應(yīng):
{"_index": "test1","_type": "books","_id": "1","_version": 2,"result": "updated","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 1,"_primary_term": 1 }刪除文檔和索引
刪除使用DELETE命令
示例:刪除文檔/test1/books/1
請(qǐng)求:
DELETE /test1/books/1響應(yīng):
{"_index": "test1","_type": "books","_id": "1","_version": 3,"result": "deleted","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 2,"_primary_term": 1 }示例:刪除索引/test1
DELETE /test1響應(yīng):
{"acknowledged": true }Search
為了方便測(cè)試,可以從官網(wǎng)導(dǎo)入測(cè)試數(shù)據(jù)
測(cè)試數(shù)據(jù)
查詢(xún)方式
ES支持兩種查詢(xún)方式,一種是直接在URL后加上參數(shù),另一種是在URL后加上JSON格式的請(qǐng)求體。
示例:查找到收入最高的十條記錄
URL + 參數(shù)
常用的參數(shù)如下
- q:用于指定搜索的關(guān)鍵詞。
- from & size:類(lèi)似于SQL中的offset和limit。
- sort:對(duì)結(jié)果排序,默認(rèn)為降序。
- _source:指定想要返回的屬性。
URL + QueryDSL
GET /test_data/_search {"query": {"match_all" : {} },"sort" : [{"balance" : "desc"}],"from" : 0,"size" : 10 }雖然URL+參數(shù)的寫(xiě)法非常簡(jiǎn)潔,但是隨著邏輯的復(fù)雜化,其可讀性也越來(lái)越差,所以通常都會(huì)使用URL + QueryDSL的格式。
match 匹配
match 匹配查詢(xún)
無(wú)論你在任何字段上進(jìn)行的是全文搜索還是精確查詢(xún),match 查詢(xún)是你可用的標(biāo)準(zhǔn)查詢(xún)。
對(duì)于not_analyzed的字段,match能做到精確查詢(xún),而對(duì)于analyzed的字段,match能做到匹配查詢(xún)(全文搜索)。
示例:查找所有年齡為25歲的記錄(精確查詢(xún))
請(qǐng)求:
GET /test_data/_search {"query":{"match" : {"age": 25} } }示例:查詢(xún)所有地址與976 Lawrence Street相關(guān)的記錄(全文搜索)
請(qǐng)求:
GET /test_data/_search {"query":{"match" : {"address": "976 Lawrence Street"} } }match_all 全部匹配
match_all 用于查詢(xún)所有文檔。在沒(méi)有指定查詢(xún)方式時(shí),它是默認(rèn)。
示例:查詢(xún)年齡最小的十條記錄
請(qǐng)求:
GET /test_data/_search {"query": {"match_all" : {} },"sort" : [{"age" : "asc"}],"from" : 0,"size" : 10 }match_phase 短語(yǔ)匹配
match_phase用于進(jìn)行短語(yǔ)的匹配,它查詢(xún)時(shí)并不是像term一樣不進(jìn)行分詞直接查詢(xún),而是借助分析器返回的查詢(xún)?cè)~的相對(duì)順序以及偏移量來(lái)做判斷——滿(mǎn)足所有查詢(xún)?cè)~且順序完全相同的記錄才會(huì)被匹配上。
示例:地址包含502 Baycliff Terrace的記錄
請(qǐng)求:
GET /test_data/_search {"query":{"match_phase" : {"address": "502 Baycliff Terrace"} } }multi_match 多字段匹配
multi_match 可以在多個(gè)字段上執(zhí)行相同的 match 查詢(xún)。
示例:查找city或address字段中包含Dixie或Street的記錄。
請(qǐng)求:
GET /test_data/_search {"query":{"multi_match":{"query":"Dixie Street","fields":["city","address"]}} }term 精確查詢(xún)
term即直接在倒排索引中查詢(xún),也就是精確查找,不進(jìn)行分詞器分析,文檔中必須包含整個(gè)搜索的詞匯。
term和match的區(qū)別:
- match是經(jīng)過(guò)分析處理的,查詢(xún)?cè)~先被文本分析器處理后再進(jìn)行查詢(xún)。所以根據(jù)不同的文本分析器,分析出
的結(jié)果也會(huì)不同。
- term是不經(jīng)過(guò)分析處理的,直接去倒排索引查找精確的值。
由于text字段會(huì)被文本分析器處理,所以通常全文檢索字段用match,其他非text字段(not_analyzed)匹配用term。
GET /test_data/_search {"query": {"term": {"address": "Street"}} }// 雖然文檔中存在”702 Quentin Street“,但是由于文本分析器默認(rèn)會(huì)轉(zhuǎn)為小寫(xiě),無(wú)法搜到任何數(shù)據(jù)布爾查詢(xún)(復(fù)合查詢(xún))
借助布爾查詢(xún)可以實(shí)現(xiàn)如SQL中(and、or、!=)等邏輯條件的判斷,并且可以合并任何其他查詢(xún)語(yǔ)句,包括復(fù)合語(yǔ)句。復(fù)合語(yǔ)句之間可以相互嵌套,可以表達(dá)復(fù)雜的邏輯。
- must(and):文檔必須匹配這些條件才能被包含進(jìn)來(lái)。(影響相關(guān)性得分)
- must_not(not):文檔必須不匹配這些條件才能被包含進(jìn)來(lái)。(不影響相關(guān)性得分)
- should(or):如果滿(mǎn)足這些語(yǔ)句中的任意語(yǔ)句,將增加得分 。(用于修正相關(guān)性得分)
示例:查找年齡不等于18的地址包含Street的男性,且優(yōu)先展示居住在30歲以上的的記錄
請(qǐng)求:
GET /test_data/_search {"query":{"bool":{"must":[{"match":{"address":"Street"}},{"match":{"gender":"M"}}],"must_not":[{"match":{"age":"18"}}],"should":[{"range":{"age":{"gt":30}}}]}} }Filter 過(guò)濾器
Filter通常搭配布爾查詢(xún)一起使用,用于過(guò)濾出所有滿(mǎn)足Filter的記錄,不影響相關(guān)性得分。
示例:查找年齡在30~60之間的記錄
請(qǐng)求:
GET /test_data/_search {"query":{"bool":{"filter":[{"range":{"age":{"gte":30,"lte":60}}}]}} }Aggregations 聚合
要掌握聚合,你只需要明白兩個(gè)主要的概念:
- 桶(Buckets):滿(mǎn)足特定條件的文檔的集合
- 指標(biāo)(Metrics):對(duì)桶內(nèi)的文檔進(jìn)行統(tǒng)計(jì)計(jì)算
翻譯成SQL的形式來(lái)理解的話:
SELECT COUNT(1),MAX(balance) FROM table GROUP BY gender;桶在概念上類(lèi)似于 SQL 的分組(GROUP BY,如上面的GROUP BY gender),而指標(biāo)則類(lèi)似于 COUNT() 、 SUM() 、 MAX() 等統(tǒng)計(jì)方法,如MAX(balance)。
聚合的語(yǔ)法如下:
"aggregations" : {"<聚合名稱(chēng) 1>" : {"<聚合類(lèi)型>" : {<聚合體內(nèi)容>}[,"元數(shù)據(jù)" : { [<meta_data_body>] }]?[,"aggregations" : { [<sub_aggregation>]+ }]?}["聚合名稱(chēng) 2>" : { ... }]* }示例:按照性別進(jìn)行分組,計(jì)算平均年齡和最高收入
請(qǐng)求:
GET /test_data/_search {"query":{"match_all": {}},"aggs":{"group_gender":{"terms":{"field":"gender"},"aggs":{"avg_age":{"avg":{"field":"age"}},"max_balance":{"max":{"field":"balance"}}}}},"size":0 }總結(jié)
以上是生活随笔為你收集整理的ElasticSearch探索之路(六)实战:环境搭建、REST、CRUD、Search的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ElasticSearch探索之路(五)
- 下一篇: 现代的缓存设计方案:Window-Tin