elasticsearch文檔-字段的mapping


mapping == Mapping是指定義如何將document映射到搜索引擎的過程,比如一個字段是否可以查詢以及如何分詞等,一個索引可以存儲含有不同"mapping types"的documents,ES允許每個mapping type關聯多個mapping定義。 顯式聲明的mapping是定義在index/type級別, 默認不需要顯式的定義mapping, 當新的type或者field引入時,ES會自動創建並且注冊有合理的默認值的mapping(毫無性能壓力), 只有要覆蓋默認值時才必須要提供mapping定義。 mapping types Mapping types是將索引里的documents按邏輯分組的方式, 類似數據中的表, 雖然不同的types之間有些區別, 但他們並不是完全分開的(說到底還是存在相同的Lucene索引里)。 強烈建議跨types的同名field有相同的類型定義以及相同的mapping特征(比如analysis的設置), 這在通過type前綴(`my_type.my_field`)來選擇字段時非常有效, 但這也不一定, 有些地方就不起作用(比如字段的聚合faceting)。 實際上在實踐中這個限制從來不是問題, field名通常表明了該field的類型(例如"first_name"總是一個字符串)。 還要注意, 這不適用於跨索引的情況。 mapping api 要創建mapping, 需要用到Put Mapping接口, 或者可以在調用create index接口時附帶mapping的定義。 global settings 全局設置`index.mapping.ignore_malformed`可以在索引級別上設置是否忽略異常內容(異常內容的一個例子是嘗試將字符串類型的值作為數字類型索引), 這個設置是跨mapping types的全局設置。 fields === 每一個ampping都有一些關聯的字段來控制如何索引的document的元數據(例如_all)。 _uid === 每個索引的document會關聯一個id和一個type, 內部的`_uid`字段將type和id組合起來作為document的唯一標示(這意味着不同的type可以有相同的id, 組合起來仍然是唯一的)。 在執行基於type的過濾時, 如果`_type`字段沒有被索引,會自動使用`_uid`字段, 並且不需要`_id`字段被索引。 ``` 附_uid的java源代碼 public static final byte DELIMITER_BYTE = 0x23; public static void createUidAsBytes(BytesRef type, BytesRef id, BytesRef spare) { spare.copyBytes(type); spare.append(DELIMITER_BYTES); spare.append(id); } ``` _id === 每個索引的document會關聯一個id和一個type, `_id`字段就是用來索引並且存儲(可能)id的,默認是不索引(not indexed)並且不存儲的(not stored)。 注意, 即使`_id`是不索引的, 相關的接口仍然起作用(他們會用`_uid`字段), 比如用`term`, `terms`或者`prefix`來根據ids過濾(包括用`ids`來查詢/過濾)。 `_id`字段也可以啟用索引或者存儲, 配置如下: ``` { "tweet" : { "_id" : {"index": "not_analyzed", "store" : "yes"} } } ``` 為了維護向后兼容性, 當升級到0.16時可以在節點級別設置`index.mapping._id.indexed`為true來確保id能被索引, 盡管不建議索引id。 可以設置`_id`的`path`屬性來從源文檔中提取id, 例如下面的mapping: ``` { "tweet" : { "_id" : { "path" : "post_id" } } } ``` 如果提交下面的數據 ``` { "message" : "You know, for Search", "post_id" : "1" } ``` `1`會提取出來作為id。 因為要提取id來決定在哪一個shard執行索引,需要在索引時做額外的解析。 _type === 每個索引的document會關聯一個id和一個type, type在索引時會自動賦給`_type`字段, 默認`_type`字段是需要索引的(但不analyzed)並且不存儲的, 這就意味着`_type`字段是可查詢的。 `_type`字段也可以設置為stored, 例如: ``` { "tweet" : { "_type" : {"store" : "yes"} } } ``` `_type`字段也可以設置為不索引, 並且此時所有用到`_type`字段的接口仍然能用。 ``` { "tweet" : { "_type" : {"index" : "no"} } } ``` _source === `_source`是一個自動生成的字段, 用來存儲實際提交的JSON數據, 他是不索引的(不可搜索), 只是用來存儲。 在執行"fetch"類的請求時, 比如get或者search, `_source`字段默認也會返回。 盡管`_source`非常有用, 但它確實會占用索引的存儲空間, 所以也可以禁用。 比如: ``` { "tweet" : { "_source" : {"enabled" : false} } } ``` compression 從0.90開始, 所有存儲的字段(包括`_source`)總是被壓縮的。 0.90之前: 如果要將source字段存儲在索引中的話,啟用壓縮(LZF)會顯著減少索引的大小, 還可能提升性能(解壓縮比從磁盤上加載一個比較大的source的性能要好)。 代碼需要特別注意,只有需要的時候才執行解壓縮, 例如直接將數據解壓縮到REST的結果流。 要啟用壓縮的話, 需要將`compress`選項設置為true, 默認設置是false。 注意可以在已經存在的索引上修改,ES支持壓縮和未壓縮的數據混合存放。 另外,`compress_threshold`可以控制壓縮source的時機,可以設置為表示字節大小的值(比如100b, 10kb)。 注意`compress`應該設置為true。 includes / excludes 可以用path屬性來包含/排除source中要存儲的字段,支持*通配符,例如: ``` { "my_type" : { "_source" : { "includes" : ["path1.*", "path2.*"], "excludes" : ["pat3.*"] } } } ``` _all === `_all`字段的設計目的是用來包羅文檔的一個或多個字段, 這對一些特定的查詢非常有用, 比如我們要查詢文檔的內容, 但是不確定要具體查詢哪一個字段, 這會占用額外的cpu和索引容量。 `_all`字段可以完全禁止掉, field mapping和object mapping可以聲明這個字段是否放到`_all`中。 默認所有的字段都包含在`_all`中。 禁用`_all`字段時, 推薦為`index.query.default_field`設置一個值(例如, 你的數據有一個"message"字段來存儲主要的內容, 就設置為`message`)。 `_all`字段一個很有用的特征是可以把字段的boost等級考慮進去, 假設title字段的boost等級比content字段高, `_all`中的title值也比`_all`中的content值等級高。 以下是一個配置的例子: ``` { "person" : { "_all" : {"enabled" : true}, "properties" : { "name" : { "type" : "object", "dynamic" : false, "properties" : { "first" : {"type" : "string", "store" : "yes", "include_in_all" : false}, "last" : {"type" : "string", "index" : "not_analyzed"} } }, "address" : { "type" : "object", "include_in_all" : false, "properties" : { "first" : { "properties" : { "location" : {"type" : "string", "store" : "yes", "index_name" : "firstLocation"} } }, "last" : { "properties" : { "location" : {"type" : "string"} } } } }, "simple1" : {"type" : "long", "include_in_all" : true}, "simple2" : {"type" : "long", "include_in_all" : false} } } } ``` 在這個例子里, `_all`字段設置了`store`, `term_vector`和`analyzer`(指定`index_analyzer`和`search_analyzer`)。 highlighting 任何可以highlighting的字段必須既是stored的,又是`_source`的一部分,默認`_all`字段不符合這個條件, 所以它的highlighting不會返回任何數據。 盡管可以設置`_all`為stored, 但`_all`從根本上說是所有字段的集合, 也就是說會存儲多余的數據,它做highlighting可能產生怪怪的結果。 _analyzer === `_analyzer` mapping可以將document某個字段的值作為索引時所用analyzer的名字,如果一個字段沒有顯式指定`analyzer`或者`index_analyzer`, 索引時就會用這個analyzer。 下面是配置的例子: ``` { "type1" : { "_analyzer" : { "path" : "my_field" } } } ``` 上面的配置用`my_field`字段的值作為analyzer, 比如下面的文檔: ``` { "my_field" : "whitespace" } ``` 會讓所有沒有指定analyzer的字段用`whitespace`做索引的analyzer。 path的默認值是`_analyzer`, 所以可以給`_analyzer`字段賦值來指定一個analyzer, 如果需要自定義為別的json字段, 需要通過path屬性來明確指定。 默認`_analyzer`字段是可索引的, 可以在mapping中將`index`設置為`no`來禁用。 _boost === Boosting是增強文檔或者字段關聯性的過程,字段級別的mapping可以將boost指定為某個字段。 `_boost`(應用在root object上)可以指定一個字段,這個字段的內容控制文檔的boost級別。 例如下面的mapping: ``` { "tweet" : { "_boost" : {"name" : "my_boost", "null_value" : 1.0} } } ``` 上面的定義指定了一個名為字段`my_boost`的字段, 如果要索引的JSON文檔包括my_boost字段, 字段的值就作為文檔的boost值, 比如下面的JSON文檔的boost值為2.2: ``` { "my_boost" : 2.2, "message" : "This is a tweet!" } ``` (注:name屬性默認是`_boost`) _parent === `_parent`用來定義子類型所關聯的父類型, 比如有一個`blog`類型和一個`blog_tag`子類型, `blog_tag`的mapping應該是: ``` { "blog_tag" : { "_parent" : { "type" : "blog" } } } ``` `_parent`默認是stored以及indexed的, 也就是說可以用`_parent`來查詢。 _routing === `routing`是索引數據或者需要明確指定路由時routing的設置。 store / index `_routing`的mapping默認會存儲routing的值(`store`設置為`yes`), 之所以這么做是為了可以在routing值來自外部而不是document一部分時仍然可以重建索引。 required 另一方面, 可以在`_routing`的mapping中設置`required`屬性為`true`來將它設置為必需的,這在使用routing功能是非常重要, 因為很多接口會用到它。 如果沒有提供routing值(或者不能從document獲取)的話,索引操作就不會執行,再比如如果`_routing`是必須的但是沒有提供routing值的話,刪除操作就會廣播到所有的分片(shards)上。 path routing的值可以在索引時額外提供(並且作為document的一部分存儲, 和`_source`字段存儲方式很像), 也可以根據`path`自動從要索引的document提取, 例如下面的mapping: ``` { "comment" : { "_routing" : { "required" : true, "path" : "blog.post_id" } } } ``` 會使下面的document基於值`111222`來路由: ``` { "text" : "the comment text" "blog" : { "post_id" : "111222" } } ``` 注意, 使用`path`而不是明確提供routing值的話, 索引時需要額外的解析過程(盡管相當快)。 id uniqueness 如果自定義`_routing`的話, 不保證`_id`在所有分片(shards)的唯一性。 事實上, 如果document的`_id`相同而`_routing`值不同的話, 會被分配到不同分片上。 _index === `_index`存儲一個document屬於哪一個索引(index), 該字段默認是禁用的, 如果要啟用的話, mapping的定義如下: ``` { "tweet" : { "_index" : { "enabled" : true } } } ``` _size === `_size`字段自動存儲原始`_source`的大小, 默認是禁用的, 要啟用的話mapping定義如下: ``` { "tweet" : { "_size" : {"enabled" : true} } } ``` 如果還要存儲的話, 定義如下: ``` { "tweet" : { "_size" : {"enabled" : true, "store" : "yes"} } } ``` _timestamp === `_timestamp`字段允許自動索引一個document的時間戳, 它可以在索引請求時提供, 也可以從`_source`提取,如果沒有提供的話會自動設置為document被處理的時間。 enabled `_timestamp`默認是禁用的, 如果要啟用, mapping的定義如下所示: ``` { "tweet" : { "_timestamp" : { "enabled" : true } } } ``` store / index 默認`_timestamp`字段的`store`設置為`no`, `index`設置為`not_analyzed`, 它可以當做一個標准的日期字段來查詢。 path `_timestamp`的值可以在索引請求時額外提供, 也可以根據`path`自動從document中提取, 例如下面的mapping定義: ``` { "tweet" : { "_timestamp" : { "enabled" : true, "path" : "post_date" } } } ``` 提交的數據為 ``` { "message" : "You know, for Search", "post_date" : "2009-11-15T14:12:12" } ``` 時間戳的值就是`2009-11-15T14:12:12`。 注意, 如果用`path`方式而沒有明確提供時間戳的值的話, 索引時需要額外的解析操作(盡管相當快)。 format 你可以定義時間戳的格式, 例如: ``` { "tweet" : { "_timestamp" : { "enabled" : true, "path" : "post_date", "format" : "YYYY-MM-dd" } } } ``` 注意, 默認的格式是`dateOptionalTime`, 時間戳的值首先作為數字解析, 如果解析失敗的話會嘗試用定義的格式解析。 _ttl === 很多documents有過期時間, 可以設置`_ttl`(time to live)來自動刪除過期的documents。 enabled `_ttl`默認是禁用的, 要啟用的話, mapping定義如下: ``` { "tweet" : { "_ttl" : { "enabled" : true } } } ``` store / index 默認`_ttl`字段的`store`設置為`yes`, `index`設置為`not_analyzed`, 注意`index`必須設置為`not_analyzed`。 default 可以為index/type設置默認的`_ttl`, 比如: ``` { "tweet" : { "_ttl" : { "enabled" : true, "default" : "1d" } } } ``` 這種情況下, 如果你沒有明確提供`_ttl`的值, `_source`里也沒有`_ttl`的話, 所有的tweets的`_ttl`會被設置為一天。 如果你沒有指定時間的單位,比如d (days), m (minutes), h (hours), ms (milliseconds), (weeks), 默認把毫秒(milliseconds)作為單位。 如果沒有設置默認值, 也沒有提供`_ttl`的值, document會有無限的`_ttl`,即永不過期。 可以用put mapping接口動態更新`default`的值, 這不會改變已有documents的`_ttl`, 只會影響新的documents。 note on documents expiration 過期的documents會自動定期刪除, 可以根據你的需要來設置`indices.ttl.interval`, 默認是60s。 刪除命令是批量處理的, 可以根據你的需要來設置`indices.ttl.bulk_size`, 默認是10000。 注意, 刪除是根據版本來的, 如果document在收集過期的documents和執行刪除操作的時間間隔之間被修改了, document是不會被刪除的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM