elasticsearch 基本概念-分析Analysis

  • 分析和分析器

术语

Tokenizer:分词器
Character Filter:字符过滤器
Token: 词元,单词
词频(Frequency):文档包含词的数量
倒排索引(Inverted Index):搜索引擎会建立词与文档的索引

分析

分析(analysis)是在文档被发送并加入倒排索引之前, 把全文本转化为一系列单词(term/token)的过程,也叫分词;在Elasticsearch 中可通过内置分词器实现分词,也可以按需定制分词器。

分析器

Character Filters:字符过滤器 使用字符过滤器转变字符。去掉HTML,或者将& 转化为and
Tokenizer:分词器 将文本切分为单个或多个分词。
Token Filters:令牌过滤器 对切分单词加工、小写、删除 stopwords,增加同义词

一个 分析器 就是在一个包里面组合了三种函数的一个包装器, 三种函数按照顺序被执行:

字符过滤器 Character Filters

字符过滤器 用来 整理 一个尚未被分词的字符串。例如,如果我们的文本是HTML格式的,它会包含像

或者

这样的HTML标签,这些标签是我们不想索引的。我们可以使用 html清除 字符过滤器 来移除掉所有的HTML标签,并且像把 Á 转换为相对应的Unicode字符 Á 这样,转换HTML实体。

一个分析器可能有0个或者多个字符过滤器

分词器 Tokenizer

一个分析器 必须 有一个唯一的分词器。 分词器把字符串分解成单个词条或者词汇单元。 标准 分析器里使用的 标准 分词器 把一个字符串根据单词边界分解成单个词条,并且移除掉大部分的标点符号,然而还有其他不同行为的分词器存在。

例如, 关键词 分词器 完整地输出 接收到的同样的字符串,并不做任何分词。 空格 分词器 只根据空格分割文本 。 正则 分词器 根据匹配正则表达式来分割文本

词单元过滤器

经过分词,作为结果的 词单元流 会按照指定的顺序通过指定的词单元过滤器 。

词单元过滤器可以修改、添加或者移除词单元。我们已经提到过 lowercase 和 stop 词过滤器 ,但是在 Elasticsearch 里面还有很多可供选择的词单元过滤器。 词干过滤器 把单词 遏制 为 词干。 ascii_folding 过滤器移除变音符,把一个像 "très" 这样的词转换为 "tres" 。 ngram 和 edge_ngram 词单元过滤器 可以产生 适合用于部分匹配或者自动补全的词单元

分词过程

1)字符过滤器 character filter

首先,字符串按顺序通过每个字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and。

2)分词器 tokenizer

其次,字符串被 分词器 分为单个的词条。一个 whitespace的分词器遇到空格和标点的时候,可能会将文本拆分成词条。

3)token过滤器token filter

最后,词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条,例如,lowercase token filter 小写化(将ES转为es)、stop token filter 删除词条(例如, 像 a, and, the 等无用词),或者synonym token filter 增加词条(例如,像 jump 和 leap 这种同义词)。

内置分析器

ES分词器汇总
我们看看每个分析器会从下面的字符串得到哪些词条:

"Set the shape to semi-transparent by calling set_trans(5)"
标准分析器
标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。它根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。最后,将词条小写。它会产生

set, the, shape, to, semi, transparent, by, calling, set_trans, 5
简单分析器
简单分析器在任何不是字母的地方分隔文本,将词条小写。它会产生

set, the, shape, to, semi, transparent, by, calling, set, trans
空格分析器
空格分析器在空格的地方划分文本。它会产生

Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
语言分析器
特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如, 英语 分析器附带了一组英语无用词(常用单词,例如 and 或者 the ,它们对相关性没有多少影响),它们会被删除。 由于理解英语语法的规则,这个分词器可以提取英语单词的 词干 。

英语 分词器会产生下面的词条:

set, shape, semi, transpar, call, set_tran, 5
注意看 transparent、 calling 和 set_trans 已经变为词根格式。

自定义分析器

自定义一个的字符过滤器:

PUT /my_index
{
  "settings": {
    "analysis": {
      "char_filter": { # 使用 html清除 字符过滤器移除HTML部分
        "&_2_and": { # 使用一个自定义的 映射 字符过滤器把 & 替换为 " and " :
          "type": "mapping",
          "mappings": [
            "&=>and"
          ]
        }
      },
      "filter": {
        "my_stopwords": { #使用自定义 停止 词过滤器移除自定义的停止词列表中包含的词
          "type": "stop",
          "stopwords": [
            "the",
            "a"
          ]
        }
      },
      "analyzer": { #指定分析器
        "my_analyzer": {
          "type": "custom",
          "char_filter": [
            "html_strip",
            "&_2_and"
          ],
          "tokenizer": "standard", #使用 标准 分词器分词。
          "filter": [
            "lowercase", # 小写词条,使用 小写 词过滤器处理
            "my_stopwords"
          ]
        }
      }
    }
  }
}

测试

GET /my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "The quick & brown fox"
}

测试结果

{
  "tokens" : [
    {
      "token" : "quick",
      "start_offset" : 4,
      "end_offset" : 9,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "and",
      "start_offset" : 10,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "brown",
      "start_offset" : 12,
      "end_offset" : 17,
      "type" : "<ALPHANUM>",
      "position" : 3
    },
    {
      "token" : "fox",
      "start_offset" : 18,
      "end_offset" : 21,
      "type" : "<ALPHANUM>",
      "position" : 4
    }
  ]
}

什么时候使用分析器

我们 索引 一个文档,它的全文域被分析成词条以用来创建倒排索引。 但是,当我们在全文域 搜索 的时候,我们需要将查询字符串通过 相同的分析过程 ,以保证我们搜索的词条格式与索引中的词条格式一致。

全文查询,理解每个域是如何定义的,因此它们可以做正确的事:

  • 当你查询一个 全文 域时, 会对查询字符串应用相同的分析器,以产生正确的搜索词条列表。
  • 当你查询一个 精确值 域时,不会分析查询字符串,而是搜索你指定的精确值。

测试分析器

有些时候很难理解分词的过程和实际被存储到索引中的词条,为了理解发生了什么,你可以使用 analyze API 来看文本是如何被分析的。在消息体里,指定分析器和要分析的文本:

GET /_analyze
{
  "analyzer": "standard",
  "text": "Text to analyze"
}

结果中每个元素代表一个单独的词条:

{
  "tokens" : [
    {
      "token" : "text",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "to",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "analyze",
      "start_offset" : 8,
      "end_offset" : 15,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}

token 是实际存储到索引中的词条。 position 指明词条在原始文本中出现的位置。 start_offset 和 end_offset 指明字符在原始字符串中的位置

指定分析器

当Elasticsearch在你的文档中检测到一个新的字符串域,它会自动设置其为一个全文 字符串 域,使用 标准 分析器对它进行分析。

你不想总是这样。可能你想使用一个不同的分析器,适用于你的数据使用的语言。有时候你想要一个字符串域就是一个字符串域—不使用分析,直接索引你传入的精确值,例如用户ID或者一个内部的状态域或标签。

要做到这一点,我们必须手动指定这些域的映射

{
    "tweet": {
        "type":     "string",
        "analyzer": "english"
    }
}

原文链接:https://blog.csdn.net/qq_24049933/article/details/110733481

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注