【Elasticsearch】学好Elasticsearch系列-分词器 1

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 【Elasticsearch】学好Elasticsearch系列-分词器

先看后赞,养成习惯。

点赞收藏,人生辉煌。

在Elasticsearch中,分词器是用于将文本数据划分为一系列的单词(或称之为词项、tokens)的组件。这个过程是全文搜索中的关键步骤。

一个分词器通常包含以下三个部分:

  1. 字符过滤器(Character Filters):它接收原始文本作为输入,然后可以对这些原始文本进行各种转换,如去除HTML标签,将数字转换为文字等。
  2. 分词器(Tokenizer):它将经过字符过滤器处理后的文本进行切分,生成一系列词项。例如,标准分词器会按照空格将文本切分成词项。
  3. 词项过滤器(Token Filters):它对词项进行进一步的处理。比如小写化,停用词过滤(移除常见而无意义的词汇如"and", "the"),同义词处理,stemming(提取词根)等。

Elasticsearch提供了许多内置的分词器,如标准分词器(Standard Tokenizer)、简单分词器(Simple Tokenizer)、空白分词器(Whitespace Tokenizer)、关键字分词器(Keyword Tokenizer)等。每种分词器都有其特定的应用场景,并且用户也可以自定义分词器以满足特殊需求。

规范化:normalization

在Elasticsearch中,"normalization" 是指将文本数据转化为一种标准形式的步骤。这种处理主要发生在索引时,包括以下操作:

  1. Lowercasing:将所有字符转换为小写。这是最常见的标准化形式,因为搜索常常是不区分大小写的。
  2. Removing diacritical marks:移除重音符号或其他变音记号。例如,将 "résumé" 转换为 "resume"。
  3. Converting characters to their ASCII equivalent:将非ASCII字符转换为等效的ASCII字符。例如,将 "ë" 转换为 "e"。

这些转换有助于提高搜索的准确性,因为用户可能以各种不同的方式输入同一个词语。通过将索引和搜索查询都转换为相同的形式,可以更好地匹配相关结果。

说白了normalization就是将不通用的词汇变成通用的词汇。文档规范化,提高召回率

举个例子:

假设我们希望在 Elasticsearch 中创建一个新的索引,该索引包含一个自定义分析器,该分析器将文本字段转换为小写并移除变音符号。可以使用以下请求:

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": { "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text",
        "analyzer": "my_custom_analyzer"
      }
    }
  }
}

在这个例子中,我们首先使用 PUT 请求创建了一个名为 "my_index" 的新索引。然后,在 settings 对象中定义了一个名为 "my_custom_analyzer" 分析器。

这个分析器包括三部分:

  • "type": "custom": 这表示我们正在创建一个自定义分析器。
  • "tokenizer": "standard": 这设置了标准分词器,它按空格和标点符号将文本拆分为单词。
  • "filter": ["lowercase", "asciifolding"]: 这是一个过滤器链,将所有文本转为小写 (lowercasing) 并移除所有的变音符号(如 accented characters)。

最后,在 mappings 对象中,我们指定 "my_field" 字段要使用这个自定义分析器。

现在,当我们索引包含像 "Résumé" 这样的文本时,它会被标准化为"resume",这样无论用户输入 "resume" 还是 "résumé" 或者 "RESUME", 都能匹配到正确的结果。

POST /my_index/_doc
{
  "my_field": "Méditerranéen RÉSUMÉ"
}

Elasticsearch 在索引这个文档时会将 "Méditerranéen RÉSUMÉ" 转换成 "mediterraneen resume"。这样,无论搜索查询是 "Méditerranéen", "méditerranéen", "MEDITERRANÉEN", "Resume", "résumé" 或 "RESUME",都能找到这个文档。

字符过滤器:character filter

Character filters就是在分词之前过滤掉一些无用的字符, 是 Elasticsearch 中的一种文本处理组件,它可以在分词前先对原始文本进行处理。这包括删除HTML标签、转换符号等。

下面是一些常用的 character filter:

  1. HTML Strip Character Filter:从输入中去除HTML元素,只保留文本内容。例如,<p>Hello World</p> 被处理为 "Hello World"
  2. Mapping Character Filter:通过一个预定义的映射关系,将指定的字符或字符串替换为其他字符或字符串。例如,你可以定义一个规则将 "&" 替换为 "and"。
  3. Pattern Replace Character Filter:使用正则表达式匹配和替换字符。

HTML Strip Character Filter

HTML Strip Character Filter 是 Elasticsearch 中的一个 character filter,其功能是从输入的文本中去除 HTML 元素。这对于处理包含 HTML 标签的文本十分有用。

下面的例子展示了如何创建一个使用 HTML Strip Character Filter 的索引:

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_html_analyzer": { 
          "tokenizer": "standard",
          "char_filter": ["html_strip"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text",
        "analyzer": "my_html_analyzer"
      }
    }
  }
  }

在这个例子中,我们首先创建了一个新的索引 "my_index"。然后,在分析器配置中,我们创建了一个名为 "my_html_analyzer" 的分析器,并在此分析器中使用了名为 "html_strip" 的内置 character filter。这将会移除 "my_field" 字段中任何的 HTML 标记,只保留纯文本内容。

如果你现在往该索引插入一个包含HTML标签的文档,例如:

POST /my_index/_doc
{
  "my_field": "<p>Hello World</p>"
}

Elasticsearch 将会把 "

Hello World

" 看作是 "Hello World" 进行索引。这样无论搜索者输入 "Hello World" 还是 "

Hello World

",都可以找到这个文档。


Mapping Character Filter

在Elasticsearch中,Mapping Character Filter允许通过创建自定义字符映射来预处理文本。这意味着在进行索引或搜索时,可以将特定的字符或字符序列替换为其他字符。

例如,如果你正在处理法语文本并希望统一所有形式的“è”,你可能会创建一个映射,将“è”映射为“e”。或者,如果你正在处理包含特定公司名称的文本,并希望将所有变体都映射到一个常见形式,可以使用此过滤器。

具体的配置如下:

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "keyword",
          "char_filter": ["my_char_filter"]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": ["&=> and ", "è => e"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

在这个例子中,我们创建了一个新的char_filter,命名为my_char_filter。然后在分析器my_analyzer中引用了这个字符过滤器。最后,我们定义了两个映射:“&”映射为“and ”,以及“è”映射为“e”。

总的来说,Mapping Character Filter提供了一种灵活的方式,让你能够根据需求修改和控制如何处理文本数据。

当你配置了索引并创建了特定的字符映射规则后,你可以往该索引中插入文档。以下是一个例子:

PUT /my_index/_doc/1
{
  "text": "M&M's are delicious!"
}

在这个例子中,我们向 my_index 索引中的 text 字段添加了一条记录:"M&M's are delicious!"。因为我们之前在 my_analyzer 中定义了一个映射规则,它会自动把 "&" 替换成 "and"。

所以,在Elasticsearch中,无论用户搜索 "M and M's are delicious!" 还是原始的 "M&M's are delicious!",都能找到这条记录。同时,如果你检索这个文档,例如 GET /my_index/_doc/1,返回的结果中 text 字段仍为原始输入: "M&M's are delicious!",因为 character filter 只对搜索和索引过程生效,不会改变实际存储的文档内容。

Mapping Character Filter还有一个使用场景,比如平时我们网上发送弹幕或者游戏中公屏聊天的时候,要是说脏话,脏话内容会被替代为:*。

Pattern Replace Character Filter

Pattern Replace Character Filter 是 Elasticsearch 中一个强大的工具,它允许使用正则表达式来匹配文本,并将匹配的内容替换为指定的字符串。这对于处理有复杂需求的文本非常有用。

例如,假设你需要在索引或搜索时删除所有的数字,可以使用 Pattern Replace Character Filter,并设置一个匹配所有数字的正则表达式 [0-9],然后将其替换为空字符串或其他所需的字符。

示例如下:

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "keyword",
          "char_filter": ["my_pattern_replace_char_filter"]
        }
      },
      "char_filter": {
        "my_pattern_replace_char_filter": {
          "type": "pattern_replace",
          "pattern": "[0-9]",
          "replacement": ""
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

在这个例子中,我们定义了一个名为 my_pattern_replace_char_filter 的字符过滤器,该过滤器将所有数字(匹配正则表达式 [0-9])替换为一个空字符串("")。然后,在我们的分析器 my_analyzer 中使用了这个字符过滤器。最后,在映射中我们指定了字段 "text" 使用这个分析器。因此,当你向 "text" 字段存储含有数字的文本时,所有的数字会被移除。

当你配置好索引并设定了特定的字符过滤规则后,你可以向这个索引插入文档。例如:

PUT /my_index/_doc/1
{
  "text": "I have 10 apples."
}

在这个例子中,我们向my_index索引的text字段添加了一条记录:"I have 10 apples."。因为我们之前在 my_analyzer 中定义了一个正则表达式替换规则,它会自动把数字("[0-9]")替换为空字符串。

所以,在Elasticsearch中,无论用户搜索 "I have apples." 还是原始的 "I have 10 apples.",都能找到这条记录。同时,如果你检索这个文档,例如 GET /my_index/_doc/1,返回的结果中 text 字段仍为原始输入: "I have 10 apples.",因为 character filter 只对搜索和索引过程生效,不会改变实际存储的文档内容。

Pattern Replace Character Filter有一个常用的场景就是手机号脱敏,比如:假设我们希望将电话号码中的某几位数字替换为星号 "*" 来进行脱敏处理。可以使用 Pattern Replace Character Filter 进行配置,如下:

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "keyword",
          "char_filter": ["my_pattern_replace_char_filter"]
        }
      },
      "char_filter": {
        "my_pattern_replace_char_filter": {
          "type": "pattern_replace",
          "pattern": "(\d{3})(\d{4})(\d{4})",
          "replacement": "$1****$3"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

在这个示例中,我们创建的 my_pattern_replace_char_filter 将匹配任意连续10位数字的电话号码,并将其中的第 4 至第 7 位替换为四个星号 "*"。

然后插入一条包含手机号的文档:

PUT /my_index/_doc/1
{
  "text": "My phone number is 12345678901."
}

Elasticsearch 在索引这个文档时,会按照我们设置的规则将手机号码脱敏为 "123****8901",所以无论用户搜索 "My phone number is 12345678901." 还是 "My phone number is 123****8901." 都能找到这条记录。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
6月前
|
存储 人工智能 自然语言处理
ElasticSearch实战指南必知必会:安装分词器、高级查询、打分机制
ElasticSearch实战指南必知必会:安装分词器、高级查询、打分机制
ElasticSearch实战指南必知必会:安装分词器、高级查询、打分机制
|
9月前
|
自然语言处理 算法 索引
elasticsearch分词器详解
elasticsearch分词器详解
161 0
|
18天前
|
自然语言处理 Java Maven
【ElasticSearch】分词器(ElasticSearchIK分词器)
【ElasticSearch】分词器(ElasticSearchIK分词器)
21 1
|
1月前
|
Linux Docker 容器
使用Docker来安装ElasticSearch,并且配置ik分词器
使用Docker来安装ElasticSearch,并且配置ik分词器
37 0
|
1月前
|
存储 自然语言处理 算法
elasticsearch集群搭建,以及kibana和ik分词器的安装(7.3.2)
elasticsearch集群搭建,以及kibana和ik分词器的安装(7.3.2)
|
3月前
|
自然语言处理
Elasticsearch+IK+pinyin自定义分词器
Elasticsearch+IK+pinyin自定义分词器
32 0
|
4月前
|
自然语言处理 数据可视化 算法
史上最详细Docker安装Elasticsearch、ik分词器、可视化工具,每一步都带有步骤图!!!
史上最详细Docker安装Elasticsearch、ik分词器、可视化工具,每一步都带有步骤图!!!
420 0
史上最详细Docker安装Elasticsearch、ik分词器、可视化工具,每一步都带有步骤图!!!
|
5月前
|
自然语言处理 搜索推荐 算法
数据库-Elasticsearch进阶学习笔记(分片、映射、分词器、即时搜索、全文搜索等)
数据库-Elasticsearch进阶学习笔记(分片、映射、分词器、即时搜索、全文搜索等)
145 0
|
8月前
|
自然语言处理 Java Windows
Windows使用elasticsearch+Kibana+ik分词器
Windows使用elasticsearch+Kibana+ik分词器
75 0
|
9月前
|
自然语言处理 关系型数据库 MySQL