Elasticsearch 索引的映射配置詳解

Profile

文章共1540字,閱讀本文大約需要5分鐘 !


概述

Elasticsearch 與傳統(tǒng)的 SQL數(shù)據(jù)庫的一個明顯的不同點是,Elasticsearch 是一個 非結(jié)構(gòu)化 的數(shù)據(jù)庫,或者說是一個 無模式 的數(shù)據(jù)庫。Elasticsearch 中數(shù)據(jù)最重要的三要素當屬:索引類型、文檔,其中索引這個概念非常重要,我們可以粗略地將其類比到傳統(tǒng)SQL數(shù)據(jù)庫中的 數(shù)據(jù)表。本文就從 Elasticsearch 的索引映射如何配置開始講起。

注: 本文原載于 My Personal Blog:, CodeSheep · 程序羊 !

本文內(nèi)容腦圖如下:

本文內(nèi)容腦圖


索引模式映射

創(chuàng)建索引時,可以自定義索引的結(jié)構(gòu),比如 創(chuàng)建一個保存用戶信息數(shù)據(jù)的 users 索引,其典型的結(jié)構(gòu)如下:

  • id:唯一表示符
  • name:姓名
  • birthday:出生日期
  • hobby:愛好

為此我們可以創(chuàng)建一個 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代碼意義如下:

  • 創(chuàng)建一個名稱為 usersIndex
  • 里面有一個名稱為 userType
  • user 有四個 field
  • 且每個 field 都有自己的 屬性 定義

然后我們來執(zhí)行如下命令來新建一個索引:

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

結(jié)果如下,索引 users、類型 user、以及 四個字段 都已經(jīng)順利插入:

新建一個索引

關(guān)于字段的 可選類型,有如下幾種:

  • string:字符串
  • number:數(shù)字
  • date:日期
  • boolean:布爾型
  • binary:二進制
  • ip:IP地址
  • token_count類型

關(guān)于每種類型有哪些 屬性,可參考官方文檔,由于內(nèi)容太多,此處不再贅述。



分析器的使用

分析器是一種用于 分析數(shù)據(jù) 或者按照用戶想要的方式 處理數(shù)據(jù) 的工具,對于 字符串類型 的字段,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(自定義過濾器,其本質(zhì)是 kstem
  • 再來看如何測試和使用自定義的分析器

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

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

可見我們輸入的時一行字符串普通"Cars Trains",而輸出為:cartrain,這說明短語 "Cars Trains" 被分成了兩個詞條,然后全部轉(zhuǎn)為小寫,最后做了詞干提取的操作,由此證明我們上面自定義的分析器已然生效了!



相似度模型的配置

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文件中,我們?yōu)?name 字段使用了 BM25 這種相似度模型,添加的方法是使用 similarity 屬性的鍵值對,這樣一來 Elasticsearch 將會為 name 字段使用 BM25 相似度計算模型來計算相似得分。



信息格式的配置

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

  • default:默認信息格式,其提供了實時的對存儲字段和詞向量的壓縮
  • pulsing:將 重復值較少字段 的信息列表 編碼為詞條矩陣,可加快 該字段的查詢速度
  • direct:該格式在讀過程中將詞條加載到未經(jīng)壓縮而存在內(nèi)存的矩陣中,該格式可以提升常用字段的性能,但損耗內(nèi)存
  • memory:該格式將所有的數(shù)據(jù)寫到磁盤,然后需要FST來讀取詞條和信息列表到內(nèi)存中
  • bloom_default:默認信息格式的擴展,增加了把 bloom filter 寫入磁盤的功能。讀取時 bloom filter 被讀取并存入內(nèi)存,以便快速檢查給定的值是否存在
  • bloom_pulsingpulsing 格式的擴展,也加入 bloom filter 的支持

信息格式字段(postings_format)可以在 任何一個字段上 進行設(shè)置,配置信息格式的示例如下:

    "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,因此可加快該字段的查詢速度。



文檔值及其格式的配置

文檔值 這個字段屬性作用在于:其允許將給定字段的值被寫入一個更高內(nèi)存效率的結(jié)構(gòu),以便進行更加高效排序搜索。我們通??梢詫⒃搶傩约釉?需要進行排序 的字段上,這樣可以 提效。

其配置方式是 通過屬性 doc_values_format 進行,有三種常用的 doc_values_format 屬性值,其含義從名字中也能猜個大概:

  • default:默認格式,其使用少量的內(nèi)存但性能也不錯
  • disk:將數(shù)據(jù)存入磁盤,幾乎無需內(nèi)存
  • memory:將數(shù)據(jù)存入內(nèi)存

舉個栗子吧:

    "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 字段,假如我們想對年齡字段進行排序,那么給該字段設(shè)置文檔值格式的屬性是可以提升效率的。



后 記

由于能力有限,若有錯誤或者不當之處,還請大家批評指正,一起學習交流!



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容