1. 程式人生 > >Elasticsearch建立索引和對映結構詳解

Elasticsearch建立索引和對映結構詳解

前言

這篇文章詳細介紹瞭如何建立索引和某個型別的對映。

下文中[address]指代elasticsearch伺服器訪問地址(http://localhost:9200)。

1       建立索引

1.1     簡單建立語句

curl -XPUT [address]/blog

1.2     帶引數的建立語句

curl -XPUT [address]/blog/ -d '{

    "settings":{

           "number_of_shards":1,     //設定分片數量

           "number_of_replicas":2,  //設定副本數量

           //自定義索引預設分析器

           "index":{

                  "analysis":{

                         "analyzer":{

                                "default":{

                                       "tokenizer":"standard",     //分詞器

                                       "filter":[ //過濾器

                                              "asciifolding",

                                              "lowercase",

                                              "ourEnglishFilter"

                                       ]

                                }

                         },

                         "filter":{

                                "ourEnglishFilter":{

                                       "type":"kstem"

                                }

                         }

                  }

           }

    }

}'

2       建立對映(扁平結構)

2.1     簡單建立語句

curl -XPUT [address]/blog/_mapping/article?pretty -d '{

         "properties":{

                   "id":{"type":"long"},

                   "name":{"type":"string"},

                   "published":{"type":"date"}

         }

}'

2.2     帶引數的建立語句

curl -XPUT [address]/blog/_mapping/article?pretty -d '{

         "dynamic":"false",  //關閉自動新增欄位,關閉後索引資料中如果有多餘欄位不會修改mapping,預設true

         "_id":{"index":"not_analyzed","store":"no"},        //設定文件識別符號可以被索引,預設不能被索引。可以設定為"_id":{"path":"book_id"},這樣將使用欄位book_id作為識別符號

         "_all":{"enabled":"false"},       //禁用_all欄位,_all欄位包含了索引中所有其他欄位的所有資料,便於搜尋。預設啟用

         "_source":{"enabled":"false"},        //禁用_source欄位,_source欄位在生成索引過程中儲存傳送到elasticsearch的原始json文件。elasticsearch部分功能依賴此欄位(如區域性更新功能),因此建議開啟。預設啟用

         "_index":{"enabled":"true"},  //啟用_index欄位,index欄位返回文件所在的索引名稱。預設關閉。

         "_timestamp":{"enabled":"true","index":"not_analyzed","store":"true","format":"YYYY-mm-dd"},                  //啟用時間戳並設定。時間戳記錄文件索引時間,使用區域性文件更新功能時,時間戳也會被更新。預設未經分析編入索引但不儲存。

         "_ttl":{"enabled":"true","default":"30d"},     //定義文件的生命週期,週期結束後文檔會自動刪除。

         "_routing":{"required":"true","path":"name"}      //指定將name欄位作為路由,且每個文件必須指定name欄位。

         "properties":{

                   "id":{

                            "type":"long",

                            //公共屬性

                            "store":"yes",

                            //數值特有屬性

                            "precision_step":"0"       //指定為該欄位生成的詞條數,值越低,產生的詞條數越多,查詢會更快,但索引會更大。預設4

                   },

                   "name":{

                            "type":"string",

                            //公共屬性

                            "store":"yes",

                            "index":"not_analyzed", //analyzed:編入索引供搜尋、no:不編入索引、not_analyzed(string專有):不經分析編入索引

                            "boost":"1",    //文件中該欄位的重要性,值越大表示越重要,預設1

                            "null_value":"jim",  //當索引文件的此欄位為空時填充的預設值,預設忽略該欄位

                            "include_in_all":"xxx"      //此屬性是否包含在_all欄位中,預設為包含

                            //字串特有屬性

                            "analyzer":"xxx",     //定義用於索引和搜尋的分析器名稱,預設為全域性定義的分析器名稱。可以開箱即用的分析器:standard,simple,whitespace,stop,keyword,pattern,language,snowball

                            "index_analyzer":"xxx",           //定義用於建立索引的分析器名稱

                            "search_analyzer":"xxx",        //定義用於搜尋時分析該欄位的分析器名稱

                            "ignore_above":"xxx"      //定義欄位中字元的最大值,欄位的長度高於指定值時,分析器會將其忽略

                   },

                   "published":{

                            "type":"date",

                            //公共屬性

                            "store":"yes",

                            //日期特有屬性

                            "precision_step":"0",      //指定為該欄位生成的詞條數,值越低,產生的詞條數越多,查詢會更快,但索引會更大。預設4

                            "format":"YYYY-mm-dd"          //指定日期格式,預設為dateOptionalTime

                   }

         }

}'

3       建立對映(非扁平結構)

在第二章我們講解了建立對映的語句。所建立的是簡單的扁平結構對映。這一章我們看看如何建立非扁平結構對映。

3.1     樹形結構

樹形結構的作用是為索引層級路徑提供便利。例如一家汽車店中可能會有如下路徑:/cars/passenger/sport、/cars/passenger/camper、/cars/delivery_truck,我們想在搜尋cars的時候返回三條記錄,搜尋cars/passenger的時候返回前兩條記錄,可以這樣建立對映:

curl -XPUT [address]/path -d '{

         "settings":{

                   //定義一個路徑分析器

                   "index":{

                            "analysis":{

                                     "analyzer":{

                                               "path_analyzer":{"tokenizer":"path_hierarchy"}

                                     }

                            }

                   }

         },

         "mappings":{

                   "category":{

                            "properties":{

                                     "category":{

                                               "type":"string",

                                               "fields":{

                                                        //定義多欄位物件,使用category.path進行查詢時將啟用路徑分析匹配指定路徑下的所有文件,使用category.name進行查詢時將精確匹配指定路徑的文件,略過結構更深的文件。

                                                        "name":{"type":"string","index":"not_analyzed"},

                                                        "path":{"type":"string","analyzer":"path_analyzer","store":true}

                                               }

                                     }

                            }

                   }

         }

}'

3.2     物件

先執行curl –XPUT [address]/extend_mapping,建立extend_mapping索引

建立一個帶有物件屬性author的型別book:

curl –XPUT [address]/extend_mapping/_mapping/book –d ‘{

         "properties":{

                   "title":{"type":"string","index":"not_analyzed"},

                   "author":{

                            "type":"object",

                            "properties":{

                                     "firstName":{"type":"string","index":"not_analyzed"},

                                     "lastName":{"type":"string","index":"not_analyzed"}

                            }

                   }

         }

}’

3.3     巢狀物件

巢狀物件允許我們連線一個主文件和多個附屬文件,下面通過一個例子來說明巢狀物件的應用場景。

現在我們有一個服裝店,需要設計一個數據結構來儲存服裝店裡的服裝資訊。例如現在有一種名字為”cloth”的服裝,這件服裝現有兩件存貨,一件XXL的紅色和一件XL的黑色,請設計一個數據結構來儲存該服裝資訊。

我們可能會把資料結構設計成這樣:

{

         “name”:”cloth”,

         “variation”:[

                   {“size”:”XXL”,”color”:”red”},

                   {“size”:”XL”,”color”:”black”}

]

}

直觀的來看,這個資料結構是能夠表現我們所描述的服裝資訊的,我們依據這個結構建立以下對映(傳送rest請求語句略):

{

"properties":{

         "name":{"type":"string","index":"not_analyzed"},

         "variation":{

                   "properties":{

                            "size":{"type":"string","index":"not_analyzed"},

                            "color":{"type":"string","index":"not_analyzed"}

                   }

         }

}

}

建立對映後索引以下資料:

{

    "name": "cloth",

    "variation": [

        {

            "size": "XXL",

            "color": "red"

        },

        {

            "size": "XL",

            "color": "black"

        }

    ]

}

下面我們查詢一下我們的服裝資訊庫,看看是否有尺寸為XXL,顏色為black的服裝:

{

  "filter": {

    "and": [

      {

        "term": {

          "variation.size": "XXL"

        }

      },

      {

        "term": {

          "variation.color": "black"

        }

      }

    ]

  }

}

         出乎意料的是,該查詢返回了結果:

{

         ......(此處資訊略去)

    "hits": {

        "total": 1,

        "max_score": 1,

        "hits": [

            {

                "_index": "extend_mapping",

                "_type": "unnested_cloth",

                "_id": "AVACnlA-8eAUpvGq_eZa",

                "_score": 1,

                "_source": {

                    "name": "cloth",

                    "variation": [

                        {

                            "size": "XXL",

                            "color": "red"

                        },

                        {

                            "size": "XL",

                            "color": "black"

                        }

                    ]

                }

            }

        ]

    }

}

這與我們的預期不符,我們只有XXL紅色和XL黑色兩件服裝,並沒有所查詢的XXL黑色服裝。

這是因為按照我們之前定義的對映結構,尺寸資訊(“size”:”XXL”,”size”:”XL”)和顏色資訊(“color”:”red”,”color”:”black”)都存在同一個文件中,ES無法將XXL和red、XL和black繫結在一起,因此在查詢時造成了混淆。

解決的方法就是使用巢狀物件,將variation物件的型別指定為巢狀:

重新建立以下對映:

{

"properties":{

         "name":{"type":"string","index":"not_analyzed"},

         "variation":{

                   “type”:”nested”,

                   "properties":{

                            "size":{"type":"string","index":"not_analyzed"},

                            "color":{"type":"string","index":"not_analyzed"}

                   }

         }

}

}

索引之前的測試資料:

{

    "name": "cloth",

    "variation": [

        {

            "size": "XXL",

            "color": "red"

        },

        {

            "size": "XL",

            "color": "black"

        }

    ]

}

現在我們通過”type”:”nested”將variation物件指定為巢狀物件,需要注意的是,如果我們對新對映執行類似之前的查詢,將無任何文件返回。因為對於巢狀對映,必須要使用專用的查詢語法,如下:

{

    "filter": {

        "nested": {

            "path": "variation",

            "filter": {

                "and": [

                    {

                        "term": {

                            "variation.size": "XXL"

                        }

                    },

                    {

                        "term": {

                            "variation.color": "black"

                        }

                    }

                ]

            }

        }

    }

}

         這次的查詢如我們的預期,沒有返回結果。這是因為使用巢狀結構後,當我們索引測試資料時,事實上ES生成了3個文件,一個cloth的主文件,和兩個variation物件的附屬文件,這樣就分離儲存了兩件服裝存貨,避免了尺寸和顏色的混淆。