天天看點

Elasticsearch 索引的映射配置詳解

Elasticsearch 索引的映射配置詳解

概述

Elasticsearch 與傳統的 SQL資料庫的一個明顯的不同點是,Elasticsearch 是一個 非結構化 的資料庫,或者說是一個 無模式 的資料庫。Elasticsearch 中資料最重要的三要素當屬:索引、類型、文檔,其中索引這個概念非常重要,我們可以粗略地将其類比到傳統SQL資料庫中的 資料表。本文就從 Elasticsearch 的索引映射如何配置開始講起。

注: 本文原載于 My Personal Blog ,歡迎光臨 小站

本文内容腦圖如下:文章共1540字,閱讀本文大約需要5分鐘 !

索引模式映射

建立索引時,可以自定義索引的結構,比如 建立一個儲存使用者資訊資料的

users

索引,其典型的結構如下:

  • id

    :唯一表示符
  • name

    :姓名
  • birthday

    :出生日期
  • hobby

    :愛好

為此我們可以建立一個 json 格式的索引模式映射檔案:users.json

{
    "mappings" : {
        "user" : {
            "properties" : {
                "id" : {
                    "type" : "long",
                    "store" : "yes"
                },
                "name" : {
                    "type" : "string",
                    "store" : "yes",
                    "index" : "analyzed"
                },
                "birthday" : {
                    "type" : "date",
                    "store" : "yes"
                },
                "hobby" : {
                    "type" : "string",
                    "store" : "no",
                    "index" : "analyzed"
                }
                
            }
        }
    }
}           

上面的 json代碼意義如下:

  • 建立一個名稱為

    users

    的 Index
  • 裡面有一個名稱為

    user

    的 Type
  • user

    有四個 field
  • 且每個 field 都有自己的 屬性 定義

然後我們來執行如下指令來建立一個索引:

curl -X PUT http://47.98.43.236:9200/users -d @users.json           

結果如下,索引

users

、類型

user

、以及 四個字段 都已經順利插入:

關于字段的 可選類型,有如下幾種:
  • string

    :字元串
  • number

    :數字
  • date

    :日期
  • boolean

    :布爾型
  • binary

    :二進制
  • ip

    :IP位址
  • token_count

    類型

關于每種類型有哪些 屬性,可參考官方文檔,由于内容太多,此處不再贅述。

分析器的使用

分析器是一種用于 分析資料 或者按照使用者想要的方式 處理資料 的工具,對于 字元串類型 的字段,Elasticsearch 允許使用者自定義分析器。

  • 先來自定義一個分析器
{
  "settings" : {
    "index" : {
      "analysis" : {
        "analyzer" : {
          "myanalyzer" : {
            "tokenizer" : "standard",
            "filter" : [
              "asciifolding",
              "lowercase",
              "myFilter"
            ]
          }
        },
        "filter" : {
          "myFilter" : {
            "type" : "kstem"
          }
        }
      }

    }
  },
    "mappings" : {
        "user" : {
            "properties" : {
                "id" : {
                    "type" : "long",
                    "store" : "yes"
                },
                "name" : {
                    "type" : "string",
                    "store" : "yes",
                    "index" : "analyzed",
                    "analyzer" : "myanalyzer"
                },
                "birthday" : {
                    "type" : "date",
                    "store" : "yes"
                },
                "hobby" : {
                    "type" : "string",
                    "store" : "no",
                    "index" : "analyzed"
                }

            }
        }
    }
}           

上述 json代碼中,使用者定義了一個名為 myanalyzer 的分析器,該分析器包含 一個分詞器 + 三個過濾器,分别如下:

  1. 分詞器:

    standard

  2. 過濾器:

    asciifolding

  3. lowercase

  4. myFilter

    (自定義過濾器,其本質是

    kstem

  • 再來看如何測試和使用自定義的分析器

可以通過類似如下的 Restful接口來測試 analyze API 的工作情況:

curl -X GET 'http://47.98.43.236:9200/users/_analyze?field=user.name' -d 'Cars Trains'           

可見我們輸入的時一行字元串普通

"Cars Trains"

,而輸出為:

car

train

,這說明短語

"Cars Trains"

被分成了兩個詞條,然後全部轉為小寫,最後做了詞幹提取的操作,由此證明我們上面自定義的分析器已然生效了!

相似度模型的配置

Elasticsearch 允許為索引模式映射檔案中的不同字段指定不同的 相似度得分 計算模型,其用法例析如下:

"mappings" : {
        "user" : {
            "properties" : {
                "id" : {
                    "type" : "long",
                    "store" : "yes"
                },
                "name" : {
                    "type" : "string",
                    "store" : "yes",
                    "index" : "analyzed",
                    "analyzer" : "myanalyzer",
                    "similarity" : "BM25"
                },
                "birthday" : {
                    "type" : "date",
                    "store" : "yes"
                },
                "hobby" : {
                    "type" : "string",
                    "store" : "no",
                    "index" : "analyzed"
                }

            }
        }
    }           
上述 json檔案中,我們為

name

字段使用了

BM25

這種相似度模型,添加的方法是使用

similarity

屬性的鍵值對,這樣一來 Elasticsearch 将會為

name

字段使用

BM25

相似度計算模型來計算相似得分。

資訊格式的配置

Elasticsearch 支援為每個字段指定資訊格式,以滿足通過改變字段被索引的方式來提高性能的條件。Elasticsearch 中的資訊格式有如下幾個:

  • default

    :預設資訊格式,其提供了實時的對存儲字段和詞向量的壓縮
  • pulsing

    :将 重複值較少字段 的資訊清單 編碼為詞條矩陣,可加快 該字段的查詢速度
  • direct

    :該格式在讀過程中将詞條加載到未經壓縮而存在記憶體的矩陣中,該格式可以提升常用字段的性能,但損耗記憶體
  • memory

    :該格式将所有的資料寫到磁盤,然後需要FST來讀取詞條和資訊清單到記憶體中
  • bloom_default

    :預設資訊格式的擴充,增加了把

    bloom filter

    寫入磁盤的功能。讀取時

    bloom filter

    被讀取并存入記憶體,以便快速檢查給定的值是否存在
  • bloom_pulsing

    pulsing

    格式的擴充,也加入

    bloom filter

    的支援

資訊格式字段(

postings_format

)可以在 任何一個字段上 進行設定,配置資訊格式的示例如下:

"mappings" : {
        "user" : {
            "properties" : {
                "id" : {
                    "type" : "long",
                    "store" : "yes",
                    "postings_format" : "pulsing"
                },
                "name" : {
                    "type" : "string",
                    "store" : "yes",
                    "index" : "analyzed",
                    "analyzer" : "myanalyzer"
                },
                "birthday" : {
                    "type" : "date",
                    "store" : "yes"
                },
                "hobby" : {
                    "type" : "string",
                    "store" : "no",
                    "index" : "analyzed"
                }

            }
        }
    }            
在該例子之中,我們手動配置改變了

id

字段的資訊格式為

pulsing

,是以可加快該字段的查詢速度。

文檔值及其格式的配置

文檔值 這個字段屬性作用在于:其允許将給定字段的值被寫入一個更高記憶體效率的結構,以便進行更加高效的排序和搜尋。我們通常可以将該屬性加在 需要進行排序 的字段上,這樣可以 提效。

其配置方式是 通過屬性

doc_values_format

進行,有三種常用的

doc_values_format

屬性值,其含義從名字中也能猜個大概:

  • default

    :預設格式,其使用少量的記憶體但性能也不錯
  • disk

    :将資料存入磁盤,幾乎無需記憶體
  • memory

    :将資料存入記憶體

舉個栗子吧:

"mappings" : {
        "user" : {
            "properties" : {
                "id" : {
                    "type" : "long",
                    "store" : "yes"
                },
                "name" : {
                    "type" : "string",
                    "store" : "yes",
                    "index" : "analyzed",
          "analyzer" : "myanalyzer"
                },
                "birthday" : {
                    "type" : "date",
                    "store" : "yes"
                },
                "hobby" : {
                    "type" : "string",
                    "store" : "no",
                    "index" : "analyzed"
                },
                "age" : {
                    "type" : "integer",
                    "doc_values_format" : "memory"
                 }
            }
        }
    }           
上述 json配置中,我們給類型

user

添加了一個

age

字段,假如我們想對年齡字段進行排序,那麼給該字段設定文檔值格式的屬性是可以提升效率的。

後 記

由于能力有限,若有錯誤或者不當之處,還請大家批評指正,一起學習交流!
可 長按 或 掃描 下面的 小心心 來訂閱 CodeSheep,擷取更多 務實、能看懂、可複現的 原創文 ↓↓↓