Elasticsearch从入门到放弃:分词器初印象

点击上方“蓝字”关注咱们吧!

Elasticsearch 系列回来了,先给由于这个系列关注个人同窗说声抱歉,拖了这么久才回来,这个系列虽然叫「Elasticsearch 从入门到放弃」,但只有三篇就放弃仍是有点过度的,因此仍是回来继续更新。
html

以前咱们聊过了 Elasticsearch 的索引和文档,不太熟悉的话能够先翻阅一下前文。今天再一块儿聊一下 Elasticsearch 的分词器。web

关于分词

若是你是讲 Elasticsearch 做为搜索引擎,那么你应该须要对分词进行了解,Elasticsearch 的分词是将全文本转换为一系列单词,这样有助于在搜索时获得相关的结果以及相关性分析。例如咱们有一个文本为“I love Elasticsearch”,而后 Elasticsearch 能够将其分解为三个单词,这时咱们不管搜索哪一个单词,都能搜到这个文本。正则表达式

Elasticsearch 经过分词器对文本进行分词处理,Elasticsearch 的分词器是由 Character Filters、Tokenizer 和Token Filter 三部分组成。在介绍它们以前,咱们先来简单了解一下 Analyze API,它能够帮助咱们快速测试一个  Analyzer 的做用,它的用法也很是简单:微信

GET /_analyze
{
  "analyzer" : "standard",
  "text" : "Quick Brown Foxes!"
}

其中,analyzer 是指定的分词器,text 是被测试的文本,这样就能获得这个文本分词后的效果。app

这是最简单的一种用法,此外,咱们还能够在 path 中指定 index,用于测试指定索引中 mapping 设置的 analyzer 或者索引默认的 analyzer。固然,你也能够测试一下自定义的 analyzer,只须要在参数中设置好 Character Filters、Tokenizer 和Token Filter 便可。关于 Analyze API 更多的使用方法能够自行查阅官方文档 Analyze APIelasticsearch

内置 Analyzer

为了方便使用,Elasticsearch 为咱们提供了几种内置 Analyzer:编辑器

  • Fingerprint:它能够将文本处理为小写的、去除扩展的、有序的、惟一的单词测试

  • Keyword:不分词flex

  • Language:提供了30多种常见语言的分词器ui

  • Pattern:使用正则表达式分词,默认\W+(非字符分隔)

  • Simple:按照非字母切分,小写处理

  • Standard:默认分词器,会基于 Unicode 文本语法,按照单词划分,并进行小写处理

  • Stop:小写处理,过滤停用词(the, a, is)

  • Whitespace:按照空格切分,不转小写

如今咱们来测试一下 Whitespace Analyzer

GET _analyze
{
  "analyzer""whitespace",
  "text""The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

它的执行结果是

{
  "tokens" : [
    {
      "token" : "The",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "2",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "QUICK",
      "start_offset" : 6,
      "end_offset" : 11,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "Brown-Foxes",
      "start_offset" : 12,
      "end_offset" : 23,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "jumped",
      "start_offset" : 24,
      "end_offset" : 30,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "over",
      "start_offset" : 31,
      "end_offset" : 35,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "the",
      "start_offset" : 36,
      "end_offset" : 39,
      "type" : "word",
      "position" : 6
    },
    {
      "token" : "lazy",
      "start_offset" : 40,
      "end_offset" : 44,
      "type" : "word",
      "position" : 7
    },
    {
      "token" : "dog's",
      "start_offset" : 45,
      "end_offset" : 50,
      "type" : "word",
      "position" : 8
    },
    {
      "token" : "bone.",
      "start_offset" : 51,
      "end_offset" : 56,
      "type" : "word",
      "position" : 9
    }
  ]
}

若是有兴趣,能够自行测试一下其余的内置 Analyzer。除了内置的 Analyzer 以外,你也能够根据须要自定义分词器。

下面咱们来看怎么定义咱们须要的 Analyzer。

前面提到 Analyzer 由三部分组成,其中 Character Filters 用于对原始文本进行处理(例如去掉html标签),Tokenizer 是按照指定规则进行切分,Token Filter 负责将切分的单词进行加工(例如转小写)。

Character Filters

Character Filters 是分词的第一步,Elasticsearch 用它来对原始文本进行一些处理。内置的 Character Filters 有三个,分别是:

  • HTML strip:使用解码值替换HTML标签

  • Mapping:使用指定的替换项替换指定的字符串

  • Pattern replace:使用指定的替换项替换正则匹配的字符串

HTML strip 默认会替换文本中全部的 HTML 标签,你也能够经过设置escaped_tags,将一些特定的标签排除

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer""keyword",
          "char_filter": [
            "my_custom_html_strip_char_filter"
          ]
        }
      },
      "char_filter": {
        "my_custom_html_strip_char_filter": {
          "type""html_strip",
          "escaped_tags": [
            "b"
          ]
        }
      }
    }
  }
}

这个自定义 Analyzer 就不会替换标签 b。

Tokenizer

在对原始文本进行初步的处理以后,Tokenizer 就要上场了,它帮助咱们根据指定的规则进行分词,Elasticsearch 一样提供了一些内置的 Tokenizer。

  • Character group:按照配置的字符组进行切分

  • Classic:针对英语语法进行分词

  • Edge n-gram:从单词的起始字符开始按长度依次切分quick 会被分为[q, qu, qui, quic, quick]

  • Keyword:不切分

  • Letter:遇到非字母的字符进行切分

  • Lowercase:与相似 Letter 相似,不过它会把切分后的单词转为小写

  • N-gram:把单词切分为指定长度的字符串集合,quick 会被分为[qu, ui, ic, ck]

  • Path hierarchy:对路径进行切分,/foo/bar/baz 会分为[/foo, /foo/bar, /foo/bar/baz]

  • Pattern:根据正则匹配进行切分

  • Simple pattern:正则会受到一些限制,但不支持按照匹配到的分割符切分

  • Simple pattern split:是支持按照匹配到的分割符切分的Simple pattern

  • Standard:按照单词进行切分

  • Thai:针对泰语进行切分

  • UAX URL email:与 Standard 类似,但它会把 url 或邮箱看成一个总体

  • Whitespace:按照空格进行切分

在这里你能够先对这些内置的 Tokenizer 有个初步的了解,知道它们能干什么,在具体使用的时候能够查阅官方文档进行更详细的了解,不少 Tokenizer 还支持一些参数配置,这些到实际场景中灵活使用就好。

Token Filter

Elasticsearch 内置的 Token Filter 很是多,这里列几个经常使用的吧:

  • Trim:删除先后空格

  • Uppercase:转大写

  • Lowercase:转小写

  • Stop:停用词过滤

  • ……

Elasticsearch 中内置的这些分词器及组件能够知足咱们平常的大部分需求了,可以作到灵活应用就很厉害了。若是真的遇到解决不了的问题,你也能够尝试自定义分词器,例如对咱们的中文进行分词。

中文分词

中文分词的难点在于,它不像英文那样有自然的空格能够进行切分,咱们也不能简单的把它分红一个个的字,而是要分红有意义的词。

比较不错的中文分词器有 ICU Analyzer、IK 和 THULAC

ICU Analyzer

ICU Analyzer 并非 Elasticsearch 内置的分词器,因此咱们须要预先安装插件才能使用

执行命令

elasticsearch-plugin install analysis-icu

进行安装,安装好之后可使用命令elasticsearch-plugin list进行查看。

安装好以后就能够运行下面这个例子

GET _analyze
{
  "analyzer""standard"
  "text""以为好看就点赞"
}

GET _analyze
{
  "analyzer""icu_analyzer"
  "text""以为好看就点赞"
}

你会发现 standard analyzer 就是把这句话拆成一个个字,而 icu analyzer 基本会根据语义进行拆分。

总结

通过本文的介绍,相信你对 Elasticsearch 的分词器也有了一个初步的认识,知道它由什么组成,可以使用 Analyze API 对一个分词器进行简单的测试,也基本可以自定义一些分词器了。

我对内置的 Token Filter 介绍的比较少,你能够结合官方文档,对你感兴趣的 Token Filter 进行更深刻的研究,若是有什么问题也欢迎和我讨论。

往期精彩回顾
Elasticsearch从入门到放弃:文档CRUD要牢记
Elasticsearch从入门到放弃:索引基本使用方法
Elasticsearch从入门到放弃:人生若只如初见

本文分享自微信公众号 - 代码洁癖患者(Jackeyzhe2018)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索