
該文章同步發佈於:我的部落格
也歡迎關注我的 Facebook 以及 Instagram 接收軟體相關的資訊!
上一篇文章 中,介紹了 term level 的查詢,其實還有一些比較有趣的查詢,像是查詢某個欄位是否存在的資料、或是使用 prefix、wildcard 以及 regular expression 的方式查詢特定字串,但因為使用方式算簡單,也沒什麼特別需要注意的地方,就略過不談。
只是需要注意的是,在查詢某個欄位是否存在時,要想到,什麼樣的資料不會被儲存的搜尋的資料之中。
舉例來說,像是在建立 mapping 時,選擇 keyword 類型的欄位,可以搭配 ignore_above 的參數,當 keyword 的長度超過某個值時,就不會加入到 inverted index 之中,意思就是不會被真正地 index。
還有像是空的 [] 或是 Null 都不會被加入到 inverted index 之中,但 "" 是會的,這是比較有趣的地方。
接著我們就要介紹 Full Text Query ( 全文搜尋 ),主要是拿來搜尋那些沒有結構化的資料,常見的使用場景是部落格的內文、Email 的內容、聊天紀錄等等,也是 Elasticsearch ( 以下簡稱 ES ) 最常做的事情。
這種搜尋方式和 term level query 的差別就在於它的搜尋字詞會被 Analyzer 給處理過,如果設定的是 Standard Analyzer 那就會被拆解成一個個的 token 並且轉成小寫,接著拿去和 inverted index 做檢查,找到擁有這些字詞的 documents。
忘記 Analyzer 是什麼?可以參考 這裡
直接來看看如何使用,以及和 term level 的查詢到底有什麼不同?
這次使用的是 match 不是 term,告訴 ES 我們要用全文搜尋!
// GET /movies/_search
{
"query": {
"match": {
"title": "beautiful"
}
}
}
接著會得到 4 筆電影資料,title 都有包含 beautiful 的單字。

如何證明這和 term level 的查詢是不同的呢?
我們把搜尋的單字改成全大寫,因為在 term level 的查詢下,搜尋的字詞並不會被 tokenize,所以就不會匹配的 inverted index 的 key,複習請看 上一篇文章,所以故意用這樣的方式來直接檢測和 term level 的查詢差別:
// GET /movies/_search
{
"query": {
"match": {
"title": "BEAUTIFUL"
}
}
}
結果不會有任何的改變,從反方向就可以證明,確實是有經過 tokenize 的過程,才可以對應到正確的 documents。

接著搜尋多個單字也是搜尋時常見的做法,我們試試看:
// GET /movies/_search
{
"query": {
"match": {
"title": "beautiful mind"
}
}
}
得到的結果會比單純搜尋 beautiful 來得更多,達到 7 筆。

為什麼會變多呢?很好理解!搜尋的字詞經過 tokenize 之後,會變成:
["beautiful", "mind"]
接著只要 inverted indices 中有對應到這 2 個 key 的 documents 都會被撈出來。
但這可能會讓你覺得不是你要的搜尋結果,對吧?
我們常常會希望,多加一個字詞,就是希望更精準地匹配到想要的資料,這時候會有這樣的結果是因為 ES 預設的搜尋條件是 OR,也就是找到有 beautiful 或是有 mind 這兩個 key 的 documents。
這時候我們可以接入 operator 的參數來調整:
// GET /movies/_search
{
"query": {
"match": {
"title": {
"query": "beautiful mind",
"operator": "and"
}
}
}
}
確實就剩下 1 筆資料了!

當然全文搜尋也可以使用在日期或是數字的搜尋上,但我建議是,如果可以知道輸入對應的欄位,就盡量使用 term level 的搜尋方式來搜尋日期或是數字,因為更精準,而且日期或是數字基本上不需要經過 tokenize 這一個步驟。
對了!我說過不要拿 term level 的查詢去操作 text 的資料類型欄位,反之,不要拿 full text 查詢去操作 keyword 的資料類型欄位,因為會被 tokenize 導致對應出來的結果和你想像的不同。
其實真正的重點都圍繞在 Analyzer 以及 Inverted Index,這也是為什麼我會放在搜尋之前的章節介紹,而不是開門見山就討論搜尋怎麼使用,這很容易讓人不理解為什麼。
這兩個概念基本上左右了整個 ES 搜尋的方向,非常重要,一定要想辦法理解!