一、介紹
1、分詞是指將文本轉換成一系列單詞(term or token)的過程,也可以叫做文本分析,在es裏面稱爲 analysis。
2、分詞會在如下2個時間使用:
- 創建或更新文檔時,會對相應的文檔進行分詞處理
- 查詢時,會對查詢語句進行分詞
3、索引時分詞(創建或更新文檔)是通過配置 mapping 中每個字段的 analyzer 屬性實現的。不指定分詞時,默認使用 standard。如:
put testindex
{
"mappings": {
"doc": {
"porperties": {
"name": {
"type": "text",
"analyzer": "whitespace" // 指定分詞器
}
}
}
}
}
4、查詢時分詞
- 查詢的時候指定分詞器,如下:
POST testindex
{
"query": {
"match": {
"name": {
"query": "hello",
"analyzer": "standard"
}
}
}
}
- 通過mapping 設置 search_analyzer 實現指定分詞器,如下:
put testindex
{
"mappings": {
"doc": {
"porperties": {
"name": {
"type": "text",
"analyzer": "whitespace", // 指定索引時分詞器
"search_analyzer": "standard" // 指定查詢時分詞器
}
}
}
}
}
5、一些注意
- 查詢時分詞和索引時分詞通常需要保持一致,否則查詢時會有其他情況產生
- 明確字段是否需要分詞,不需要分詞的字段將 type 設置爲 keyword,可以節省空間和提高寫性能
- 使用 _anzlyzer 查看文檔的具體分詞結果
二、分詞器
分詞器是es 中專門處理分詞的組件,英文是 analyzer,它的組成如下:
- character filters:針對原始文本進行處理,比如去除 html 特殊標記符
- tokenizer:將原始文本按照一定規則切分爲單詞,比如按空格切分
- token filters:針對tokenizer 處理的單詞進行進一步加工,比如轉小寫、刪除或新增等處理
- 三個組成部分需要按照嚴格的先後順序:character filters —> tokenizer —> token filters
三、analyze api
1、es 提供了 一個測試分詞的api 接口,方便驗證分詞效果,endpoint 是 _analyze
- 可以直接指定 analyzer 進行測試
舉例:
POST _analyze
{
"analyzer": "standard", // 指定分詞器, standard 是默認分詞器
"text": "hello world"
}
- 可以直接指定索引中的字段進行測試
舉例:
POST testindex/_analyze
{
"field": "username",
"text": "hello world"
}
- 可以自定義分詞器進行測試,api如下:
POST _analyze
{
"tokenizer": "standard",
"filter": [
"lowercase" // 轉小寫
],
"text": "hello world"
}
四、預定義的分詞器
1、standard
- 默認分詞器
- 其組成如圖所示,特性爲:
-
- 按詞切分,支持多語言
- 小寫處理
2、simple
其組成如圖,特性爲:
- 按照非字母切分
- 小寫處理
3、whitespace
其組成如圖,特性爲:
- 按照空格切分
4、stop
- stop word 指語氣助詞等修飾性的詞語,比如 the、an、的、這 等等
- 其組成如圖,特性爲:
-
- 相比 simple analyzer 多了 stop word 處理
- 相比 simple analyzer 多了 stop word 處理
5、keyword
其組成如圖,特性爲:
- 不分詞,直接將輸入作爲一個完整單詞輸出
6、pattern
其組成如圖,特性爲:
- 通過正則表達式自定義分隔符
- 默認是 \W+,即非字詞的符號作爲分隔符
五、中文分詞
IK
- 實現中英文單詞的切分,支持ik_smart、ik_max word模式
- 可自定義詞庫,支持熱更新分詞詞典
jieba
- python 中最流行的粉分詞系統,支持分詞和詞性標註
- 支持繁體分詞、自定義詞典、並行分詞等
Hanlp、THULAC
六、自定義分詞
- 當自帶的分詞無法滿足需求時,可以自定義分詞器。
- 通過自定義分詞器的3個組成部分:character filters、tokenizer 和 token filters實現。
1、character filters
- 在 tokenizer 之前對原始文本進行處理,比如增加、刪除或替換字符等
- 自帶的如下:
-
- HTML Strip 去除html 標籤和轉換 html實體
- Mapping 進行字符替換操作
- Pattern Replace 進行正則匹配替換
- 會影響後續 tokenizer 解析的 position 和 offset 信息
POST _analyze
{
"char_filter": [
"html_strip"
],
"text": "<p>so <b>happy</b></p>"
}
2、tokenizer
-
將原始文本按照一定規則切分爲單詞
-
自帶的如下:
-
- standard 按照單詞進行分割
- letter 按照非字符類進行分割
- whitespace 按照空格進行分割
- UAX URL Email 按照 standard 分割,但不會分割 郵箱和url
- NGram 和 Edge NGram 連詞分割
- Path Hierarchy 按照文件路徑進行分割
-
舉例:
POST _analyze
{
"tokenizer": "standard",
"filter": [
"lowercase" // 轉小寫
],
"text": "hello world"
}
3、token filter
- 對於 tokenizer 輸出的單詞 (term)進行增加、刪除、修改等操作
- 自帶的如下:
-
- lowercase 將所有 term轉換爲小寫
- stop 刪除 stop words(指語氣助詞等修飾性的詞語,比如 the、an、的、這 等等)
- NGram 和 Edge NGram 連詞分割
- Synonym 添加近義詞的 term
- 舉例:
POST _analyze
{
"text": "hello world",
"tokenizer": "standard",
"filter": [
"stop",
"lowercase",
{
"type": "ngram",
"min_gram": 4, // 4個詞切割一次
"min_gram": 4
}
]
}
4、自定義分詞
自定義分詞需要在索引的配置中設定,如下所示:
PUT testindex
{
"settings": {
"analysis": {
"char_filter": {},
"tokenizer": {},
"filter": {},
"analyzer": {}
}
}
}
舉例:
PUT testindex
{
"settings": {
"analysis": {
"filter": {
"lowercase"
},
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "standard",
"char_filter": [
"html_strip"
]
}
}
}
}
}