1. 程式人生 > >Lucene 查詢中的距離查詢(proximity query)

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

後面加波浪線和距離即可。