持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
导语
Elasticsearch 是一个分布式的开源搜索和分析引擎,目前被广泛使用,本文主要介绍ES中的一些分词器的构成以及如何自定义分词器。
ES中的分词器
在全文搜索中,分词是非常关键的一步,它是建立倒排索引的基础。对于全文搜索的部分,ES中会使用分词器对其进行分词,用于构建倒排索引。一般包括以下几个步骤:
Character filter
首先是字符过滤,我们使用爬虫从互联网上可能爬取了很多html网页文本,这些文本中可能有一部分html标签或者特殊符号,我们需要进行字符的预处理,比如将真正文本内容外的标签去掉,将&符号转换为and英文单词等。
例如:
<span><em>hello</em><span> --> hello,
I&you --> I and you
Tokeinzer
预处理之后我们开始进行划分边界进行分词。Tokenizer就是完成边界划分进行分词,比如最简单的,可以用空格作为各个词的边界进行划分。
如:
hello you and me --> hello, you, and, me
Token filter
边界划分之后,我们进行最后一步操作,使用过滤器对划分好的单词进行处理。这里就是一个归一化的过程,比如我们将所有大写字母转小写,去掉一些没有意义的停用词,比如a、the、to等等无意义的词语。还可以进行一些同义词归一化,比如去掉复数等等。
如:
dogs --> dog,
liked --> like,
Tom --> tom,
a/the/an --> 删掉,
mother --> mom
我们可以看几个内置的分词器来理解。
内置分词器举例
我们以一句话"Literature is a mirror of real life which can reflect all aspects of people’s lives."为例,介绍四种分词器对其处理后的结果。
standard(默认):literature, is, a, mirror, of, real, life, which, can, reflect, all, aspects, of, people’s, lives.
whitespace:Literature, is, a, mirror, of, real, life, which, can, reflect, all, aspects, of, people’s, lives.
simple:literature, is, a, mirror, of, real, life, which, can, reflect, all, aspects, of, people, s, lives.
english:literature, mirror, real, life, which, can, reflect, all, aspect, peopl, lives.
使用标准分词器后可以看到,它主要是进行了大小写变换、然后空格分界,这个也是我们ES在构建index时默认的分词器;
第二个是whitespace分词器,这个可以看到,它只是简单的空格进行了分词;
第三个叫做简单分词器,我们可以看到它进行了大小写变换、并用空格和一撇对单词进行了分界;
第四个是英语分词器,这种分词器呢我们可以看到,它进行了哪些变换呢,大家有没有发现。(大小写、去复数、停用词)
自定义分词器
除了使用ES提供的内置分词器,我们还可以自定义分词器来满足自己构建的应用的需求。自动以分词器,也主要是设置这三个部分。同样的,我们也可以只更改其中一部分,而另一部分仍采用内置的子模块。比如Tokenizer子模块里有standard tokenizer,它主要是以单词边界进行切分。Token filter模块有standard token filter,它什么都不做,lowercase token filter,它将所有字母转换为小写和stop token filer(默认被禁用)用来移除停用词,比如a the it等等。
下面展示了一个自定义的分词器,
# 自定义分词器
PUT /my_index
{
"settings": {
"analysis": {
"char_filter": {
"&_to_and": {
"type": "mapping",
"mappings": ["&=> and"]
}
},
"filter": {
"my_stopwords": {
"type": "stop",
"stopwords": ["the", "a"]
}
},
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": ["html_strip", "&_to_and"],
"tokenizer": "standard",
"filter": ["lowercase", "my_stopwords"]
}
}
}
}
}
在这里,我们自定义了一个 &-->and 的character filter和my_stopwords这个token filter,同时也使用了内置的html_strip 和 lowercase子模块。