分析 包含下面的過程:
- 首先,將一塊文本分成適合於倒排索引的獨立的 詞條 ,
- 之後,將這些詞條統一化爲標準格式以提高它們的“可搜索性”,或者 recall
分析器執行上面的工作。 分析器 實際上是將三個功能封裝到了一個包裏:
1.字符過濾器
首先,字符串按順序通過每個 字符過濾器 。他們的任務是在分詞前整理字符串。一個字符過濾器可以用來去掉HTML,或者將 &
轉化成 `and`。
2.分詞器
其次,字符串被 分詞器 分爲單個的詞條。一個簡單的分詞器遇到空格和標點的時候,可能會將文本拆分成詞條。
3.Token 過濾器
最後,詞條按順序通過每個 token 過濾器 。這個過程可能會改變詞條(例如,小寫化 Quick
),刪除詞條(例如, 像 a`, `and`, `the
等無用詞),或者增加詞條(例如,像 jump
和 leap
這種同義詞)。
內置分析器
但是, Elasticsearch還附帶了可以直接使用的預包裝的分析器。 接下來我們會列出最重要的分析器。爲了證明它們的差異,我們看看每個分析器會從下面的字符串得到哪些詞條:
"Set the shape to semi-transparent by calling set_trans(5)"
標準分析器
標準分析器是Elasticsearch默認使用的分析器。它是分析各種語言文本最常用的選擇。它根據 Unicode 聯盟 定義的 單詞邊界 劃分文本。刪除絕大部分標點。最後,將詞條小寫。它會產生
set, the, shape, to, semi, transparent, by, calling, set_trans, 5
簡單分析器
簡單分析器在任何不是字母的地方分隔文本,將詞條小寫。它會產生
set, the, shape, to, semi, transparent, by, calling, set, trans
空格分析器
空格分析器在空格的地方劃分文本。它會產生
Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
語言分析器
特定語言分析器可用於 很多語言。它們可以考慮指定語言的特點。例如, 英語
分析器附帶了一組英語無用詞(常用單詞,例如 and
或者 the
,它們對相關性沒有多少影響),它們會被刪除。 由於理解英語語法的規則,這個分詞器可以提取英語單詞的 詞幹 。
英語
分詞器會產生下面的詞條:
set, shape, semi, transpar, call, set_tran, 5
注意看 transparent`、 `calling
和 set_trans
已經變爲詞根格式。
什麼時候使用分析器
當我們 索引 一個文檔,它的全文域被分析成詞條以用來創建倒排索引。 但是,當我們在全文域 搜索 的時候,我們需要將查詢字符串通過 相同的分析過程 ,以保證我們搜索的詞條格式與索引中的詞條格式一致。
全文查詢,理解每個域是如何定義的,因此它們可以做 正確的事:
- 當你查詢一個 全文 域時, 會對查詢字符串應用相同的分析器,以產生正確的搜索詞條列表。
- 當你查詢一個 精確值 域時,不會分析查詢字符串, 而是搜索你指定的精確值。
現在你可以理解在 開始章節 的查詢爲什麼返回那樣的結果:
date
域包含一個精確值:單獨的詞條 `2014-09-15`。_all
域是一個全文域,所以分詞進程將日期轉化爲三個詞條: `2014`, `09`, 和 `15`。
當我們在 _all
域查詢 2014`,它匹配所有的12條推文,因爲它們都含有 `2014
:
GET /_search?q=2014 # 12 results
當我們在 _all
域查詢 2014-09-15`,它首先分析查詢字符串,產生匹配 `2014`, `09`, 或 `15
中 任意 詞條的查詢。這也會匹配所有12條推文,因爲它們都含有 2014
:
GET /_search?q=2014-09-15 # 12 results !
當我們在 date
域查詢 `2014-09-15`,它尋找 精確 日期,只找到一個推文:
GET /_search?q=date:2014-09-15 # 1 result
當我們在 date
域查詢 `2014`,它找不到任何文檔,因爲沒有文檔含有這個精確日誌:
GET /_search?q=date:2014 # 0 results !
測試分析器
有些時候很難理解分詞的過程和實際被存儲到索引中的詞條,特別是你剛接觸 Elasticsearch。爲了理解發生了什麼,你可以使用 analyze
API 來看文本是如何被分析的。在消息體裏,指定分析器和要分析的文本:
GET /_analyze { "analyzer": "standard", "text": "Text to analyze" }
結果中每個元素代表一個單獨的詞條:
{ "tokens": [ { "token": "text", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 1 }, { "token": "to", "start_offset": 5, "end_offset": 7, "type": "<ALPHANUM>", "position": 2 }, { "token": "analyze", "start_offset": 8, "end_offset": 15, "type": "<ALPHANUM>", "position": 3 } ] }
token
是實際存儲到索引中的詞條。 position
指明詞條在原始文本中出現的位置。 start_offset
和 end_offset
指明字符在原始字符串中的位置。
analyze
API 是一個有用的工具,它有助於我們理解Elasticsearch索引內部發生了什麼,隨着深入,我們會進一步討論它。
指定分析器
當Elasticsearch在你的文檔中檢測到一個新的字符串域 ,它會自動設置其爲一個全文 字符串
域,使用 標準
分析器對它進行分析。
你不希望總是這樣。可能你想使用一個不同的分析器,適用於你的數據使用的語言。有時候你想要一個字符串域就是一個字符串域--不使用分析,直接索引你傳入的精確值,例如用戶ID或者一個內部的狀態域或標籤。