# 解決 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"]
}
}
}
```