一起来学ES —— 浅谈Nested结构
生活随笔
收集整理的這篇文章主要介紹了
一起来学ES —— 浅谈Nested结构
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Nested是什么?
- 直觀的說,Nested實際上就是Object的數組。如下,這個user就是個nested結構 { "user" : [ {"first" : "John","last" : "Smith"},{"first" : "Alice","last" : "White"} ] }
Nested 和 Object 是什么關系?
- ES原生支持Object類型,也就是任意字段都可以是個對象,而ES又是所有字段都是多值,也就是都可以是list。那么在ES中Nested和Object List又是什么關系呢?
- 這就要從Object說起了。Object雖然是個對象,但是實際存儲時是在當前文檔里打平存儲的。如上那個例子,如果只有一個user,那么在真實索引中實際上是下面這樣的
- 而如果是個list,那么就成了
- 因為建索引時打平,因此檢索時ES就無法知道到底是John Smith還是John White了。因此引入了Nested結構。
- Nested將list里的每個doc單獨變成子文檔進行存儲,因此在查詢時就可以知道具體的結構信息了。
Nested 查詢要注意什么?
- Nested因為是單獨的子文檔存儲,因此在使用時,直接用?a.b.c?是無法訪問的,需要將其套在nested查詢里。除此之外,和其他的查詢并無差異。
- 如上所示,用一個nested套住真實query即可。默認的hit是返回父文檔,也就是大的doc。如果加上inner_hits會在父文檔的source中多一個inner_hits的字段,返回真實命中的object,其中有個offset表明list數組下標。
- 需要注意的是,由于單獨存儲很耗資源,因此默認一個index最多只有50個nested字段。此外,雖然nested是單獨存儲的,但是其字段數也算入index總字段數,默認最多1000個。
Nested Aggregation是什么?
- 對于Nested結構,有一點需要謹記的,就是他是個List結構。Nested Agg就是對這個list做agg操作,agg寫法和普通的一樣,只需要在外面套上nested即可。
- 如官方文檔的例子,就是一個商品有許多賣家,對這些賣家的報價求最小值。
能否用Nested做動態kv?
- Nested除了存儲固定的Object List,還有一種常用的場景就是用來存儲動態的KV。雖然ES天然支持dynamic mapping,但是其key都是固化在每一個doc中的,如果存儲用戶自定義報表數據。每個用戶的key差異很大,放在同一張表會出現大量空值。這是很浪費系統資源的行為,并且隨著Key的不斷增多,最終會超出index的最大key數量。
- 因此用nested結構來處理這種動態kv就比較合適。 nested的本質就是將?{"tags":{"k1":"v1","k2":"v2"}}=>{"tags":[{"key":"key1","value":"v1"},{"key":"key2","value":"v2"}]}
- 這樣一來就可以輕松處理動態kv。并且查詢依舊簡單,例如k1:v1 AND k2:v2變為
動態kv如何做agg呢?
- 普通查詢的確很簡單,但是agg就并不簡單了。原來的模式可以直接用真實字段tags.k1做agg,但是在nested里k1已經變成了一個字段的值,因此沒法直接做agg了。
- 這時就需要引入script大法了。其實agg的本質就是從每個doc的正排里取一個值,用這個值做聚合。因此我們只需要用script遍歷list,找到對應的key然后返回其value即可。
- 簡單寫了個如下所示,如果有更好的方法歡迎留言。
- 注意!!! 由于nested單獨存儲,因此doc里并沒有nested數據,需要用params從source中拿。性能很差,僅可用于少量數據場景!
- 在使用中我們還可以把script存在來,來加速運算,減少緩存。(注意:5.6以后將code改為了source字段,具體寫法參閱文檔)
- 這樣用起來就簡單多了
怎么在kibana里做agg呢?
- kibana其實和上面的一樣,也是用script.不過只支持inline的,在script field配置。不過注意一定不能太多,因為每一個inline script都是一個單獨的script都需要消耗存儲資源。
參考資料
- nested datatype
- nested query
- nested agg
- How to use scripts
- painless DEBUG
版權聲明
- 自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證)
- 本文首發于:?http://czjxy881.coding.me/
總結
以上是生活随笔為你收集整理的一起来学ES —— 浅谈Nested结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 国内流量畅享是什么意思(图文)
- 下一篇: 关于es查询dsl的filter与mus