天天看點

大神都這麼做,讓 Kibana 搜尋文法 query string 也能輕松上手

作者介紹

魏彬,普翔科技 CTO,開源軟體愛好者,中國第一位 Elastic 認證工程師,《Elastic日報》和 《ElasticTalk》社群項目發起人,被 elastic 中國公司授予 2019 年度合作夥伴架構師特别貢獻獎。對 Elasticsearch、Kibana、Beats、Logstash、Grafana 等開源軟體有豐富的實踐經驗,為零售、金融、保險、證券、科技等衆多行業的客戶提供過咨詢和教育訓練服務,幫助客戶在實際業務中找準開源軟體的定位,實作從 0 到 1 的落地、從 1 到 N 的拓展,産生實際的業務價值。

用過 Kibana 的同學應該都注意過其頂部的搜尋框,像下圖這樣。

大神都這麼做,讓 Kibana 搜尋文法 query string 也能輕松上手

這個輸入框接受符合 query string 文法的查詢語句。在日常開發中我們常用的都是 elastic query dsl(domain specific language),都是 json 格式的,像下面這個簡單的查詢語句。

{
    "query":{
        "match":{
            "name":"elastic"
        }
    }
}           

這個查詢如果用 query string 來表示的話,如下所示:

ame:elastic

看起來是不是簡潔了很多呢?對于 kibana 這種 UI 界面,輸入越是簡單,越是接近自然語言,對于使用者也就越是友好,是以 kibana 的搜尋框預設選擇了 query string 的搜尋文法。雖然 query string 展示起來簡潔了很多,但是要用好卻沒有那麼簡單,如果不好好閱讀官方文檔并做實驗,那你會吃不少苦頭。下面我就來幫大家掃清障礙。

注解:如果非要用 query dsl 的話,kibana 也是支援的,你隻需要把 query 中的内容放到搜尋框中就可以了,比如上面的查詢語句,你隻要放下面的内容就可以查詢了。
{    
    "match":{    
        "name":"elastic"
    }
}           

由來

Elasticsearch 的 query string 其實就是 lucene 的 query language。elasticsearch 本身就是建構于 lucene 之上的,它支援 lucene 的 query language 也是很簡單的事情。那這個 query language 是怎麼來的呢?根據 lucene 文檔中介紹,雖然 lucene 已經提供了建構查詢條件的 API,但對于人類直接使用而言不夠友好和自然,是以 lucene 提供了這樣一種接近自然語言的查詢語言,友善人工輸入和記憶查詢條件。lucene 不鼓勵在代碼中直接使用 query language,因為它還要經過一層 query parser 的轉換,有性能損耗,另外 query language 也隻覆寫了一部分查詢 API,并不完備。

基本概念

這裡先講解兩個術語: single term 和 phrase。前者是指單個詞(分詞後的最小機關),後者指短語。舉例來說,word、sun 這些都是 single term,而用雙引号包裹起來 “word sun“ 就成了 phrase 。是以這兩者的差別在于 phrase 是由 term 組成的,包裹在雙引号中。而 phrase 中的詞在比對是有順序要求的,這也就是 elasticsearch 中 match query 和 match phrase query 的差別之一。

name:tom

如果不寫 name: ,隻寫 tom,那麼相當于執行 _all:tom 這個查詢。

另外 field 是有作用域的,隻對緊跟其後的 term 生效。

name:"Tom Lee"

上面這是一個 phrase 查詢,查詢比對 Tom Lee 的所有文檔。

name:Tom Lee

上面這個查詢實際等效于

name:Tom OR _all:Lee

這也是在實際使用中很多人容易踩坑的地方,使用的過程中要切記,否則查詢出的結果肯定不會如你預期的那樣。

如果你想對一個 field 指定複雜的查詢條件,那麼可以使用括号将查詢條件包起來用(field grouping)。比如下面的這個語句:

name:(tom lee)

等價于

name:(tom OR lee)

查詢 name 為 tom 或者 lee的所有文檔。

另外括号不僅可以作用在 field 上,還可以作用在外層的邏輯進行中。比如下面這種查詢組合也是支援的(大家先忽略還沒有講到的操作符)。

(name:tom && age:10)||city:(shanghai beijing)

有心的讀者可能會發現為什麼 && 的語句還要加括号呢,它的優先級不是比 || 高嗎?我 也是這麼認為的,但動手測試後發現貌似 lucene 沒有實作這個優先級的解析,是以大家使用的時候注意括号的使用。

下面再講一下布爾操作符,大家對這個應該很熟悉了,比如 AND、OR、NOT等。這裡要注意的一點是:query string 中的布爾操作符必須大寫。如果小寫,比如 and、or、not,query解析器會把他們當做普通 term 解析。比如下面這個語句:

name:tom and age:10

上面的查詢實際對應下面的語句:

name:tom OR _all:and OR age:10

愛思考的同學看到上面的解釋應該就有疑問了。

“這個 OR 是從哪裡來的呢?”

這個 OR 是預設的布爾操作符,當多個查詢條件之間沒有指定布爾關系時,就會使用 OR。

另外可以用 && 和 ||* 分别代替 AND 和 OR,使得查詢語句更簡潔易懂。

NOT 就是非操作,簡寫符号為 !。用法如下:

name:(tom NOT lee)

查詢 name 為 tom,但不是 lee 的所有文檔。

除去 AND、OR、NOT ,query string 還支援 + 和 -,分别對應 must 和 must not 的含義。

name:(tom +lee -alfred)

上面的語句查詢 name 中 含有 lee,不含有 alfred,但可能含有 tom 的所有文檔。

大家可以想一下如果用 AND、OR、NOT 來重寫上面的語句是什麼樣子呢?

name:((lee && !alfred) || (tom && lee && !alfred))

你是不是發現 + 和 - 的好處了?

查詢功能

講完基礎概念,我們再來看看 query string 支援的幾個查詢功能。

範圍查詢 range search

數字、日期類型等都是可以指定範圍的,對于這類可以使用範圍查詢,閉區間用[],開區間用{}。舉幾個例子大家一看就明白了。

age:[1 TO 10] 意為 1<=age<=10
age:[1 TO 10} 意為 1<=age<10
age:[1 TO ] 意為 age>=1
age:[* TO 10] 意為 age<=10           

日期也是一樣的用法,隻要将數字替換為 2017-01-01 即可。

如果你覺得這樣寫太麻煩了,那可以使用簡略寫法,如下:

age:(>=1 && <=10) 或者 age:(+>=1 +<=10)
age:(>=1 && <10) 或者 age:(+>=1 +<10)
age:>=1
age:<=10           

通配符查詢 wildcard search

大家對于通配符應該都不陌生,有 ? 和 * 兩個,前者代表一個字元,後者代表0或多個字元。

name:t?m
name:tom*
name:t*m           

上面的使用方式都可以,但是不能把 ? 和 * 放在最前面,因為這會導緻 elasticsearch 将所有的分詞都比對一遍,效率低下。

通配符查詢的效率很低,也會占用較多的記憶體(因為要把所有符合條件的分詞進行比對),建議大家謹慎使用。

正則查詢 regular expressionsearch

正則查詢如同字面意義所講的,支援正規表達式進行比對。

name:/[mb]oat/

但這裡并不支援所有的正則文法,使用的時候要注意檢視官方文檔說明。另外正則查詢的記憶體壓力也很大,要謹慎使用。

模糊查詢 fuzzy search

所謂模糊查詢是指允許搜尋和比對的詞(term)之間有差異,比如搜尋 surprize,可以比對到surprise。

name:roam~

上面的語句會比對到 foam 和 roams,波浪号後面可以指定一個 0~2 的浮點值,用以表示模糊度,我在實際使用中用的不多,就不展開來講了。

近似度查詢 proximity search

所謂近似度查詢是指在一個短語(phrase)中,詞(term)與詞之間距離的比對。

name:"tom lee"~2

比對時允許 tom 和 lee 之間有 2 個詞的距離,筆者用的也不多,是以不班門弄斧了。

提升查詢權重 boosting term

查詢時如果想改變某個查詢條件的權重,可以使用 ^ 來實作。

name:(tom^4 lee)

上面的查詢表示,當 name 中包含 tom 時,其權重是 lee 的4倍,這就意味着相應得分也會高,排序也會靠前。

特殊字元過濾

uery string 本身已經占據了一些關鍵字,如下

+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /

當遇到這些關鍵詞時,需要使用 做轉義,比如如果你要搜尋

(1+1):2

,那麼查詢條件需要寫成

\(1\+1\)\:2

總結

至此,query string就講完了,大家可以去愉快地和 kibana 玩耍了,遇到問題時歡迎和筆者我讨論哦~

參考文檔

1、

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax

2、

https://www.timroes.de/2016/05/29/elasticsearch-kibana-queries-in-depth-tutorial/

3、

http://lucene.apache.org/core/6_4_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package.description

4、

http://www.lucenetutorial.com/lucene-query-syntax.html
聲明:本文由原文《Kibana頂部的那個輸入框你知道怎麼用嗎?》作者“魏彬”授權轉載,對未經許可擅自使用者,保留追究其法律責任的權利。
大神都這麼做,讓 Kibana 搜尋文法 query string 也能輕松上手

阿裡雲Elastic Stack

】100%相容開源ES,獨有9大能力,提供免費X-pack服務(單節點價值$6000)

相關活動

更多折扣活動,請

通路阿裡雲 Elasticsearch 官網 阿裡雲 Elasticsearch 商業通用版,1核2G ,SSD 20G首月免費 阿裡雲 Logstash 2核4G首月免費
大神都這麼做,讓 Kibana 搜尋文法 query string 也能輕松上手
大神都這麼做,讓 Kibana 搜尋文法 query string 也能輕松上手