文章目錄

  • 一、索引操作
  • 1、創建索引
  • 2、查詢索引
  • 3、刪除索引
  • 4、ES倒排索引
  • 5、文檔映射Mapping
  • (1)字段類型
  • (2)映射
  • (3)動靜態映射
  • (4)Dynamic Mapping類型自動識別
  • (5)後期更改Mapping的字段類型
  • (6)對已有字段的mapping修改
  • (7)常用Mapping參數配置
  • (7.1)index
  • (7.2)index_options
  • (7.3)null_value
  • (7.4)copy_to
  • (8)Index Template
  • (9)lndex Template的工作方式
  • (10)Dynamic Template

一、索引操作

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index.html

1、創建索引

索引命名必須小寫,不能以下劃線開頭 格式: PUT /索引名稱

#創建索引
PUT /es_db
#創建索引時可以設置分片數和副本數
PUT /es_db
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
#修改索引配置
PUT /es_db/_settings
{
"index" : {
"number_of_replicas" : 1
}
}

Elasticsearch 使用 RESTful API 操作索引_ci

2、查詢索引

格式: GET /索引名稱

#查詢索引
GET /es_db
#es_db是否存在
HEAD /es_db

Elasticsearch 使用 RESTful API 操作索引_ci_02

3、刪除索引

格式: DELETE /索引名稱

DELETE /es_db

4、ES倒排索引

當數據寫入 ES 時,數據將會通過 分詞 被切分為不同的 term,ES 將 term 與其對應的文檔列表建立一種映射關係,這種結構就是 倒排索引。如下圖所示:

Elasticsearch 使用 RESTful API 操作索引_倒排索引_03


為了進一步提升索引的效率,ES 在 term 的基礎上利用 term 的前綴或者後綴構建了 term index, 用於對 term 本身進行索引,ES 實際的索引結構如下圖所示:

Elasticsearch 使用 RESTful API 操作索引_字段_04


這樣當我們去搜索某個關鍵詞時,ES 首先根據它的前綴或者後綴迅速縮小關鍵詞的在 term dictionary 中的範圍,大大減少了磁盤IO的次數。

單詞詞典(Term Dictionary) :記錄所有文檔的單詞,記錄單詞到倒排列表的關聯關係
常用字典數據結構:

倒排列表(Posting List)-記錄了單詞對應的文檔結合,由倒排索引項組成

倒排索引項(Posting):

文檔ID

詞頻TF–該單詞在文檔中出現的次數,用於相關性評分

位置(Position)-單詞在文檔中分詞的位置。用於短語搜索(match phrase query)

偏移(Offset)-記錄單詞的開始結束位置,實現高亮顯示

Elasticsearch 使用 RESTful API 操作索引_字段_05


Elasticsearch 的JSON文檔中的每個字段,都有自己的倒排索引。 可以指定對某些字段不做索引:

優點︰節省存儲空間

缺點: 字段無法被搜索

5、文檔映射Mapping

(1)字段類型

核心類型:

  • 字符串(string)
    text,keyword
  • 數字類型(Numeric)
    long,integer,short,byte,double,float,half_float,scaled_float
  • 日期類型(Date)
    data
  • 布爾類型(Boolean)
    boolean
  • 二進制類型(binary)
    binary

複合類型:

  • 數組類型(Array)
    Array支持不針對特定的類型
  • 對象類型(Object)
    Object用於單JSON對象
  • 嵌套類型(Nested)
    nested用於JSON對象數組

地理類型(Geo):

  • 地理座標(Geo-points)
    geo_point用於描述經緯度座標
  • 地理圖形(Geo-Shape)
    geo_shape用於描述複雜形狀,如多邊形

特定類型:

  • IP類型
    ip用於描述ipv4和ipv6
  • 補全類型(Completion)
    completion提供自動完成提示
  • 令牌計數類型(Token count)
    token_count用於統計字符串中的詞條數量
  • 附件類型(attachment)
    參考mapper-attachements插件,支持將附件如Microsoft Office格式,Open Document格式,ePub,HTML等等索引為attachment數據類型
  • 抽取類型(Percolator)
    接受特定領域查詢語言(query-dsl)的查詢

多字段:
通常用於為不同目的用不同的方法索引同一個字段。例如,string字段可以映射為一個text字段用於全文檢索,同樣可以映射為一個keyword字段用於排序和聚合。另外,你可以使用standard analyzer,english analyzer,french analyzer來索引一個text字段。
這就是muti-fields的目的。大多數的數據類型通過fields參數來支持muti-fields。

(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

mapping其實不需要手動定義,在插入數據時會自動猜測映射類型:
布爾型:trye或者false : boolean
整數:123 : long
浮點數:123.45 : double
字符串,有效日期:2022-06026 : date
字符串:learn elasticSearch : string

(3)動靜態映射

Mapping類似數據庫中的schema的定義,作用如下:
定義索引中的字段的名稱
定義字段的數據類型,例如字符串,數字,布爾等
字段,倒排索引的相關配置(Analyzer)
ES中Mapping映射可以分為動態映射和靜態映射

動態映射:
在關係數據庫中,需要事先創建數據庫,然後在該數據庫下創建數據表,並創建表字段、類型、長度、主鍵等,最後才能基於表插入數據。而Elasticsearch中不需要定義Mapping映射(即關係型數據庫的表、字段等),在文檔寫入Elasticsearch時,會根據文檔字段自動識別類型,這種機制稱之為動態映射

靜態映射:
靜態映射是在Elasticsearch中也可以事先定義好映射,包含文檔的各字段類型、分詞器等,這種方式稱之為靜態映射。

動態映射(Dynamic Mapping)的機制,使得我們無需手動定義Mappings,Elasticsearch會自動根據文檔信息,推算出字段的類型。但是有時候會推算的不對,例如地理位置信息。當類型如果設置不對時,會導致一些功能無法正常運行,例如Range查詢

(4)Dynamic Mapping類型自動識別

Elasticsearch 使用 RESTful API 操作索引_字段_06

#刪除原索引
DELETE /user
#創建文檔(ES根據數據類型, 會自動創建映射)
PUT /user/_doc/1
{
"name":"cxf",
"age":32,
"address":"長沙麓谷"
}
#獲取文檔映射
GET /user/_mapping

Elasticsearch 使用 RESTful API 操作索引_倒排索引_07

(5)後期更改Mapping的字段類型

新增加字段
dynamic設為true時,一旦有新增字段的文檔寫入,Mapping 也同時被更新
dynamic設為false,Mapping 不會被更新,新增字段的數據無法被索引,但是信息會出現在_source中
dynamic設置成strict(嚴格控制策略),文檔寫入失敗,拋出異常

Elasticsearch 使用 RESTful API 操作索引_ci_08


對已有字段,一旦已經有數據寫入,就不再支持修改字段定義

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

如果希望改變字段類型,可以利用 reindex API,重建索引

原因:
如果修改了字段的數據類型,會導致已被索引的數據無法被搜索
但是如果是增加新的字段,就不會有這樣的影響

測試:

PUT /user
{
"mappings": {
"dynamic": "strict",
"properties": {
"name": {
"type": "text"
},
"address": {
"type": "object",
"dynamic": "true"
}
}
}
}
# 插入文檔報錯,原因為age為新增字段,會拋出異常
PUT /user/_doc/1
{
"name":"cxf",
"age":32,
"address":{
"province":"湖南",
"city":"長沙"
}
}

dynamic設置成strict,新增age字段導致文檔插入失敗

Elasticsearch 使用 RESTful API 操作索引_字段_09

# 修改dynamic後再次插入文檔成功
#修改daynamic
PUT /user/_mapping
{
"dynamic":true
}
# 添加新的字段映射
# 解釋:index:false,默認所有的字段的index都是true,為false是不會被索引的不會被查出來,也就是相當於一個冗餘字段。
PUT /my-index/_mapping
{
"properties": {
"employee-id": {
"type": "keyword",
"index": false
}
}
}

(6)對已有字段的mapping修改

具體方法:
1)如果要推倒現有的映射, 你得重新建立一個靜態索引
2)然後把之前索引裏的數據導入到新的索引裏
3)刪除原創建的索引
4)為新索引起個別名, 為原索引名

PUT /user2
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"address": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
POST _reindex
{
"source": {
"index": "user"
},
"dest": {
"index": "user2"
}
}
DELETE /user
PUT /user2/_alias/user
GET /user

注意: 通過這幾個步驟就實現了索引的平滑過渡,並且是零停機

也可以使用條件:

Elasticsearch 使用 RESTful API 操作索引_ci_10

(7)常用Mapping參數配置

(7.1)index

index: 控制當前字段是否被索引,默認為true。如果設置為false,該字段不可被搜索

DELETE /user
PUT /user
{
"mappings" : {
"properties" : {
"address" : {
"type" : "text",
"index": false
},
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}
PUT /user/_doc/1
{
"name":"cxf",
"address":"廣州白雲山公園",
"age":30
}
GET /user
GET /user/_search
{
"query": {
"match": {
"address": "廣州"
}
}
}

Elasticsearch 使用 RESTful API 操作索引_字段_11

(7.2)index_options

有四種不同基本的index options配置,控制倒排索引記錄的內容:
docs : 記錄doc id
freqs:記錄doc id 和term frequencies(詞頻)
positions: 記錄doc id / term frequencies / term position
offsets: doc id / term frequencies / term posistion / character offsets

text類型默認記錄postions,其他默認為 docs。記錄內容越多,佔用存儲空間越大

DELETE /user
PUT /user
{
"mappings" : {
"properties" : {
"address" : {
"type" : "text",
"index_options": "offsets"
},
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}

(7.3)null_value

null_value: 需要對Null值進行搜索,只有keyword類型支持設計Null_Value

DELETE /user
PUT /user
{
"mappings" : {
"properties" : {
"address" : {
"type" : "keyword",
"null_value": "NULL"
},
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}
PUT /user/_doc/1
{
"name":"fox",
"age":32,
"address":null
}
GET /user/_search
{
"query": {
"match": {
"address": "NULL"
}
}
}

Elasticsearch 使用 RESTful API 操作索引_字段_12

(7.4)copy_to

copy_to設置:將字段的數值拷貝到目標字段,滿足一些特定的搜索需求。copy_to的目標字段不出現在_source中。

# 設置copy_to
DELETE /address
PUT /address
{
"mappings" : {
"properties" : {
"province" : {
"type" : "keyword",
"copy_to": "full_address"
},
"city" : {
"type" : "text",
"copy_to": "full_address"
}
}
},
"settings" : {
"index" : {
"analysis.analyzer.default.type": "ik_max_word"
}
}
}
PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "長沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "廣東","city": "廣州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵陽"}
GET /address/_search
{
"query": {
"match": {
"full_address": {
"query": "湖南常德",
"operator": "and"
}
}
}
}

(8)Index Template

Index Templates可以幫助你設定Mappings和Settings,並按照一定的規則,自動匹配到新創建的索引之上

模版僅在一個索引被新創建時,才會產生作用。修改模版不會影響已創建的索引
你可以設定多個索引模版,這些設置會被“merge”在一起
你可以指定“order”的數值,控制“merging”的過程

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,
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1
},
"mappings": {
"date_detection": false,
"numeric_detection": true
}
}

(9)lndex Template的工作方式

當一個索引被新創建時:
應用Elasticsearch 默認的settings 和mappings
應用order數值低的lndex Template 中的設定
應用order高的 Index Template 中的設定,之前的設定會被覆蓋
應用創建索引時,用户所指定的Settings和 Mappings,並覆蓋之前模版中的設定

#查看template信息
GET /_template/template_default
GET /_template/temp*
PUT /testtemplate/_doc/1
{
"orderNo": 1,
"createDate": "2022/01/01"
}
GET /testtemplate/_mapping
GET /testtemplate/_settings
PUT /testmy
{
"mappings": {
"date_detection": true
}
}
PUT /testmy/_doc/1
{
"orderNo": 1,
"createDate": "2022/01/01"
}
GET /testmy/_mapping

(10)Dynamic Template

Dynamic Tempate定義在某個索引的Mapping中。

#Dynaminc Mapping 根據類型和字段名
DELETE my_index
PUT my_index/_doc/1
{
"firstName":"Ruan",
"isVIP":"true"
}
GET my_index/_mapping
DELETE my_index
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"strings_as_boolean": {
"match_mapping_type":   "string",
"match":"is*",
"mapping": {
"type": "boolean"
}
}
},
{
"strings_as_keywords": {
"match_mapping_type":   "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
#結合路徑
PUT /my_test_index
{
"mappings": {
"dynamic_templates": [
{
"full_name":{
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping":{
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
PUT /my_test_index/_doc/1
{
"name":{
"first": "John",
"middle": "Winston",
"last": "Lennon"
}
}
GET /my_test_index/_search
{
"query": {
"match": {
"full_name": "John"
}
}
}