Neil Zhu,簡書ID Not_GOD,University AI 創(chuàng)始人 & Chief Scientist,致力于推進世界人工智能化進程。制定并實施 UAI 中長期增長戰(zhàn)略和目標,帶領團隊快速成長為人工智能領域最專業(yè)的力量。
作為行業(yè)領導者,他和UAI一起在2014年創(chuàng)建了TASA(中國最早的人工智能社團), DL Center(深度學習知識中心全球價值網(wǎng)絡),AI growth(行業(yè)智庫培訓)等,為中國的人工智能人才建設輸送了大量的血液和養(yǎng)分。此外,他還參與或者舉辦過各類國際性的人工智能峰會和活動,產(chǎn)生了巨大的影響力,書寫了60萬字的人工智能精品技術內(nèi)容,生產(chǎn)翻譯了全球第一本深度學習入門書《神經(jīng)網(wǎng)絡與深度學習》,生產(chǎn)的內(nèi)容被大量的專業(yè)垂直公眾號和媒體轉(zhuǎn)載與連載。曾經(jīng)受邀為國內(nèi)頂尖大學制定人工智能學習規(guī)劃和教授人工智能前沿課程,均受學生和老師好評。
關于elasticsearch filter bitset的全部
在使用ES進行查詢時,你常常會發(fā)現(xiàn)自己深深地陷入了過濾器的各種復合中。假設你需要過濾滿足下面要求的用戶:
bitset
首先需要看看bitset如何工作的。基本上,bitset是一個表示狀態(tài)的列表。每個位置非0即1.
過濾器不對文檔打分——僅僅是包含或者拒絕。如果文檔匹配了一個過濾器,則在bitset中會置成1;否則置為0.于是ES就可以在一個緊致的bitset中存儲整個分段的過濾信息。
ES第一次執(zhí)行過濾器時,他解析了Lucene的分段數(shù)據(jù)結(jié)構來判斷哪些東西匹配了你的過濾器。而且會將這個信息存放在一個Bitset中。
下次同樣的過濾器執(zhí)行時,ES可以找到壓縮后的Bitset而不是Lucene分段。這將帶來性能的巨大提升。
我喜歡bitset的原因
怎么說bitset快都不為過
按bit進行操作是一個基礎的計算單元,CPU專門設計為按照按bit操作的。執(zhí)行一個內(nèi)存中的按位AND比解析Lucene數(shù)據(jù)結(jié)構和手動地執(zhí)行交集操作要快好幾個數(shù)量級。
擁有多個過濾器時,可以進行AND操作來獲得最終匹配的文檔。
更好的是,bitset獨立于查詢本身進行cache。復雜的查詢可以用一堆過濾器,但是這些過濾器bitset是獨立的并且可以在其他的上下文環(huán)境中進行使用。這就使得ES重用過濾器非常高效。
而且因為bitset針對每個segment進行存儲,ES可以做出一些非??岬男阅芗记?。Lucene分段是不可變的——一旦寫入磁盤,便永不改變
如果一個特定的過濾器不匹配一個分段中的任何文檔(bitset中所有位置都是0),ES可以在其執(zhí)行過濾操作時忽略整個bitset。
類似的,當新的分段被加進來時,緩存的過濾bitset不需要被關閉。如果你索引新的文檔進入一個mysql表,例如B-Tree索引是不斷地進行更新的。
使用ES過濾器緩存,只有新創(chuàng)建的分段需要構建過濾器bitset,老的bitset可以不需要修改進行重用。
boolean 還是 and/or/not
“可是這跟我有啥關系呢?”你也許會問。
當然重要了,因為bool過濾器使用了Bitset而and/or/not過濾器沒有/如果你將一個term過濾器放入一個and中,盡管它存在,也不會用到Bitset。
為什么?
and/or/not是一個文檔一個文檔進行的。首先會載入需要放入field數(shù)據(jù)內(nèi)存池中,然后對這些文檔進行遍歷。不會有bitset被使用,也就不會有緩存的過濾器重用復合了。ES簡單地掃描文檔的列表,并獨立地檢查每個。
如果你有多個過濾器,and/or/not將進行短路操作,只會傳遞匹配的文檔進入下一個過濾器。
這個會降低每個后續(xù)的需要執(zhí)行的過濾器工作量。因此,你最重的過濾器應該放到最后位置——典型例子是Geo過濾因為他們會進行相當重的計算來確定距離。
什么時候使用and/or/not
看起來Bool過濾器在任何方面都超過了對手,那么有沒有什么時候需要使用and/or/not呢?
and/or/not在你使用哪些不返回bitset的過濾器時更有效率。這些操作肯定需要對每個文檔進行一遍。例如,定制的script不是可以bitset化,因為它對每個文檔進行計算。
在這些情形下,and/or/not是比bool更好的選擇。Non-Bitset過濾器非常少,下面列出來:
- Geo* filter
- Scripts
- Numeric_range
其他的過濾器都應該放在一個bool中
把bool和and/or/not結(jié)合起來
當你遇到需要用到這兩者的情形時,可以將他們合起來使用??偸鞘褂靡粋€and/or/not整合起來。例如,你有這樣的數(shù)據(jù):
- Gender: Male
- Age: 23-26
- Language: English
- Custom Script
- Geo
你過濾器列表看起來就是這樣:
{
"and" : [
{
"bool" : {
"must" : [
{ "term" : {} },
{ "range" : {} },
{ "term" : {} }
]
}
},
{ "custom_script" : {} },
{ "geo_distance" : {} }
]
}
總結(jié)
過濾器讓我們可以找到想要的文檔,通過使用bitset操作來代替簡單的排除操作來提高查詢性能。當我們整合過濾器時,確保你花了時間來考慮如何組織他們來使用合適的聚合過濾器的類:
- Geo, Script or Numeric_range filter: Use And/Or/Not Filters
- Everything else: Use Bool Filter