Elasticsearch 的分词运用

2020-06-18 18:28:08 浏览数 (1)

索引分词原理

倒排索引

每个全文索引都是一个倒排索引,ES 在进行检索操作时,会建立倒排索引,将拆分的词进行处理,提高索引命中率。

以下索引已有2个 segment,从 data resource 接收到了新的数据会先存入 buffer,buffer 将数据刷到文件系统缓存中, 生成一个新的 segment,此时已经可以进行检索这个 segment,之后再被刷入磁盘中。

倒排索引流程倒排索引流程

分词器(analyzer)

不管是内置还是自定义的分词器,都可以视为一种包含了三种基础架构的包,分别是字符过滤器(Character filters)、标记器(Tokenizer)和 令牌过滤器(Token filters)。

字符过滤器(Character filters)

在将字符传递给标记器之前进行预处理,在接收原始文本后进行一系列的增、删、改操作来转换字符流。

HTML Strip Char Filter

可从文本中剥离 HTML 元素,并用它们的解码值替换 HTML 实体(例如用 & 替换 &)

代码语言:txt复制
POST _analyze
{
  "tokenizer":      "keyword", 
  "char_filter":  [ "html_strip" ],
  "text": "<p>Tencent Cloud &amp; <b>ES</b>!</p>"
}

Mapping Chartacter Filter

可映射键值对,遇到相同的键时可替换成关联词;贪婪模式匹配,替换的字符串允许空字符串。

Pattern Replace Char Filter

用正则表达式来匹配应该用指定的替换字符串替换的字符。 替换字符串可以引用正则表达式中的捕获组。

如以下实例,执行后,原本的“123-456-789”会返回“123_456_789”

代码语言:txt复制
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "standard",
          "char_filter": [
            "my_char_filter"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": "(\d )-(?=\d)",
          "replacement": "$1_"
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "My credit card is 123-456-789"
}

Tokenizer(标记器)

标记器在接收到字符流后会分解为独立的标记,并输出一个标记流。常见的标记器如下

tokenizer

description

standard tokenizer

标准标记器,删除大多数标点符号,适用于绝大多数语言

letter tokenizer

遇到非字母的字符时,标记器会将文本标为 terms

lowercase tokenizer

类似 letter tokenizer,遇到非字母

whitespace tokenizer

遇到空白字符时,会将文本标记为 terms

UAX URL email tokenizer

类似于 classic tokenizer,将 URL 和 email 地址识别为令牌

classic tokenizer

基于语法的标准标记器

Thai tokenizer

针对泰语的标记器

Token filters(令牌过滤器)

接收标记器,可对标记器进行增、删、改操作

内置分词器

analyzer

description

standard analyzer

默认分析器,如果未指定,则使用该分析器。它提供基于语法的标记化,适用于绝大多数语言

simple analyzer

当 simple 分词器遇到非字母的字符时,会将文本划分为多个术语。小写所有术语

whitespace Analyzer

遇到空白字符时,会将空白字符分解为 terms,非小写 terms

stop analyzer

类似 simple 分词器,支持去除停止词

keyword analyzer

不分词,内容整体作为一个 token(not_analyzed)

pattern analyzer

正则表达式分词,默认匹配W

language analyzers

多种语言分词器

Fingerprint Analyzer

专业的指纹分词器,可创建指纹重复使用

Keyword 对比 text

keyword

text

不会分词建立索引

会分词建立索引

支持模糊、精确查询

支持模糊、精确查询

支持聚合

不支持聚合

IK 分词的运用

IK 分词的两种模式

ik_smart:以最粗粒度进行分词

ik_max_word:以最细粒度进行分词,穷尽各种可能的组合

IK 分词实践

创建索引的时候用 ik_max_word,搜索数据时用 ik_smart,以保证数据在存入索引时最细粒度拆分,搜索数据时更精确的获取到想要的结果。

创建索引

代码语言:javascript复制
PUT shani_ik

{
  "settings": {
    "index.analysis.analyzer.default.type": "ik_max_word"
  },
  "mappings": {
    "doc" : {
      "properties": {
        "dep_test": {
          "type": "text",
          "analyzer": "ik_max_word"
        }
      }
    }
  }
}

检索数据

代码语言:javascript复制
GET shani_ik

{
  "text": "我爱北京天安门",
  "analyzer": "ik_smart"
}

ES 分词进阶运用

自定义分词器

内建分词无法满足需求时,可自定义分词器

关闭索引

在修改自定义之前,需要关闭索引

向索引中添加自定义分词器

代码语言:javascript复制
PUT shani/settings

{
    "analysis": {
        "char_filter": {
            "&_to_and": {
                "type": "mapping",
                "mappings": ["& => and"]
            }
        },
        "filter": {
            "my_stopwords": {
                "type": "stop",
                "stopwords": ["the", "a"]
            }
        },
        "analyzer": {
            "shani_analyzer": {
                "type": "custom",
                "char_filter": ["html_strip", "@_to_and"],
                "tokenizer": "ik_max_word",
                "filter": ["lowercase", "my_stopwords"]
            }
        }
    }
}

0 人点赞