Elasticsearch Analyzer 分詞器是什麼,以及日語搜尋 token filter 簡介
Analysis 是 Elasticsearch 的一個概念,他可以將我們數據 寫入及查詢時,也會針對分詞做處理。
這些 analysis 的概念主要是由 Analyzer(分詞器) 來處理,主要做的事情包含:
Elasticsearch 內建包含 Alalyzer 可以透過過濾、變形、分詞方式把字句拆分成可以搜尋的索引,基本構成如下:
- Character filter: 可以將文字過濾,例如將文本的 HTML 內容進行過濾
- Tokenizer: 按照規則進行分詞處理,一個 analyzer 只需有一個 Tokenizer
- Token Filter: 將 Tokenizer 分詞進階處理,例如去掉一些詞語或轉換大小寫會類型
在 Elasticsearch 內置的分詞器包含:
分詞器名稱 | 處理方式 |
---|---|
standard analyzer | 預設分詞器,可以做分詞切分,小寫處理 |
simple analyzer | 按照符號切分(非字母),小寫處理 |
stop analyzer | 小寫處理,停用詞語過濾(the, a, this…) |
whitespace analyzer | 依照空白進行切分,小寫處理,並且不會過濾HTML |
keyword analyzer | 不分詞,直接輸入 |
pattern analyzer | 正則表達式,預設使用 \W+(非字符串分隔) |
在了解分詞的運作方式之後,接下來我們就針對這些分詞器來進行範例演練:
standard analyzer
預設分詞器:
GET _analyze
{
"analyzer": "standard",
"text":"hello for 2 <b>in your</b> why-not?"
}
處理結果,可以看到所有字串都會進行拆分,如下:
{
"tokens" : [
{
"token" : "hello",
"start_offset" : 0,
"end_offset" : 5,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "for",
"start_offset" : 6,
"end_offset" : 9,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "2",
"start_offset" : 10,
"end_offset" : 11,
"type" : "<NUM>",
"position" : 2
},
{
"token" : "b",
"start_offset" : 13,
"end_offset" : 14,
"type" : "<ALPHANUM>",
"position" : 3
},
{
"token" : "in",
"start_offset" : 15,
"end_offset" : 17,
"type" : "<ALPHANUM>",
"position" : 4
},
{
"token" : "your",
"start_offset" : 18,
"end_offset" : 22,
"type" : "<ALPHANUM>",
"position" : 5
},
{
"token" : "b",
"start_offset" : 24,
"end_offset" : 25,
"type" : "<ALPHANUM>",
"position" : 6
},
{
"token" : "why",
"start_offset" : 27,
"end_offset" : 30,
"type" : "<ALPHANUM>",
"position" : 7
},
{
"token" : "not",
"start_offset" : 31,
"end_offset" : 34,
"type" : "<ALPHANUM>",
"position" : 8
}
]
}
simple analyzer
按照符號切分(非字母),小寫處理:
GET _analyze
{
"analyzer": "standard",
"text":"hello for 2 <b>in your</b> why-not?"
}
處理結果,可以看到數字已經消失,如下:
{
"tokens" : [
{
"token" : "hello",
"start_offset" : 0,
"end_offset" : 5,
"type" : "word",
"position" : 0
},
{
"token" : "for",
"start_offset" : 6,
"end_offset" : 9,
"type" : "word",
"position" : 1
},
{
"token" : "b",
"start_offset" : 13,
"end_offset" : 14,
"type" : "word",
"position" : 2
},
{
"token" : "in",
"start_offset" : 15,
"end_offset" : 17,
"type" : "word",
"position" : 3
},
{
"token" : "your",
"start_offset" : 18,
"end_offset" : 22,
"type" : "word",
"position" : 4
},
{
"token" : "b",
"start_offset" : 24,
"end_offset" : 25,
"type" : "word",
"position" : 5
},
{
"token" : "why",
"start_offset" : 27,
"end_offset" : 30,
"type" : "word",
"position" : 6
},
{
"token" : "not",
"start_offset" : 31,
"end_offset" : 34,
"type" : "word",
"position" : 7
}
]
}
接下來以下幾項僅舉例,可以自行試試看:
stop analyzer
小寫處理,停用詞語過濾(the, a, this…)
GET _analyze
{
"analyzer": "stop",
"text":"hello for 2 <b>in your</b> why-not?"
}
whitespace analyzer
依照空白進行切分,小寫處理 ,並且不會過濾HTML
GET _analyze
{
"analyzer": "whitespace",
"text":"hello for 2 <b>in your</b> why-not?"
}
keyword analyzer
不分詞,直接輸入
GET _analyze
{
"analyzer": "keyword",
"text":"hello for 2 <b>in your</b> why-not?"
}
輸出結果
{
"tokens" : [
{
"token" : "hello for 2 <b>in your</b> why-not?",
"start_offset" : 0,
"end_offset" : 35,
"type" : "word",
"position" : 0
}
]
}
pattern analyzer
正則表達式,預設使用 \W+(非字符串分隔)
GET _analyze
{
"analyzer": "pattern",
"text":"hello for 2 <b>in your</b> why-not?"
}
日語搜尋
日語包含多音詞與拼寫方式
- 平假名, 如「検索 -> けんさく」
- 片假名全形,如 「検索 -> ケンサク」
- 片假名半形,如「検索 -> ケンサク」
- 漢字,如 「検索」
- 羅馬字全形,如「検索 -> kennsaku」
- 羅馬字半形,如「検索 -> kennsaku」
上述提到的多種型態,因此在搜尋時,需要使用自行定義的 analyzer
簡易入門
- Kuromoji
- Sudachi 進階
- MeCab
- Juman++
在這裡先介紹 Kuromoji 如何處理日語
Kuromoji 的 token filter 介紹:
一個 Kuromoji token filter 的如下
PUT my_index { "mappings": { "my_type": { "properties": { "title": { "type": "text", "analyzer": "kuromoji" } } } } }
等同於
PUT my_index { "settings": { "analysis": { "analyzer": { "ja_fulltext_analyzer": { "type": "custom", "tokenizer": "kuromoji_tokenizer", "filter": [ "cjk_width", "lowercase", "kuromoji_stemmer", "ja_stop", "kuromoji_part_of_speech", "kuromoji_baseform" ] } } } }, "mappings": { "my_type": { "properties": { "title": { "type": "text", "analyzer": "ja_fulltext_analyzer" } } } } }
底下個別說明各個 token filter 的功能:
Lowercase token filteredit
將英文轉小寫
CJK Width Token Filter
將 ASCII 全形字元轉為半形
ja_stop Token Filter
日本停止詞過濾
kuromoji_baseform token filter
日語詞根過濾
kuromoji_readingform Token Filter
日語讀音過濾,把單詞轉換為發音,發音可以是片假名或羅馬字 2 種形式
kuromoji_part_of_speech Token Filter
日本語氣詞過濾
kuromoji_stemmer Token Filter
日本音長過濾,可去除單詞尾端的長音
kuromoji_number Token Filter
將漢語數字轉為 ASCII 數字