ElasticSearch裡面一些小坑筆記

FeelTouch發表於2019-04-30

最近線上的es報了一個異常,核心資訊如下:

我們的es索引是巢狀索引,上面的這個異常大致意思是說在某個shard裡面巢狀結構裡面 k1.k2.time這個欄位不存在資料,所以排序失敗。

我們知道在ES裡面可以分shard和索引,大多數時候我們es索引都是自動按某個規則建立的,比如說按天,按月,按年,這個用過logstash的同學應該都比較熟悉,收集的log基本上都是按天生成索引的,然後我們用kibana查詢或者自己寫程式碼查詢。

下面看總結一些問題場景:

(場景1)查詢一個不存在的索引

預設情況下,查詢一個不存在的索引是會報異常的(no such index....) ,那麼如何避免這個問題呢?

有兩種辦法:

A:每次查詢前去使用es的索引api判斷這個索引存在不存在,如果不存在就不進行任何操作,存在的話在執行查詢,這樣就能避免,但這樣的問題就是每次都得判斷存在不存在多一次查詢互動。

B:在構建查詢時,使用萬用字元標識索引,如果這個索引不存在,查詢結果就是空,但是不會報異常,這樣比較方便,不需要關注存在不存在問題。

一個java api的例子如下:

如上程式碼,查詢這個不存在的索引,這段程式碼結果不會報錯,推薦使用這種方法。

(場景2)查詢一個不存在的欄位

查詢一個不存在的欄位es是不會報錯的

(場景3)排序一個不存在的欄位

預設情況下,排序一個不存在的欄位,在es裡面也會報錯。這裡主要分三種情況:

A:排序的單個索引不存在這個欄位

B:排序的單個索引存在這個欄位,但是它分shard了,如果有3個shard,只有2個shard上有這個欄位,另外一個shard上沒有這個欄位,那麼它同樣會報異常

C:跨索引查詢,如果跨2個索引,一個索引上所有的shard都包含這個欄位,另外一個索引有部分shard沒有,那麼也會出現這個問題

如何解決:

這個也比較好解決,在排序的時候,需要設定在maping裡面不存在的裡面,應該如何處理,容錯程式碼如下:

注意unmappedType方法了,定義這個值不存在的時候,預設按什麼型別處理。

(場景4)在一個不存在的欄位上算count,max,min,sum,avg這些指標

求聚合統計這些指標時,也不會報錯,但結果值列有不同,詳情如下:

(場景5)分組一個不存在的欄位

分組一個不存在的欄位,也不會報錯,返回結果是空

上面這些場景基本涵蓋了查詢統計大多數的可能出現的問題,需要我們在使用的時候需要注意一下,避免一些不必要的問題。

最後我們來介紹一下es裡面一個有用的查詢Exists Query:

功能:查詢的欄位至少有一個非null值才回返回

我們來看官網給的一個例子:

上面這個查詢是查欄位user的資料,是不是為空,注意下面的這些資料,是可以被匹配上

在來看下,那些情況,不能被匹配:

此外,Exists Query可以非常方便的替代Miss Query看下面的例子:

上面這個查詢將返回沒有user欄位的資料,java api寫法如下:

注意,經過測試發現一個巢狀索引裡面,如果只有一個為空的陣列,然後使用巢狀查詢Exists Query是會報錯的,而使用平鋪的Exists Query是不會報錯的,也就是說,巢狀的索引裡面必須有一個不為空的物件存在,才能使用Exists Query查詢語法,來查詢相關欄位不存在的資料 否則會報錯,這一點目前還沒看到有任何好的辦法來校驗多級巢狀結構下的某個索引裡面到底存不存在某個巢狀結構,巢狀索引的判斷是否存在大致一樣 唯一需要注意到是,巢狀結構,一定有一條不為空的資料存在才行

轉自:https://cloud.tencent.com/developer/article/1122434

相關文章