中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

編程隨筆-ElasticSearch知識導圖(3):映射

發布時間:2020-03-31 00:22:45 來源:網絡 閱讀:951 作者:簡單是美美 欄目:大數據

1. 啥是映射

??ES中的映射(Mapping)實質上就是對文檔對象結構的定義,也即對文檔中各元素的描述。在ES中定義映射,就如同定義XML文檔的XML Schema。
??ES中的映射定義了文檔模式(就如同在關系數據庫中定義了關系模式),文檔模式確定了存在ES中的文檔的格式,結構和字段的數據類型。通過查看某個索引的映射可以了解文檔的結構,以便使用查詢語言(Query DSL)構建更符合我們要求的查詢命令。

2. 從一個示例開始

??讓我們首先看一下如下關于銀行賬號的文檔示例:

{
    "account_number": 1,
    "balance": 39225,
    "firstname": "Amber",
    "lastname": "Duke",
    "age": 32,
    "gender": "M",
    "address": "880 Holmes Lane",
    "employer": "Pyrami",
    "email": "amberduke@pyrami.com",
    "city": "Brogan",
    "state": "IL"
}

??ES對該文檔的自動生成的映射是下面這個樣子的:

{
    "bank": {
        "mappings": {
            "account": {
                "properties": {
                    "account_number": {
                        "type": "long"
                    },
                    "address": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "age": {
                        "type": "long"
                    },
                    "balance": {
                        "type": "long"
                    },
                    "city": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "email": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "employer": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "firstname": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "gender": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "lastname": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "state": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    }
                }
            }
        }
    }
}

??由這個自動生成的映射可以看到:ES自動將account_number、balance、age這些屬性映射為long類型,其它的屬性都映射為text類型。text類型的屬性常用于全文搜索,但是并不進入內存中索引,因此text類型并不可用于聚合和排序(系統會報錯:"Fielddata is disabled on text fields by default. Set fielddata=true on [address] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.")。
??ES允許為一個對象屬性定義多個域(fields),每個域是該屬性的一個facet(我思考很久,還是覺得這個詞最合適),如“address”屬性類型為text,為它定義 一個域為keyword,該域的類型為“keyword”,不會被分析器(analyzer)分析,可用于排序、聚合和精確查找(請注意ignore_above這個屬性,限制了用于keyword的有效字符數目)。
??在DSL查詢語言中查詢時,使用“address”時,經分析器分析后,"880 Holmes Lane"可能被分解為“880”,“Holmes”,“Lane”進入全文搜索。看看下面的兩個查詢命令:

curl -iXGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json'  -d'
{"query":
    {"match":
       {"address.keyword":"880 Holmes Lane"}
    }
}'

??查詢出來只有一個結果,精確匹配“880 Holmes Lane”。

curl -iXGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json'  -d'
{"query":
    {"match":
       {"address":"880 Holmes Lane"}
    }
}'

??查詢出來多個結果,查詢條件“880 Holmes Lane”被分析器分析后檢索,"591 Nolans Lane"也被檢索出來(其中包含了一個分析器分解后的Lane)。
??以一張圖總結相關的知識點:
編程隨筆-ElasticSearch知識導圖(3):映射

3. 域的數據類型

??ES中域的主要數據類型如下表所示,還可由一些插件擴展數據類型(這里不贅述了):

數據類型 分類
text , keyword 字符串
long , integer , short , byte , double , float , half_float , scaled_float 數字
date 日期
boolean 布爾
binary 二進制
integer_range , float_range , long_range , double_range , date_range 區間類型
Array, object, nested 復雜數據類型
geo_point, geo_shape 地理數據類型
binary 二進制
ip, completion,token_count,percolator,join, alias 特殊數據類型

3.1. 核心數據類型

??核心數據類型與我們常使用的強類型語言中的數據類型類似,可分為以下幾類:

  • 字符串型:包含text 、keyword。
  • 數字類型:包含long , integer , short , byte , double , float , half_float , scaled_float。這里偷個懶,各數字類型參見參考文獻1中的截圖描述。
    編程隨筆-ElasticSearch知識導圖(3):映射
  • 日期類型:date。可表示為字符串類型,如"2015-01-01" or "2015/01/01 12:10:30",也可表示為秒或毫秒的整數。
  • 布爾類型:boolean。真值可用true(對應json中的布爾值),“true”表示。
  • 二進制類型:binary。值用以base64編碼的字符串表示。
  • 區間類型:包含integer_range , float_range , long_range , double_range , date_range。
    ??對于數字區間類型,示例如下:
    //類型為integer_range
    "expected_attendees" : { 
    "gte" : 10,
    "lte" : 20
    }

    ??對于日期區間類型,示例如下:

    //類型為date_range
    "time_frame" : { 
    "gte" : "2015-10-31 12:00:00", 
    "lte" : "2015-11-01"
    }

    3.2. 復雜數據類型

    ??復雜數據類型可用于表達對象之間的語義,包含Array, object, nested等類型。

  • Array類型:在ES中,沒有專門的“array”類型用于顯式定義,任何域都可以包含零個或多個值,即任何域都可以是一個數組,不過不同于JSON中的數組,ES中的數組各元素必須為相同類型。
  • Object類型:JSON對象可以是一個嵌套結構,在現實應用中我們常常使用這種嵌套結構來表達對象之間的層次關系。
    我們看看下面這個映射的定義:
    "manager": { 
          "properties": {
            "age":  { "type": "integer" },
            "name": { 
              "properties": {
                "first": { "type": "text" },
                "last":  { "type": "text" }
              }
            }
          }
        }

    ??其對應的對象為:

    "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
    }

    ??其中域manager就是一個對象類型,其中的name是它的子對象。對于對象類型,缺省設置“type”為”object”,因此不用顯式定義“type”。
    ??對于上面的對象類型,ES在索引時將其轉換為"manager.age", "manager.name.first" 這樣扁平的key,因此查詢時也可以使用這樣的扁平key作為域來進行查詢。

  • nested類型:是object類型的延伸,主要用于對象數組。仍以參考文獻1中的示例:
    對于對象:
    "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
    ]

    ??如果使用動態映射,會被ES索引為如下形式:

    "user.first" : [ "alice", "john" ],
    "user.last" :  [ "smith", "white" ]

    ??這樣的索引形式在查詢時會丟失對象中”first”與“last”之間的關聯關系。
    ??如果將user映射為如下形式:

    "user": {
          "type": "nested" 
        }

    ??ES在索引時會保留對象域之間的關聯關系,在查詢時找對正確的對象。
    ??如使用如下查詢則找不到任何命中對象(不存在“Alice Smith”這個對象):

    {
    "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }} 
          ]
        }
      }
    }
    }
    }

    3.3. 地理數據類型

    ??地理數據類型可用于LBS的應用,包括:

  • geo_point類型:可用于存儲某個地理坐標的經緯度。示例如下:
       // location為geo_point類型
    "location": { 
    "lat": 41.12,
    "lon": -71.34
    }
  • geo_shape類型:用于存儲地理多邊形形狀,有興趣的讀者可以參考文獻1。

    3.4. 特殊數據類型

    ??特殊數據類型包括:

  • ip類型:用于表示IPv4與IPv6的地址
  • completion類型:提供自動輸入關聯完成功能,如常見的baidu收縮框。
  • token_count類型:用于計算字符串token的長度,使用時需提供"analyzer"定義。
  • percolate類型:定義為percolate類型的字段會被ES分析為一個查詢并保存下來,并可用在后繼對文檔的查詢中。Percolate可以理解為一個預置的查詢。
  • alias類型:定義一個已存在域的別名。
  • join類型:該類型定義了文檔對象之間的父子關系(可定義多層,形成一顆層次樹),即同一索引中多個文檔對象可以存在依賴關系,如互聯網應用常見的博客文章與回復,問題與回答之間的關系。參看文獻1中的如下示例:
    定義映射字段:
    {
    "my_join_field": {
        "type": "join",
        "relations": {
            "question": "answer"
        }
    }
    }

    ??my_join_field定義了"question"與"answer"之間關系為父子關系。
    ??觀察對于該映射的一個文檔實例,路徑為“my_index/_doc/1”:

    {
    "text": "This is a question",
    "my_join_field": "question" 
    }

    ??該文檔的一個子文檔對象示例如下,在my_join_field需要定義父親的ID(這里根據上面的父實例,為1):

    {
    "text": "This is an answer",
    "my_join_field": {
    "name": "answer", 
    "parent": "1" 
    }
    }

    ??需要注意的是,一個父文檔可以有多個子文檔,父子文檔應部署在同一個分片上。因而在向ES提交父子文檔時,應在URI中使用相同的routing參數。
    ??join類型定義了文檔之間的父子依賴關系,在查詢和聚合操作中可使用這種依賴關系。

    4. 映射參數

    ??JSON是JS對象序列化的字符串,ES接收一個JSON字符串形式的文檔對象,本質上是存入一個JS對象,JS定義了對象,數組,字符串,數字,布爾型和null等數據類型。
    ??ES中的域數據類型可視為對JS對象數據類型的擴展,如join,區間類型等都表示為js對象。
    ??在定義域映射時,ES定義了相關的映射參數,這里簡單列舉并描述,詳細信息可以查看文獻1。

參數 描述
analyzer 定義對文本數據的分析器
normalizer 對文本數據規范化
boost 用于提升字段搜索的權重
coerce 當為false時,強制輸入值必須符合映射的域數據類型
copy_to 將當前域的值復制到另一個域中
doc_values 當該域不參與排序域聚合操作時,可設置為false使得不在磁盤上存儲Doc value(以列式存儲的文檔值)以節約磁盤空間。缺省為true
dynamic 該參數控制在對象中檢測到的新的域(未在映射中定義)是否加入到域中,當為false或strict時,新域不會加入到映射中。缺省為true
enabled 主要應用于object類型的域,當設置為false,該域不被索引。缺省為true
fielddata 對于text類型的域,如果該參數設置為true,該域的數據在第一次使用時會載入常駐于內存中。缺省為false
format 定義域數據的格式,用于日期類型
ignore_above 定義字符串的有效長度
ignore_malformed 如果設置為true,當字段值與映射定義不一致時,不會拋出錯誤。缺省為false
index 缺省為true,當設置為false時,該域不被索引,不可被搜索
null_value 定義該域為空值時的格式,如使用“NULL”這樣的字符串
search_analyzer 定義搜索時的analyzer,可與定義映射時使用的analyzer不同
store 該值設置為true時,當前域的原始值也存儲下來(在_source之外)。默認為false

??總結一下:

  • 與域數據格式及約束相關的參數:normalizer,format,ignore_above,ignore_malformed,coerce
  • 與索引相關的參數:index,dynamic,enabled
  • 與存儲策略相關的參數:store, fielddata,doc_values
  • 分析器相關參數:analyzer,search_analyzer
  • 其它參數:boost,copy_to,null_value
    ??對于這些參數的描述主要基于筆者的理解,可能有不準確之處。實際上這些參數與ES的實現機制(如存儲結構,索引結構密切有關),只能在實際應用中去慢慢體會。

    5. 一個設計實例

    ??在ES中設計一個索引的映射和在關系數據庫中設計關系模式,ER模型,在XML中設計XML Schema一樣。需要完整包含領域知識并滿足數據之間的約束。
    ??在這一節中我們探討一個使用ES構建視頻圖像信息數據庫的實例。

    5.1. GA/T 1400.3的數據模型分析

    ??視頻圖像信息數據庫(以下簡稱視圖庫)基于GA/T 1400.3 標準定義,用于存儲視頻、圖像等基本對象(二進制數據)和由這些基本對象分析(可自動)出的屬性對象。
    ??在GA/T 1400.4中,定義了訪問視頻圖像信息數據庫的接口,這些接口以基于HTTP的restful形式定義,以JSON格式傳輸數據。因而使用ES作為視頻圖像信息數據庫的存儲容器可以利用ES的JSON文檔對象存儲和。
    ??在GA/T 1400.3中定義了視頻圖像信息數據庫的數據模型,該數據模型中定義了三十多個領域對象,對象之間具有關聯關系。視圖庫中的對象定義主要包含以下特征:

  • 視圖庫中每個對象都定義了唯一ID用于標識。
  • 對象之間存在父子(或因果)關系,關聯方式為:子對象中包含父對象的ID。如車道對象包含對應卡口的ID;告警對象包含布控對象的ID;人、車、物對象包含其對應的來源圖像ID和采集設備ID。
  • 對象之中嵌套子對象:如人、車、物對象中都包含子圖像列表對象。
    ??總的來說,視圖庫模型中的數據對象間的關聯關系比較簡單,也相對獨立。
    視圖庫中的對象的屬性(字段)被約束為三種類型:R(必選),R/O(條件可選,當滿足某個條件時該屬性必須存在),O(可選)。
    ??不同于RDBMS,ES在映射對象的屬性時并沒有標明值是否不為空的選項,因而需要在提交對象數據到ES前進行數據的有效性檢驗。在設計基于ES的視圖庫架構設計時,這樣的數據有效性檢驗服務(模塊)可放在API網關(或負載均衡網關)與ES之間,并根據實際場景的效率和完整性要求決定是否啟用。

    5.2. GA/T 1400.3的數據類型分析

    ??視圖庫規范定義對象字段的數據類型可為:

  • 基礎數據類型:包含字符串,整型數,長整型數,浮點數,日期時間,數組,對象。可與ES的數據類型對應。
  • 擴展數據類型:定義了領域知識,對基礎數據類型做了一些約束形成擴展數據類型。如道路類型(SceneType)定義為使用最大長度為2的字符串表示的枚舉類型。

    5.3. File對象的映射分析

    ??以視圖庫中的File對象(GA/T 1400.3附錄A.7)為例,我們看看如何定義它的映射。
    ??在GA/T 1400.3中,它的XML Schema是這樣定義的:

    <complexType name="File">
    <sequence>
    <element name="FileID" type=" BasicObjectIdType"/>
    <element name="InfoKind" type="InfoType" use="required"/>
    <element name="Source" type="DataSourceType" use="required"/>
    <element name="FileName" type="FileNameType" use="required"/>
    <element name="StoragePath" type="string" />
    <element name="FileHash" type="string" use="required"/>
    <element name="FileFormat" type="string" use="required"/>
    <element name="Title" type="string" use="required"/>
    <element name="SecurityLevel" type="SecretLevelType" />
    <element name="SubmiterName" type="NameType" />
    <element name="SubmiterOrg" type="string" />
    <element name="EntryTime" type="dateTime" />
    <element name="FileSize" type="int"/>
    </sequence>
    </complexType>

    ??一個文件對象的對象實例如下所示。

    {
    "FileObject": {
        "FileID": "31000000001190000138022019021416121100001",
        "InfoKind": 1, 
        "Source": "3",  
        "FileName": "tollgate_3_lane_4_20190214161211.jpg",
        "StoragePath": "/tollgate/3/lane/4/images",
        "FileHash": "38b8c2c1093dd0fec383a9d9ac940515",
        "FileFormat": "Jpeg",
        "Title": "tollgate_3_lane_4_20190214161211",
        "SecurityLevel": "3",
        "SubmiterName": "zhangkai",
        "SubmiterOrg": "pudong",
        "EntryTime": "20190214161214",
        "FileSize": 94208
    }
    }

    ??分析該對象中的各屬性字段,整理出下表:

字段名稱 標準中的數據類型定義 ES中對應類型 備注
FileID string(41) type:keyword <br> doc_values:false <br>ignore_above : 41 不參與排序與聚合
InfoKind int type: integer<br>coerce: false
Source string(2) type:keyword<br> ignore_above : 2
FileName string(0..256) type:keyword<br>ignore_above : 256
StoragePath string(256) type:keyword<br>doc_values:false<br>ignore_above : 256 不參與排序與聚合
FileHash string(32) type:keyword<br>doc_values:false<br> ignore_above : 32 不參與排序與聚合
FileFormat string(32) type:keyword<br>ignore_above : 32
Title string(128) type:keyword <br>ignore_above : 128
SecurityLevel String(1) type:keyword<br> ignore_above : 1
SubmiterName string(0..50) type:keyword <br>ignore_above : 50
SubmiterOrg string(0..100) type:keyword <br>ignore_above : 100
EntryTime dateTime type: date <br>format:yyyyMMddHHmmss 格式為:YYYYMMDDhhmmss
FileSize int type: integer <br> coerce: false

5.4. File對象的映射定義

??我們使用如下命令在ES中創建索引file(注意這里的index.mapping.coerce被設置為false):

curl -iXPUT 'localhost:9200/file?pretty' -H "Content-type: application/json" -d' 
{
  "settings": {
     "number_of_shards":3,
     "number_of_replicas":1,
     "index.mapping.coerce": false
  }
}
'

??使用如下命令修改file索引的映射:

curl -iXPUT 'localhost:9200/file/_mapping/object?pretty' -H "Content-type: application/json" -d'
{
    "properties": {
        "FileObject": {
            "properties": {
                "FileID": {
                    "type": "keyword",
                    "doc_values": false,
                    "ignore_above": 41
                },
                "InfoKind": {
                    "type": "integer",
                    "coerce": false
                },
                "Source": {
                    "type": "keyword",
                    "ignore_above": 2
                },
                "FileName": {
                    "type": "keyword",
                    "ignore_above": 256
                },
                "StoragePath": {
                    "type": "keyword",
                    "doc_values": false,
                    "ignore_above": 256
                },
                "FileHash": {
                    "type": "keyword",
                    "doc_values": false,
                    "ignore_above": 32
                },
                "FileFormat": {
                    "type": "keyword",
                    "ignore_above": 32
                },
                "Title": {
                    "type": "keyword",
                    "ignore_above": 128
                },
                "SecurityLevel": {
                    "type": "keyword",
                    "ignore_above": 1
                },
                "SubmiterName": {
                    "type": "keyword",
                    "ignore_above": 50
                },
                "SubmiterOrg": {
                    "type": "keyword",
                    "ignore_above": 100
                },
                "EntryTime": {
                    "type": "date",
                    "format": "yyyyMMddHHmmss"
                },
                "FileSize": {
                    "type": "integer",
                    "coerce": false
                }
            }
        }
    }
}
'

??使用如下命令查看file的映射信息:

curl -iXGET 'localhost:9200/file/_mapping?pretty'

??可以看到返回的映射信息:

{
  "file" : {
    "mappings" : {
      "object" : {
        "properties" : {
          "FileObject" : {
            "properties" : {
              "EntryTime" : {
                "type" : "date",
                "format" : "yyyyMMddHHmmss"
              },
              "FileFormat" : {
                "type" : "keyword",
                "ignore_above" : 32
              },
              "FileHash" : {
                "type" : "keyword",
                "doc_values" : false,
                "ignore_above" : 32
              },
              "FileID" : {
                "type" : "keyword",
                "doc_values" : false,
                "ignore_above" : 41
              },
              "FileName" : {
                "type" : "keyword",
                "ignore_above" : 256
              },
              "FileSize" : {
                "type" : "integer",
                "coerce" : false
              },
              "InfoKind" : {
                "type" : "integer",
                "coerce" : false
              },
              "SecurityLevel" : {
                "type" : "keyword",
                "ignore_above" : 1
              },
              "Source" : {
                "type" : "keyword",
                "ignore_above" : 2
              },
              "StoragePath" : {
                "type" : "keyword",
                "doc_values" : false,
                "ignore_above" : 256
              },
              "SubmiterName" : {
                "type" : "keyword",
                "ignore_above" : 50
              },
              "SubmiterOrg" : {
                "type" : "keyword",
                "ignore_above" : 100
              },
              "Title" : {
                "type" : "keyword",
                "ignore_above" : 128
              }
            }
          }
        }
      }
    }
  }
}

??現在我們可以向file索引提交數據對象了,使用如下命令:

curl -iXPOST 'localhost:9200/file/object/31000000001190000138022019021416121100001?pretty'  -H "Content-type: application/json" -d'
{
    "FileObject": {
        "FileID": "31000000001190000138022019021416121100001",
        "InfoKind": 1, 
        "Source": "3",  
        "FileName": "tollgate_3_lane_4_20190214161211.jpg",
        "StoragePath": "/tollgate/3/lane/4/images",
        "FileHash": "38b8c2c1093dd0fec383a9d9ac940515",
        "FileFormat": "Jpeg",
        "Title": "tollgate_3_lane_4_20190214161211",
        "SecurityLevel": "3",
        "SubmiterName": "zhangkai",
        "SubmiterOrg": "pudong",
        "EntryTime": "20190214161214",
        "FileSize": 94208
    }
}
'

5.5. 小結

??視圖庫中對象的字段不用進行全文檢索,也可以使用關系數據庫作為存儲容器,但需要對JSON數據進行反序列化解析相應字段入庫,查詢出庫時需要將多個字段序列化為JSON數據。固然在編程時可以使用ORM和JSON序列化中間件來完成工作,但在海量請求下,效率會有影響。使用ES可以利用ES的restful接口和JSON存儲格式的天然特性以契合規范要求。

??在視圖庫規范中有一些自定義的約束,這些涉及數據有效性檢驗的服務應該部署在ES入庫之前。在本實例中,更多的是把ES作為一個Nosql數據庫使用。

6. 參考文獻

  1. https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
  2. Clinton Gormley &Zachary Tong, Elasticsearch: The Definitive Guide,2015
  3. GA/T 1400.3 公安視頻圖像信息應用系統 第3部分:數據庫技術要求,2017
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汤原县| 南康市| 军事| 乐东| 确山县| 鲜城| 连州市| 邮箱| 濮阳县| 公安县| 祁连县| 浑源县| 尤溪县| 红安县| 南乐县| 新田县| 河南省| 光泽县| 宣化县| 河北区| 台中市| 重庆市| 谢通门县| 定州市| 信丰县| 湟中县| 溆浦县| 土默特左旗| 玉田县| 泸溪县| 林西县| 仁化县| 金秀| 来凤县| 喜德县| 桐乡市| 同德县| 孙吴县| 团风县| 蒲江县| 台南市|