Lucene 查詢中的距離查詢(proximity query)
我們在使用 ELK 的時候,使用 Lucene querystring 語法的機會,遠超過使用 Elasticsearch 的 query DSL。畢竟在搜尋框裡寫語法比自己拼 JSON 簡單多了。
不過一般我們用的 querystring 語法總是最簡單的幾樣:
text
key:value
key:"term"
k1:v1 AND NOT k2:v2
80% 的情況下,這幾個用法也就足夠了。但總有剩下的 20% 的情況,還是需要我們來了解一些更復雜的語法。
舉一個還算通用的場景:我們在 ELK 裡索引了訪問日誌。這時候需要查一下以 /api/login
開頭的
URL 們的情況。
我們沒法確定 URL 裡是不是隻有 /api/login
/api/oauth/login
呢?沒準可能還有 login/weibo/api
呢?
一般來說,日誌進 ELK 都是採用標準分詞器的。而很巧,/
就是標準分詞器的停止詞之一。所以,我們在搜尋框裡寫 api/login
等效於 api
login
。那麼太多可能都可以命中了。
這個時候,Lucene 查詢語法裡的距離查詢(proximity query)就可以幫忙了:
url:"api login"
看起來很簡單,無非是給加了一對雙引號?!
沒錯,加引號以後,意味著這個短語查詢必須是有序的,即只能命中先出現api,再出現login的文字了。這下就把 login/weibo/api
其次,Lucene 距離查詢預設的距離為 0,即只能命中出現api之後,下一個term必須為login的文字了。這些就把 /api/oauth/login
也排除了。
當然,如果這時候你日誌裡除了 api/login
還有 api,login
之類的文字,也是會命中的。不過在
url 欄位裡出現這個的概率不大,可以無視了~
如果你要搜的就是 /api/oauth/login
,但是你不記得中間這個是不是
oauth,也可能是其他的吧,怎麼辦?
url:"api login"~1
後面加波浪線和距離即可。