
該文章同步發佈於:我的部落格
也歡迎關注我的 Facebook 以及 Instagram 接收軟體相關的資訊!
上一篇文章 介紹完 analyzer 之後,還是要來實際地使用看看 API,這篇文章也會順便解釋一下 Inverted indices 是什麼?
使用起來非常簡單,這是 Elasticsearch ( 以下簡稱 ES ) 提供我們測試內容分析後結果的一個 API。
使用 POST /_analyze 接著輸入要被分析的語句,這邊使用一部電影的台詞做示範:
No point in punching things you can’t see.” Cinderella Man (2005) – James Braddock ( Russell Crowe )
然後使用的 analyzer 是 standard,根據 上一篇文章 中有提過 analyzer 的三個組件,這邊預設的 standard 是使用哪三個呢?別急,我們等等會做個實驗。
下圖就是送出請求後得到的回覆:

一張圖片沒辦法截完,但每一個 token 的結構都是長下面這樣:
{
"token": "in",
"start_offset": 9,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 2
}
除了 token 本身的 in 之外,還可以看到一些額外的 metadata,像是 start_offset 以及 end_offset 就提供了該 token 在原始詞句中的位置,這有助於 ES 提供一些有趣的功能,像是文字的 highlight。
而 type 則是這個 token 在這個 tokenizer 底下被分配的類別,以 standard 的 analyzer 來說,主要有 ALPHANUM , NUM , IDEOGRAPHIC 這幾種類型,但具體還是需要看使用的 tokenizer 提供什麼樣的 type。
好的,現在對於使用 analyze 的 API 應該是有一點概念了,接著我們可以把 analyzer 拆分成三個組件去呼應 上一篇文章 提到的內容,如下圖:

回應的結果還是和原本的一模一樣,你可以自己試試看!
這樣我們就知道,standard 的 analyzer 的組成是:
standard 的 tokenizer
lowercase 的 token filter ( 這邊 API 的 payload 直接使用 filter 就可以了 )所以基本上所有的分析核心都是在 standard 的 tokenizer 裡面,那它到底做了什麼呢?簡單來說大概就三點:
@ 就不會被移除。在知道 Analyzer 以及如何使用 analyze API 之後,就要把這些 tokens 給儲存起來,關於 text 的資料類型,ES 是使用 Inverted indices 的資料結構去儲存的。
俗稱倒排索引,也可以叫做反向索引,至於反在哪?往下看就知道了。
主要就是在紀錄 單字 以及 documents 之間的關聯。
舉一個簡單的例子,My name is Robert. 這段句子,經過基本的分析過後,會變成:
["my", "name", "is", "robert"]
這時候,ES 就會建立一個本子,記錄下來這樣的格式:

這樣大概對於為什麼叫做 反向索引 有一點感覺了吧?正常邏輯下的索引都會以 document 為主體,去儲存它含有哪些單字,但那樣對於全文搜尋來說太慢太弱了,反向索引 才是典型搜尋引擎演算法中重要的一個部分。
接著假設繼續加入一些資料,像是 Robert is a man 以及 That is a good name 這兩個句子好了。
結構圖就會變成這樣:

這時候,當我們搜尋 robert 時,ES 就會知道 document#1 以及 document#2 裡面有這個單字。
現在你可能會有點疑惑,這些資料到底在指什麼呢?我們現在討論的脈絡都是在 document 上的某一個欄位,像是上面這三個句子,可以是 Chats 這個 index 其中 3 個 documents 的 message 欄位。
//document#1
{
...
"_source": {
"message": "My name is Robert."
}
}
// document#2
{
...
"_source": {
"message": "Robert is a man"
}
}
// document#3
{
...
"_source": {
"message": "That is a good name"
}
}
但是我們的資料一定不會是只有一個欄位,很多個欄位時,ES 怎麼做呢?它會根據欄位來區分 inverted index,我把下圖補上一個 title 就會一目暸然:

那不同的 index 之間有相同的欄位呢?
這個就完全不相關了,就算兩個 index 內都有 message 的欄位,自然而然就會有兩份 inverted index 在不同的 index 中,所以是各自維護和獨立運作的。
我知道有點饒舌,但沒辦法,就是這麼多 index。
下一篇文章,會介紹到 Mapping 這個概念,也會帶入資料的類型一起討論。
記住我們現在討論的 inverted index 都是作用在 text 的資料類型上,可以暫時想像成關聯式資料庫的 string 或是 text,總之其他的資料類型並不是使用 Inverted index 做儲存。