# 解決 Elasticsearch IK analyzer 短詞搜尋不到長詞的問題 ## 遇到的問題 文本內有 `官方網站` 這個詞,但在搜尋時卻沒辦法用 `官方` 找到該文檔。 ## 主要原因 會有這個問題產生,在於文本被索引的詞。目前自訂的字典檔內有的大量的詞,包含短詞和短詞延伸的長詞,而原本的分詞方法是用 `ik_smart`,搜尋方法也是使用`ik_smart`,會使得多數的長詞會被索引,短詞會被忽略。如上述問題,文本中如果出現`官方網站`,搭配現有的字典檔,分詞後的結果會是`官方網站`,也只有單一長詞的索引,如此一來就沒辦法使用`官方` 去搜尋到這文檔。 ## 解決方法 改變分詞的方法,從原本索引分詞的方法 `ik_smart` 改用 `ik_max_word`,搜尋方法依舊使用 `ik_smart`。 因為使用 `ik_max_word` 建立索引時,會將 `官方網站` 分為 `官方網站`、`官方`、`網站`,會有較多的詞被索引,如此一來就可以增加短詞被搜尋到的機率。 如此就可以透過 `官方` 或 `網站` 或 `官方網站` 搜尋到有 `官方網站` 的文檔。 --- 為了測試這解決方法是否真的有效,且不影響現有的服務下,先利用 Elasticsearch 中 `copy_to`,這個方法。透過更新 Index Mapping,將目前的欄位,複製到新的欄位,而新的欄位使用新的分詞方法。再重新索引部分資料,做測試。 透過指定不同的搜尋欄位,可測試不同情況下,搜尋結果是如何。 **透過測試不同的關鍵詞,結果為新的方法跟現有的方法文檔量成長了約 2-3成** --- ### copy_to 用來將一個或多個欄位值複製到另一個指定的目標欄位中。該目標欄位可以用於搜尋、聚合或排序等操作,以便在多個欄位中查找相關的資料。簡化查詢操作並提高性能。例如,可以將多個使用者的姓名、電話號碼和電子郵件地址合併到一個目標欄位中,然後對該欄位進行全文搜尋或聚合操作,以查找符合特定條件的使用者。 以下範例,是當文檔中的 `title`, `content` 欄位發生更改時,它們的值都將自動複製到 `new_content` 欄位中。然後,可以透過對 `new_content` 欄位進行搜尋、聚合或排序操作,以查找符合特定條件的文件。 ``` PUT /<index_name>/_mapping { "properties": { "title": { "analyzer": "ik_smart", "copy_to": [ "new_content" ], "type": "text" }, "content": { "analyzer": "ik_smart", "copy_to": [ "new_content" ], "type": "text" }, "new_content": { "analyzer": "ik_max_word", "search_analyzer": "ik_smart", "type": "text" } } } ``` ### Query 設定不同的搜尋欄位 - 現有方法 ``` /<index_name>/_search { "query": { "query_string": { "query": "網站", "fields": ["title", "content"] } } } ``` - 新方法 ``` /<index_name>/_search { "query": { "query_string": { "query": "網站", "fields": ["new_content"] } } } ```