ElasticSearch學習
- 2022 年 8 月 8 日
- 筆記
- elasticsearch
ElasticSearch(中文官網)
之前在蟹老闆手下干命的日子裡,我給公司搭建了一套LEK,收集我們測試環境、生成環境,每個服務運行狀態,以及bug及時定位,現在在新東家ElasticSearch除了做日誌收集,還會保存業務數據文檔,提升查詢效率。
在上次寫的「使用ElasticSearch、Kibana、Docker 進行日誌收集」 介紹了如何進行環境搭建,以及日誌數據收集。
Elasticsearch 基本操作
dev_tools命令執行面板
dev_tools
是Kibana
提供的命令執行面板,當然大家也會看到其他人使用Postman調用ElasticSearch
介面,但是我還是喜歡使用dev_tools
(如果安裝了Kibana
就可以使用,也可以使用Postman)
索引操作
關於索引操作我列舉了一些常用的api,大家可以根據我給出的文檔連接詳細的閱讀文檔,拋磚引你。
創建索引
索引必須小寫,不支援大寫,重複創建索引會報錯
# 創建索引
PUT /test_dawn
{
}
# 返回結果
# 注意:創建索引庫的分片數默認 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默認 5 片
{
# 【響應結果】true 操作成功
"acknowledged" : true,
# 【分片結果】分片操作成功
"shards_acknowledged" : true,
# 【索引名稱】
"index" : "test_dawn"
}
查看所有索引詳細資訊
GET /_cat/indices?v
名稱 | 含義 |
---|---|
health | 當前伺服器健康狀態,green(集群完整),yellow(單點正常,集群不完整),red(單點異常) |
status | 索引打開、關閉 |
index | 索引名 |
uuid | 索引統一編號 |
pri | 主分片數量 |
rep | 副本數量 |
docs.count | 可用文檔數量 |
docs.deleted | 文檔刪除狀態(邏輯刪除) |
store.size | 主分片和副分片整體占空間大小 |
pri.store.size | 主分片占空間大小 |
查看單個索引
# 查看test_dawn索引資訊
GET /test_dawn
# 返回參數
{
# 索引名
"test_dawn" : {
# 別名
"aliases" : { },
# 映射
"mappings" : { },
# 設置
"settings" : {
"index" : {
# 創建時間
"creation_date" : "1659450485862",
# 主分片數量
"number_of_shards" : "1",
# 副分片數量
"number_of_replicas" : "1",
# 唯一標識
"uuid" : "Gsu7-arFRJmju1p3_5wSOQ",
"version" : {
"created" : "7090299"
},
# 名稱
"provided_name" : "test_dawn"
}
}
}
}
刪除索引
刪除不存在的索引會報錯
DELETE /test_dawn
創建映射
提醒:索引不存在會報錯
創建映射就相當於,創建表需要添加欄位、欄位類型的操作(後面講到文檔操作的時候我們也可以直接添加屬性,ElasticSearc
會自動推斷我們添加的屬性使用什麼類型)ElasticSearc
屬性類型
# 創建映射
PUT /test_dawn/_mapping
{
"properties":{
"name": {
# 支援分詞,但是不支援分組
"type": "text",
# 欄位會被索引,則可以用來進行搜索,反之
"index": true,
# 是否將數據進行獨立存儲,默認為 false
"store": false,
# 分詞器只能在text 類型下使用
# 指定該屬性使用那個分詞器
"analyzer": "ik_max_word"
},
"age": {
"type": "integer",
"index": true,
"store": false
},
"gender": {
# 不能分詞,數據會作為完整欄位進行匹配,支援分組操作
"type": "keyword",
"index": true,
"store": false
}
}
}
查看映射
# 查看映射
GET /test_dawn/_mapping
store 和 _source 對比
默認情況下,欄位值被索引以使它們可搜索,但它們不被存儲。這意味著可以查詢該欄位,但無法檢索原始欄位值。
通常這無關緊要。欄位值已經 是默認存儲的_source欄位的一部分。如果您只想檢索單個欄位或幾個欄位的值,而不是整體_source,則可以通過 源過濾來實現。
在某些情況下,它對一個領域是有意義store的。例如,如果您有一個包含 a title、 adate和一個非常大的content 欄位的文檔,您可能只想檢索 thetitle和 thedate而不必從一個大欄位中提取這些欄位_source
文檔操作
添加文檔
# 添加一個文檔
POST /test_dawn/_doc
{
"title":"少年說",
"category":"青春",
"images":"//baidu.com"
}
# 返回參數
{
# 索引
"_index" : "test_dawn",
# 文檔類型,默認是_doc 在老版中有應用場景,不過到8.0版本就開始淡化、拋棄
"_type" : "_doc",
# 文檔唯一id 可以手動指定,或者自動生成
"_id" : "evQSaYIBhcAYjjJxxtf3",
# 當前文檔本版,每次對該文檔進行操作會+1
"_version" : 1,
# 當前操作類型,還有update
"result" : "created",
# 分片
"_shards" : {
# 分片總數量
"total" : 2,
# 分片成功數量
"successful" : 1,
# 分片失敗數量
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
手動指定Id
查看文檔
# 查看文檔
GET /test_dawn/_doc/1234567890
# 返回參數
{
"_index" : "test_dawn",
"_type" : "_doc",
"_id" : "1234567890",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
# 如果找到了為true
"found" : true,
"_source" : {
"title" : "少年說",
"category" : "青春",
"images" : "//baidu.com"
}
}
修改文檔
剛才我們指定id創建文檔,還有一個作用如果該id 存在就修改文檔(全欄位覆蓋修改)
# 指定id 或者 如果該id 存在就修改文檔(全欄位覆蓋修改)
POST /test_dawn/_doc/1234567890
{
"title":"少年說",
"category":"青春"
}
使用該命令一定要注意注意,它是覆蓋式的(工作事小,老婆跑了事大)
指定欄位更新
刪除文檔
# 刪除文檔
DELETE /test_dawn/_doc/1234567890
條件刪除
# 條件刪除
POST /test_dawn/_delete_by_query
{
"query": {
"match": {
"title": "少年說"
}
}
}
查詢DSL
Elasticsearch 提供了基於 JSON 的完整 Query DSL(Domain Specific Language)來定義查詢。將查詢 DSL 視為查詢的 AST(抽象語法樹)由兩種類型的子句組成:
- 葉查詢子句
葉查詢子句在特定欄位中查找特定值,例如 match、term或 range查詢。這些查詢可以單獨使用。 - 複合查詢子句
複合查詢子句包裝其他葉或複合查詢,並用於以邏輯方式組合多個查詢(例如 boolordis_max查詢),或改變它們的行為(例如constant_score查詢)。
查詢子句的行為不同,具體取決於它們是在 查詢上下文還是過濾器上下文中使用。
允許昂貴的查詢
某些類型的查詢由於它們的實現方式,通常會執行緩慢,這會影響集群的穩定性。這些查詢可以分類如下:
-
需要進行線性掃描以識別匹配的查詢:
-
前期成本高的查詢:
-
每個文檔成本可能較高的查詢:
match查詢
match
查詢是執行全文搜索的標準查詢,包括模糊匹配選項。
# 全文搜索的標準查詢,包括模糊匹配
GET /test_dawn/_search
{
"query": {
"match": {
"title": "少年"
}
}
}
term查詢
您可以使用term查詢根據價格、產品 ID 或用戶名等精確值查找文檔。
避免使用欄位term查詢。text
默認情況下,Elasticsearch 會在分析text過程中更改欄位的值。這會使查找欄位值的精確匹配變得困難。text
要搜索text欄位值,請改用match查詢。
# 精確查詢
GET /test_dawn/_search
{
"query": {
"term": {
"_id": "vxvNeIIB7oKD63DUcC9h"
}
}
}
複合查詢
複合查詢包裝其他複合查詢或葉查詢,以組合它們的結果和分數,改變它們的行為,或者從查詢切換到過濾上下文。
用於組合多個葉或複合查詢子句的默認查詢,如 must
或子句。and
子句將 它們的分數組合在一起——匹配的子句越多越好——而and子句在過濾上下文中執行。 should
must_not
filter
mustshould
must_notfilter
返回匹配positive
查詢的文檔,但減少也匹配negative
查詢的文檔的分數。
包裝另一個查詢,但在過濾器上下文中執行它的查詢。所有匹配的文檔都被賦予相同的「常量」 _score
。
接受多個查詢並返回與任何查詢子句匹配的任何文檔的查詢。雖然bool查詢結合了所有匹配查詢的分數,但dis_max
查詢使用單個最佳匹配查詢子句的分數。
使用函數修改主查詢返回的分數,以考慮流行度、新近度、距離或使用腳本實現的自定義演算法等因素。
bool查詢
匹配與其他查詢的布爾組合匹配的文檔的查詢。
bool
查詢映射到Lucene BooleanQuery
。它是使用一個或多個布爾子句構建的,每個子句都有一個類型的出現。出現類型有:
名稱 | 描述 |
---|---|
must | 子句(查詢)必須出現在匹配的文檔中,並將有助於得分。 |
filter | 子句(查詢)必須出現在匹配的文檔中。然而,與 must查詢的分數不同,將被忽略。過濾器子句在過濾器上下文中執行,這意味著忽略評分並考慮快取子句。 |
should | 子句(查詢)應該出現在匹配的文檔中。 |
must_not | 子句(查詢)不得出現在匹配的文檔中。子句在過濾器上下文中執行,這意味著忽略評分並考慮快取子句。因為忽略了評分,0所以返回所有文檔的評分。 |
該bool查詢採用更多匹配更好的方法,因此每個匹配must或should子句的分數將加在一起以提供_score每個文檔的最終結果。
# 符合查詢,其實我們只要記住:must(必須 )、must_not(必須不)、should(應該)的方式進行組合就可以了
GET /test_dawn/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"_id": "vxvNeIIB7oKD63DUcC9h"
}
}
],
"should": [
{
"match": {
"title": "少年說"
}
}
]
}
}
}
總結
- 本次我主要列舉了,我再項目開發中比較常見的命令,當然這個只是官方文檔中的一些部分知識點,內容有很多可以先不必全部死記理解命令的使用場景即可。
- 之前使用ELK收集日誌資訊,我都是使用的
Kibana
的可視化介面查詢的,但是在實際開發中習慣命令行查詢會靈活很多。 - 本篇主要介紹的是原生命令行操作
ElasticSearch
,下一篇我們就要使用程式碼操作Elasticsearch Clients地址。