重生之我们在ES顶端相遇第11 章 - 深入自定义语言分词器

文章目录

      • 0. 前言
      • 1. 英语分词器
      • 2. 阿拉伯语分词器
      • 3. 结语

0. 前言

国内企业出海是大势所趋,那么基于不同的语种进行分词就显得尤为重要,因为这会让用户的搜索体验更棒!

国内出海企业,会更偏向于选择欧美、中东这 2 个地区。

因此本文章也重点介绍英语、阿拉伯语的分词。

在 ES 中内置的分词器中,有一个叫 Language analyzers,我们可以根据该分词器,自定义出符合业务需求的特定语言分词器。

1. 英语分词器

英语分词器一般而言应该满足以下要求

  1. 不区分大小写
  2. 去掉英语停顿词
  3. 具有相同的词干可以被认为是同一个词,例如 friends = fried
  4. 可能还需要有同义词,例如 quick = fast

Ok,基于以上要求,我们来自定义一个英文分词器。

  • 不区分大小写,ES 有现成的 token filters: lowercase token filter
  • 去掉英语停顿词,ES 有现成的 token filters: stop token filter。并且 stop token filter 对多个语种均有支持
  • 词干提取器,ES 有现成的 token filters: stemmer token filter。并且 stemmer token filter 对多个语种均有支持
  • 同义词,ES 有现成的 token filters: synonym token filter, 不过需要我们提前定义好哪些词属于同义词。

OK,接下来,让我们看下具体的 Mapping 如何编写

PUT test9_en

{
  "mappings": {
      "properties": {
      "text": {
        "type": "text",
        "analyzer": "my_custom_analyzer"
      }
    }
  },
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "english_stop",
            "english_stemmer",
            "english_synonym"
          ]
        }
      },
      "filter": {
        "english_stop": {
          "type": "stop",
          "stopwords": "_english_"
        },
        "english_stemmer": {
          "type": "stemmer",
          "language": "english"
        },
        "english_synonym": {
          "type": "synonym",
          "synonyms": [ "quick => fast" ]
        }
      }
    }
  }
}

接下来,我们验证下效果
GET test9_en/_analyze

{
  "analyzer": "my_custom_analyzer",
  "text": "the Friends quick"
}

输出如下

{
  "tokens" : [
    {
      "token" : "friend",
      "start_offset" : 4,
      "end_offset" : 11,
      "type" : "",
      "position" : 1
    },
    {
      "token" : "fast",
      "start_offset" : 12,
      "end_offset" : 17,
      "type" : "SYNONYM",
      "position" : 2
    }
  ]
}

符合我们的预期:

  • the 是停顿词,被过滤掉
  • Friends 的词干为 friend;同时因为 lowercase token filter 的存在,大小被转换为小写了
  • quick 和 fast 是同义词

ES 内置了非常丰富的 token filter 更多可以参考 ES token filter 官网

2. 阿拉伯语分词器

阿拉伯语分词器做法和英语类似,
对于 stop token filterstemmer token filter 均支持阿拉伯语。

在英语中,字母有大小写,而在阿拉伯语中,则存在不同字母的变形,因此我们需要将文本先做归一化处理。

这需要用到 ES 的 Normalizers。用于将文本进行归一化处理。
本质上 lowercase token filter 就是一种 Normalizers,即将所有文本都统一修改为小写
更详细的介绍,参考 ES Normalizers 官网

那么其 Mapping 如下

PUT test9_alb

{
	"mappings": {
		"properties": {
			"text": {
				"type": "text",
				"analyzer": "arabic"
			}
		}
	},
	"settings": {
		"analysis": {
			"filter": {
				"arabic_stop": {
					"type": "stop",
					"stopwords": "_arabic_"
				},
				"arabic_stemmer": {
					"type": "stemmer",
					"language": "arabic"
				}
			},
			"analyzer": {
				"arabic": {
					"tokenizer": "standard",
					"filter": [
                        "arabic_normalization",
						"arabic_stop",
						"arabic_stemmer"
					]
				}
			}
		}
	}
}

我对阿拉伯语也不熟悉,这里就不进行效果验证了。

3. 结语

该篇我们探讨了如何实现英语、阿拉伯语的分词器。理论上其他语种的分词器也是类似的做法。

你可能感兴趣的:(Elasticsearch,elasticsearch)