Elasticsearch学习笔记(七):ES中的分词器

173 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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,  ofreal,  life,  which,  can,  reflect,  all,    aspects,  of,  people’s,  lives.
whitespace:Literature,  is,  a,  mirror,  ofreal,  life,  which,  can,  reflect,  all,    aspects,  of,  people’s,  lives.
simple:literature, is,  a,  mirror,  ofreal,  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子模块。