Elasticsearch7-基本概念


什么是文檔

Elasticsearch是面向文檔的,文檔是可搜索數據區的最小單元,例如:日志文件中的日志項,一個電影的詳細信息等。在Elasticsearch中文檔被序列化為包含鍵值對的 JSON 對象。 一個  可以是一個字段或字段的名稱,一個  可以是一個字符串,一個數字,一個布爾值, 另一個對象,一些數組值,或一些其它特殊類型諸如表示日期的字符串,或代表一個地理位置的對象:

{
          "GenTime" : """"2019-12-26 09:13:36"""",
          "EventName" : "HTTP_XSS腳本注入",
          "EventID" : "152526081",
          "SerialNum" : "0113211811149999",
          "@timestamp" : "2019-12-26T01:13:36.670Z",
          "deamon" : "IPS",
          "time" : "Dec 26 09:13:36",
          "SMAC" : "f4:15:63:d4:3a:05",
          "EventLevel" : "2",
          "EventsetName" : "All",
          "SecurityID" : "28",
          "SrcPort" : "65320",
          "Action" : "PASS Vsysid=0",
          "syslog5424_pri" : "212",
          "DstIP" : "10.3.160.112",
          "EvtCount" : "1",
          "Protocol" : "TCP",
          "InInterface" : "ge0/3"
}

文檔元數據

元數據是豐富文檔的相關信息

...
{
       "_index" : "ips-event2019.12.26",
        "_type" : "_doc",
        "_id" : "UYHEP28BhfJeQd0SJfMF",
        "_score" : 1.0,
        "_source" : {
          "GenTime" : """"2019-12-26 09:13:36"""",
          "EventName" : "HTTP_XSS腳本注入",
          "EventID" : "152526081",
.....

}
  • _index  文檔所屬索引名稱
  • _type  文檔所屬的類型名
  • _id 文檔唯一id
  • _score 相關性打分
  • _source 文檔的原始數據

什么是索引

索引是文檔的容器,是一類相似文檔的集合

  • Index體現了邏輯空間的概念,每個索引都有自己的mapping定義,用於定義包含的文檔的字段名和字段類型
  • Shard 體現物理空間的概念,索引中的數據分散到各個Shard上

索引的Mapping和Setting

  • Mapping是定義索引中的所有文檔中的字段類型
  • Setting是定義數據的不同分布

常見API使用

以下可以在DevTools中實驗

#查看索引相關信息,可以看到Mapping和Setting的定義
GET movies

#查看索引的文檔總數
GET movies/_count

#查看索引前10條文檔
GET movies/_search
{
  
}

 

節點

master節點

  • 每一個節點啟動后,默認就是mastrt eligible節點(可以設置node.master: flase 禁止)
  • mastrt eligible節點可以參加選主流程,成為master節點
  • 當第一個節點啟動時,它將會把自己選舉成master節點
  • 每一個節點都保存集群狀態,只有master節點才能修改集群的狀態
    • 集群狀態,維護一個集群中的必要信息
      • 所有節點信息
      • 所有索引和其相關的Mapping和Setting信息
      • 分片的路由信息
         

Data節點

  • 可以保存數據的節點,負責保存分片數據,在數據擴展中起到了至關重要的作用

Coordianting 節點

  • 負責接收Clent端的請求,將請求分發到合適的節點,最終把結果匯集到一起
  • 每個節點默認都起到了Coordianting Node的職責

Hot & warm節點

  • 不同硬件配置的Data Node。把熱門索引或者近期索引放在高配置節點(Hot節點)上,反而冷門索引和相對久遠的數據放到低配置節點(warm節點)上。從而節省資源

Machine Learning 節點

  • 用來跑機器學習的job,來發現數據中的異常

 配置節點類型

  • 開發環境中一個節點可以承擔多個角色
  • 生產環境,應該設置單一的角色節點
節點類型 配置參數 默認值
master eligible node.master true
data node.data true
ingest node.ingest true
Coordianting only 每個節點默認都是Coordianting。設置其他類型為false

machine learning

node.ml true(需要enable x-pack)

 

 分片

分片分為兩種,主分片和副本:

主分片用於解決數據水平擴展的問題,通過主分片,可以將數據分布到集群內的所有節點之上

  • 一個分片是一個運行的Lucene實例
  • 主分片數在索引創建時指定,后續不允許修改,除非Reindex

副本用以解決數據高可用的問題,分片是主分片的拷貝

  • 副本分片數,可以動態調整
  • 增加副本數,還可以在一定程度上提高服務的可用性(讀取的吞吐)

 

 查看一個三節點集群的分片和副本的分布情況:

創建一個三分片一副本的索引:

 

 查看分布情況:

 

分片設定

對於生產的分片設定,需要提前設計好容量規划

  • 分片數設置過下
    • 導致后續無法增加節點實現水平擴展
    • 單個分片數據量過大,導致數據重新分片耗時
  • 分片數設置過大,7.0之后,默認主分片是1,解決了over-sharding的問題
    • 影響搜索結果的相關性打分,影響統計結果的准確性
    • 單個節點上過多分片,會導致資源浪費,同時會影響性能

集群監控狀態說明:

GET _cluster/health

{
  "cluster_name" : "Sxp-Ops-ES-Cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 10,
  "active_shards" : 20,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

Green

  • 主分片和副本分配正常

Yellow

  • 主分片全部正常,有副本未能正常分配

Red

  • 有主分片未能分配

文檔的CRUD

Index PUT myindex/_doc/1
Create

PUT myindex/_create/1

POST myindex/_doc(不指定ID 自動生成)

Read GET myindex/_doc/1
Update POST myindex/_update/1
Delete  DELETE myindex/_doc/1

 

創建文檔

#創建文檔POST方法
POST jaxzhai/_doc
{
  "user": "jaxzhai",
  "Postdate":"20191226T20:23",
  "message":"This test create doc"
}

#指定ID存在 就報錯
PUT jaxzhai/_doc/1?op_type=create
{
    "user": "jax",
  "Postdate":"20191226T20:26",
  "message":"This test create doc"
}

獲取一個文檔

#獲取一個文檔,通過ID
GET jaxzhai/_doc/1

執行結果

{
  "_index" : "jaxzhai",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "user" : "jax",
    "Postdate" : "20191226T20:26",
    "message" : "This test create doc"
  }
}

PUT更新一下文檔 通過ID

PUT jaxzhai/_doc/1
{
  "user": "zhaikun"
}
#執行結果
{
  "_index" : "jaxzhai",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

我們看到version發生變化

源文檔增加字段

#增加字段
POST jaxzhai/_update/1/
{
  "doc":{
    "postdate":"20191226T20:34",
    "message":"This test update"
  }
}

#執行結果
{
  "_index" : "jaxzhai",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

#GET結果
{
  "_index" : "jaxzhai",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "_seq_no" : 3,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "user" : "zhaikun",
    "postdate" : "20191226T20:34",
    "message" : "This test update"
  }
}

 BULK API

BULK API是一次調用中執行多種操作,這樣節省網絡開銷

支持以下4種操作:

  • Create
  • Update
  • Index
  • Delete

可以在URI中指定Index 也可以在請求的Playload中進行

操作中單條失敗,並不會影響其他操作

返回結果包含每條執行結果

#Bulk
POST _bulk
{"index":{"_index": "test","_id":"1"}}
{"field1":"v1"}
{"delete":{"_index": "test","_id":"2"}}
{"create":{"_index": "test2","_id":"3"}}
{"field1":"v3"}
{"update":{"_index": "test","_id":"1"}}
{"doc":{"field2":"v2"}}
#執行結果
{
  "took" : 184,
  "errors" : false,
  "items" : [
    {
      "index" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "delete" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "2",
        "_version" : 1,
        "result" : "not_found",
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 404
      }
    },
    {
      "create" : {
        "_index" : "test2",
        "_type" : "_doc",
        "_id" : "3",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "update" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_version" : 2,
        "result" : "updated",
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 1,
        "status" : 200
      }
    }
  ]
}

批量讀取 mget

GET /_mget
{
  "docs":[
    {
      "_index": "test",
      "_id": "1"
    },
    {
      "_index": "test",
      "_id": "2"
    }
    ]
}
#執行結果
{
  "docs" : [
    {
      "_index" : "test",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 2,
      "_seq_no" : 2,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {
        "field1" : "v1",
        "field2" : "v2"
      }
    },
    {
      "_index" : "test",
      "_type" : "_doc",
      "_id" : "2",
      "found" : false
    }
  ]
}

 常見錯誤返回

問題 原因
無法連接 網絡故障或集群掛了
連接無法關閉 網絡故障或節點錯誤
429 集群過於繁忙
4xx 請求體格式錯誤
500 集群內部錯誤

 

 URISearch

#URI查詢
#查詢2012,並查詢結果里有df=title
GET /movies/_search?q=2012&df=title
{
  "profile": "true"
}
#泛查詢
GET /movies/_search?q=2012
{
  "profile": "true"
}

#指定字段查詢
GET /movies/_search?q=title:2012
{
  "profile": "true"
}

 指定指端 vs 泛查詢

  •  q=title:2012 / q=2012

Term vs Phrase

  • Beautiful Mind 等效  Beautiful 或者  Mind(兩者有一 既返回)
  • "Beautiful Mind" 等效  Beautiful AND  Mind。(兩者都存在才能返回) Phrase查詢,要保持先后順序

分組 vs 引號

  • title:(Beautiful AND Mind)
  • title="Beautiful Mind"
#使用引號,Phrase查詢
GET /movies/_search?q=title:"Beautiful Mind"
{
  "profile": "true"
}

#查詢結果,可以看到查詢出一條,查詢type是PhraseQuery
{
  "took" : 11,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 13.68748,
    "hits" : [
      {
        "_index" : "movies",
        "_type" : "_doc",
        "_id" : "4995",
        "_score" : 13.68748,
        "_source" : {
          "title" : "Beautiful Mind, A",
          "genre" : [
            "Drama",
            "Romance"
          ],
          "year" : 2001,
          "@version" : "1",
          "id" : "4995"
        }
      }
    ]
  },
  "profile" : {
    "shards" : [
      {
        "id" : "[ybtUpGB4StCgJIP3Rp05Xg][movies][0]",
        "searches" : [
          {
            "query" : [
              {
                "type" : "PhraseQuery",
                "description" : """title:"beautiful mind"""",
                "time_in_nanos" : 6930465,
                "breakdown" : {
                  "set_min_competitive_score_count" : 0,
                  "match_count" : 1,
                  "shallow_advance_count" : 0,
                  "set_min_competitive_score" : 0,
                  "next_doc" : 27865,
                  "match" : 69781,
                  "next_doc_count" : 1,
                  "score_count" : 1,
                  "compute_max_score_count" : 0,
                  "compute_max_score" : 0,
                  "advance" : 293949,
                  "advance_count" : 2,
                  "score" : 8335,
                  "build_scorer_count" : 4,
                  "create_weight" : 2263785,
                  "shallow_advance" : 0,
                  "create_weight_count" : 1,
                  "build_scorer" : 4266740
                }
              }
            ],
            "rewrite_time" : 4433,
            "collector" : [
              {
                "name" : "CancellableCollector",
                "reason" : "search_cancelled",
                "time_in_nanos" : 44976,
                "children" : [
                  {
                    "name" : "SimpleTopScoreDocCollector",
                    "reason" : "search_top_hits",
                    "time_in_nanos" : 34993
                  }
                ]
              }
            ]
          }
        ],
        "aggregations" : [ ]
      }
    ]
  }
}
#查找美麗心靈,Mind 為泛查詢
GET /movies/_search?q=title:Beautiful Mind
{
  "profile": "true"
}

#使用分組,Bool  (類似把口號內容作為一個詞組查詢)
GET /movies/_search?q=title:(Beautiful Mind)
{
  "profile": "true"
}

布爾操作

  • AND/OR/NOT或者&&/||/!
    • 必須大寫
    • title:(matrix NOT reloaded)

分組

  • + 表示must
  • - 表示must_not
  • title:(matrix - reloaded)
#查找美麗心靈 
#"type" : "BooleanQuery",
#"description" : "+title:beautiful +title:mind",(同時滿足beautiful mind)
GET /movies/_search?q=title:(Beautiful AND Mind)
{
  "profile": "true"
}

#查找美麗心靈 
#"type" : "BooleanQuery",
#"description" : "title:beautiful -title:mind",(滿足必須包含beautiful 不能包含mind)
GET /movies/_search?q=title:(Beautiful NOT Mind)
{
  "profile": "true"
}

范圍查詢

  • 區間表示:[]閉區間,{}開區間
    • year:{2019 TO 2018}
    • year:[* TO 2018]

算符符號

  • year:>2010
  • year:(+2010 && <=2018)
  • year:(+>2010 +<2018)
#范圍查詢,區間寫法,數學寫法
GET /movies/_search?q=year:>=1980
{
  "profile": "true"
}

 通配符查詢(通配符查詢效率低下,占用內存大,不建議使用,特別是放在最前面)

  • ?代表一個字符,*代表0或多個字符
    • title:mi?d
    • title:be*

正則表達式

  • title:[bt]oy

模糊匹配和近似查詢

  • title:befutifl~1
  • title:"lord rings"~2
#模糊匹配  近似度匹配
GET /movies/_search?q=title:beautifl~1
{
  "profile": "true"
}

GET /movies/_search?q=title:"Lord Rings"~2
{
  "profile": "true"
}

Request Body Search

POST /movies/_search
{
  "from":10,
  "size":20,
  "query": {
    "match_all": {}
  }
}
  • 將語句通過HTTP Request Body 發送給Elasticsearch
  • Query DSL
  • from和size 達到分頁效果
  • sort 排序
  • _source filtering 顧慮只需要的字段
POST /movies/_search
{
  "_source": ["title","year"], 
  "from":10,
  "size":20,
  "query": {
    "match_all": {}
  }
}

 

 查詢方式

POST /movies/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Last Christmas",
        "operator": "and"
      }
    }
  }
}

POST /movies/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "one love"
        , "slop": 1
      }
    }
  }

 

Mapping

什么是Mapping

Mapping 類似數據庫中的schema的定義,作用如下:

  • 定義索引中的字段和名稱
  • 定義字段的數據類型,例如:字符串、數字、布爾
  • 字段、倒排索引的相關配置

Mapping會把Json文檔映射成Lucene所需的扁平格式

一個Mapping屬於一個索引的Type

  • 每一個文檔都屬於一個type
  • 一個type有一個mapping定義
  • 7.0開始,不需要在mapping定義中指定type信息

字段數據類型

簡單類型

  • Text/Keyword
  • Data
  • Integer/Floating
  • Boolean
  • IPv4 & IPv6

復雜類型

  • 對象類型 / 嵌套類型

特殊類型

  • geo_point & geo——shape / percolator

什么是Dynamic Mapping

  • 在寫入文檔的時候,如果索引不存在,會自動創建索引
  • Dynamic Mapping 的機制,使得我們無需手動定義Mappings,Elasticsearch會自動根據文檔信息,推算出字段類型
  • 但是有時候推算的不正確,例如地理位置信息
  • 當類型設置不對時,會導致一些功能無法正常運行,例如Range查詢

 如何自動生成的類型:

PUT mapping_test/_doc/1
{
  "uid":"123",
  "isvip":false,
  "isadmin":"true",
  "age":19,
  "heigh":180
}
GET mapping_test/_mapping
 {
  "mapping_test" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "heigh" : {
          "type" : "long"
        },
        "isadmin" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "isvip" : {
          "type" : "boolean"
        },
        "uid" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

能否更改Mapping字段

新增字段:

  • Dynamic 設置為true時,一旦有新字段的文檔寫入,Mapping同時也會被更新
  • Dynamic 設置為false時,Mapping不會被更新,新增字段的數據無法被索引,但是信息會出現在_source中。
  • Dynamic 設置為strict,文檔寫入失敗

對已有的字段

  • Lucene實現的倒排索引,一旦生成后,就不允許修改

如果希望改變字段類型,必須Reindex API,重建索引

#默認Mapping支持Dynamic,寫入的文檔中加入新的字段
#寫入一個新索引
PUT mapping_dynamic_test/_doc/1
{
  "field":"somevalue"
}
#查看是否可以被索引(可以)
POST mapping_dynamic_test/_search
{
  "query": {
    "match": {
      "field": "somevalue"
    }
  }
}
#修改dynamic的值為false
PUT mapping_dynamic_test/_mapping
{
  "dynamic":false
}
#新增字段anotherField
PUT mapping_dynamic_test/_doc/10
{
  "anotherField":"sv"
}
#查看是否可以被索引(不可以,但不報錯)
POST mapping_dynamic_test/_search
{
  "query": {
    "match": {
      "anotherField": "sv"
    }
  }
}

#查看mapping配置(沒有anotherField字段)
GET mapping_dynamic_test/_mapping

#修改dynamic的值為strict
PUT mapping_dynamic_test/_mapping
{
  "dynamic": "strict"
}
#再嘗試加入一個字段(寫入數據錯誤,400)
PUT mapping_dynamic_test/_doc/10
{
  "lastfield":"v3"
}

 

如何顯示定義一個mapping

 為了減少輸入量,並減少錯誤,可以依照下面幾步操作:

  • 創建一個臨時索引,寫入一些樣本數據
  • 通過訪問Mapping API 獲得該臨時文件的動態mapping定義
  • 修改后,使用該配置創建所需的索引
  • 刪除臨時索引

Index 控制字段是否被索引,默認是true,如果設置成false,該字段不可索引。

 

什么是Index Template

Index Template 幫助設定mapping和setting,並按照一定的規則自動匹配到新建索引上

  • 模板僅在索引被新創建時使用,修改模板不是影響已創建的索引
  • 可以設定多個索引模板,這些設置可以“合並”在一起
  • 可以指定“order”的數值,控制“合並中”的過程

工作方式:

當一個索引被創建時:

  • 應用Elasticsearch默認的mapping和setting
  • 應用order數值低Index Template 中的設定
  • 應用order數值高的Index Template模板中,之前的會被覆蓋
  • 應用索引被創建時,用戶指定的Settings和Mappings,並覆蓋之前的模板中的設定
##Index Template 測試(默認方式)
PUT template_test/_doc/1
{
  "Sn":"1",
  "Sd":"2019/12/27"
}
#查看 sd正確推斷成date類型,而Sn是text類型
GET template_test/_mapping
#創建兩個模板
PUT _template/template_default
{
  "index_patterns":["*"],
  "order":0,
  "version":1,
  "settings":{
    "number_of_shards":1,
    "number_of_replicas":1
  }
}
PUT _template/template_test
{
  "index_patterns":["test*"],
  "order":1,
  "version":1,
  "settings":{
    "number_of_shards":1,
    "number_of_replicas":2
  },
  "mappings":{
    "date_detection": false,
    "numeric_detection": true
  }
}
#查看Index Template
GET /_template/template_default
GET _template/temp*

#寫入一個test開頭的index
PUT testtemplate/_doc/1
{
  "Sn":"1",
  "Sd":"2019/12/27"
}
#我們發現原本sd轉換日期類型的沒有轉換,而sn轉換成長整形
GET testtemplate/_mapping
#因為我們之前設置成2副本,查看settings,副本數為2
GET testtemplate/_settings

什么是Dynamic Template

根據Elasticsearch識別的數據類型,結合字段名稱,來動態設定字段類型

  • 所有字符串類型都設成keyword,或者關閉keyword字段
  • is開頭的字段都設置成boolean
  • long_開頭的都設置成long類型
#創建Dynamic Template
PUT myindex
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_name": {
          "path_match": "name.*",
          "path_unmatch": "*.middle",
          "mapping": {
            "tyep": "text",
            "copy_to": "full_name"
          }
        }
      }
    ]
  }
}
PUT myindex/_doc/1
{
  "name":{
    "first":"zhai",
    "middle":"jax",
    "last": "anni"
  }
}

GET myindex/_search?q=full_name:zhai

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM