ElasticSearch学习(四)-分词器

分词是指将文本转化成一系列的单词的过程,也可以叫做文本分析,在es中称为Analysis,例如:

文本:elasticSearch是最流行的搜索引擎

分词结果:elasticSearch 流行 搜索引擎

分词器

分词器是es中专门处理分词的组件,英文为Analyzer,它的组成如下:

  • Character Filters:针对原始文本进行处理,比如去除html中的特殊标记符。
  • Tokenizer:将原始文本按照一定规则切分成单词。
  • Token Filters:针对Tokenizer处理后的单词进行再加工,比如转小写、删除(删除一些类似 的、这等没有实际意义的词)或新增等处理。

我们可以通过API进行测试:

指定文本测试

需要自己指定分词器,standard是默认分词器。

POST _analyze 
{
  "analyzer": "standard",
  "text": "hello world!"
}

返回结果:

{
  "tokens" : [
    {
      "token" : "hello",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "world",
      "start_offset" : 6,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

指定索引里的字段进行测试

不需要指定分词器,用索引的分词器。

POST book/_analyze
{
  "field": "title",
  "text": "hello world!"
}

返回结果:

{
  "tokens" : [
    {
      "token" : "hello",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "world",
      "start_offset" : 6,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

自定义分词器

我们可以指定使用哪个分词器和filter,这里filter会将大写转化为小写。

POST _analyze
{
  "tokenizer": "standard",
  "filter": ["lowercase"],
  "text": "Hello World!"
}

返回结果:

{
  "tokens" : [
    {
      "token" : "hello",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "world",
      "start_offset" : 6,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

系统默认分词器

standard 分词器

英文的处理能力同于StopAnalyzer.支持中文采用的方法为单字切分。他会将词汇单元转换成小写形式,并去除停用词和标点符号。
在这里插入图片描述

simple 分词器

功能强于WhitespaceAnalyzer, 首先会通过非字母字符来分割文本信息,然后将词汇单元统一为小写形式。该分析器会去掉数字类型的字符。

在这里插入图片描述

Whitespace 分词器

仅仅是去除空格,对字符没有lowcase化,不支持中文; 并且不对生成的词汇单元进行其他的规范化处理。
在这里插入图片描述

Stop 分词器

StopAnalyzer的功能超越了SimpleAnalyzer,在SimpleAnalyzer的基础上增加了去除英文中的常用单词(如the,a等),也可以更加自己的需要设置常用单词;不支持中文。
在这里插入图片描述

keyword 分词器

KeywordAnalyzer把整个输入作为一个单独词汇单元,方便特殊类型的文本进行索引和检索。针对邮政编码,地址等文本信息使用关键词分词器进行索引项建立非常方便
在这里插入图片描述

pattern 分词器

一个pattern类型的analyzer可以通过正则表达式将文本分成"terms"(经过token Filter 后得到的东西 )。接受如下设置:

lowercaseterms是否是小写. 默认为 true 小写.pattern正则表达式的pattern, 默认是 \W+.flags正则表达式的flagsstopwords一个用于初始化stop filter的需要stop 单词的列表.默认单词是空的列表。

在这里插入图片描述

language 分词器

一个用于解析特殊语言文本的analyzer集合。( arabic,armenian, basque, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english, finnish, french,galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian,persian, portuguese, romanian, russian, sorani, spanish, swedish, turkish, thai.)可惜没有中文。不予考虑

在这里插入图片描述

中文分词器

在这里插入图片描述
在这里插入图片描述

自定义分词器

虽然Elasticsearch带有一些现成的分析器,然而在分析器上Elasticsearch真正的强大之处在于,你可以通过在一个适合你的特定数据的设置之中组合字符过滤器、分词器、词汇单元过滤器来创建自定义的分析器。

字符过滤器:

字符过滤器 用来 整理 一个尚未被分词的字符串。例如,如果我们的文本是HTML格式的,它会包含像<p>或者<div>这样的HTML标签,这些标签是我们不想索引的。我们可以使用 html清除 字符过滤器 来移除掉所有的HTML标签,并且像把Á转换为相对应的Unicode字符 Á 这样,转换HTML实体。一个分析器可能有0个或者多个字符过滤器。

分词器:

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

词单元过滤器:

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

创建一个自定义分析器

我们可以在 analysis 下的相应位置设置字符过滤器、分词器和词单元过滤器:

PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": { ... custom character filters ... },
            "tokenizer":   { ...    custom tokenizers     ... },
            "filter":      { ...   custom token filters   ... },
            "analyzer":    { ...    custom analyzers      ... }
        }
    }
}

这个分析器可以做到下面的这些事:

  1. 使用 html清除 字符过滤器移除HTML部分。

  2. 使用一个自定义的 映射 字符过滤器把 & 替换为 “和” :

    "char_filter": {
        "&_to_and": {
            "type":       "mapping",
            "mappings": [ "&=> and "]
        }
    }
    
  3. 使用 标准 分词器分词。

  4. 小写词条,使用 小写 词过滤器处理

  5. 使用自定义 停止 词过滤器移除自定义的停止词列表中包含的词.

    "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" ]
    }
}

汇总起来,完整的 创建索引 请求 看起来应该像这样:

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" ]
            }}
}}}

索引被创建以后,使用 analyze API 来 测试这个新的分析器:

GET /my_index/_analyze?analyzer=my_analyzer
The quick & brown fox

下面的缩略结果展示出我们的分析器正在正确地运行:

{
  "tokens" : [
      { "token" :   "quick",    "position" : 2 },
      { "token" :   "and",      "position" : 3 },
      { "token" :   "brown",    "position" : 4 },
      { "token" :   "fox",      "position" : 5 }
    ]
}

这个分析器现在是没有多大用处的,除非我们告诉 Elasticsearch在哪里用上它。我们可以像下面这样把这个分析器应用在一个 string 字段上:

PUT /my_index/_mapping/my_type
{
    "properties": {
        "title": {
            "type":      "string",
            "analyzer":  "my_analyzer"
        }
    }
}
发布了44 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/hxyascx/article/details/98498237