【ES实战】ES分词器介绍

news/2024/7/7 6:36:32 标签: elasticsearch, 搜索引擎, 大数据

文章目录

  • ES分词器介绍
    • 什么是分词器
    • 分词器的组成
      • Character filters
      • Tokenizers
      • Token filters
    • 分词的过程
      • 写入时分词
      • 搜索时分词
      • 测试分词效果
    • 分词器的分类
    • 使用示例
      • 以Standard Analyzer为例
        • 测试分析效果
    • 其他:Normalizers(规范器)

ES分词器介绍

什么是分词器

分词属于ES的文本分析功能,是将文本(如任何的电子邮件的正文),转换成 tokens / terms的过程,再将这些 tokensterms 添加到倒排索引中以进行搜索服务。 分词器就是用来执行上述工作的。这里的分词器指的是 analyzer,ES提供了内置的分词器,也可以进行自定义分词器。

分词器的组成

一个标准的分词器包含三个部分,character filterstokenizerstoken filters

Character filters

字符过滤器将原始文本作为字符流接收,并可以通过添加、删除或更改字符来转换流。 例如,字符过滤器可用于将印度-阿拉伯数字 (٠ ١٢٣٤٥٦٧٨ ٩ ) 转换为阿拉伯-拉丁语等价物 (0123456789),或从流中去除诸如“”之类的 HTML 元素。

分词器可能有零个或多个 字符过滤器,它们按顺序应用。

Tokenizers

tokenizer分词器 接收字符流,将其分解为单独的 tokens(通常是单个单词),并输出 tokens 流。 例如,whitespace 分词器在看到任何空格时将文本分解为tokens。 它会将文本“Quick brown fox!”转换为terms[Quick, brown, fox!]

tokenizer分词器还负责记录每个词条的顺序或位置,以及该词条所代表的原始单词的开始和结束字符偏移量

分词器必须具有正好一个 tokenizer。

Token filters

token 过滤器 接收token流并可以添加、删除或更改token 。 例如,一个 lowercase 标记过滤器将所有标记转换为小写,一个 stop 标识过滤器从标识流中删除常用词(停用词),如 the ,并且 synonym token过滤器将同义词引入token流。

token 过滤器不允许更改每个token 的位置或字符偏移量。

分词器可能有零个或多个 token filters,它们按顺序应用。

分词的过程

在这里插入图片描述

写入时分词

在写入时,内置的 english analyzer 将首先句子转换成做个单词标记。然后将这些单词标记转换成小写,然后删除过滤词,并将单词转换成词干(foxes → fox,jumped → jump,lazy → lazi),最后将term存储在倒排索引中。

mapping中的每个 text 类型字段都可以指定自己的 analyzer

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "title": {
          "type":     "text",
          "analyzer": "standard"
        }
      }
    }
  }
}

在写入索引时,如果没有指定 analyzer,它会在索引设置中查找名为 default 的分析器。 否则,它默认使用 standard 分析器。

搜索时分词

在 full text query 中,在搜索时将相同的分析过程应用于查询的字符串,例如 match query 将查询字符串中的文本转换的terms形式为存储在倒排索引中的存储的terms相同。

例如,用户可能会搜索:

"a quick fox"

这将由相同的english分析器分析为以下terms:

[ quick, fox ]

即使查询字符串中使用的确切单词没有出现在原始文本中(quick vs QUICKfox vs foxes),因为我们对文本和查询字符串中应用了相同的分析器 ,查询字符串中的terms与倒排索引中文本中的terms完全匹配,这意味着该查询将匹配我们的示例文档。

通常应在索引时和搜索时使用相同的分析器。以及 全文查询 像 match 查询 将使用映射来查找每个字段使用的分析器。

用来搜索特定字段的分析器通过查找以下内容来确定:

  • 在查询体本身中指定的analyzer
  • search_analyzer 映射参数。
  • analyzer 映射参数。
  • 索引设置中称为default_search的分析器。
  • 索引设置中称为default的分析器。
  • standard分析器。

测试分词效果

ES提供了一个analyze API ,用来查询分词的结果。

Positions and character offsets

As can be seen from the output of the analyze API, analyzers not only convert words into terms, they also record the order or relative positions of each term (used for phrase queries or word proximity queries), and the start and end character offsets of each term in the original text (used for highlighting search snippets).
位置和字符偏移

从analyze API的输出可以看出,analyzer不仅将语句转化为词,还记录了每个词的顺序或相对位置(用于词组查询或词邻近查询),以及词的开始和结束字符偏移量。 原始文本中的每个更专业的词汇(用于突出显示搜索片段)。

在请求体重内联式的指定分词器:

POST _analyze
{
  "analyzer": "whitespace",
  "text":     "The quick brown fox."
}	

也可以在请求中内联指定内置标记器、标记过滤器和字符过滤器的组合:

POST _analyze
{
  "tokenizer": "standard",
  "filter":  [ "lowercase", "asciifolding" ],
  "text":      "Is this déja vu?"
}

同样的也可以在自定义类型的分词器中运行analyze API :

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_folded": {              // 自定义一个叫std_folded的分析器
          "type": "custom",
          "tokenizer": "standard",   // 标准标记器
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "my_text": {
          "type": "text",
          "analyzer": "std_folded"  // 在my_text字段上使用了这个分析器
        }
      }
    }
  }
}



GET my_index/_analyze             // 通过api直接指明分词器的方式分词效果
{
  "analyzer": "std_folded", 
  "text":     "Is this déjà vu?"
}


GET my_index/_analyze            // 通过api查询字段使用的分词器查询分词效果
{
  "field": "my_text", 
  "text":  "Is this déjà vu?"
}

分词器的分类

ES内置的分词器有(以6.7版本为基准):

  • Standard Analyzer
  • Simple Analyzer
  • Whitespace Analyzer
  • Stop Analyzer
  • Keyword Analyzer
  • Pattern Analyzer
  • Language Analyzers
  • Fingerprint Analyzer
  • Custom Analyzer

中文分词器:

  • IK分词器
  • pinyin分词器

使用示例

以Standard Analyzer为例

standard 分析器是默认的分析器,如果没有指定则使用。 它提供基于语法的标记化(基于 Unicode 标准附件 #29 中指定的 Unicode 文本分段算法),并且适用于大多数语言。

内置的标准分析器包含以下部分:

  • 分词器:英文分词可以根据空格将单词分开,中文分词比较复杂,可以采用机器学习算法来分词。

    • Standard Tokenizer
  • Token过滤器:对切分的单词进行加工。

    • Standard Token Filter:一个标准类型的标记过滤器,对使用标准标记器提取的标记进行规范化。是一个保留项,啥都不干,在6.5.0之后已经不建议使用
    • Lower Case Token Filter:默认的都是将英文转成小写的
    • Stop Token Filter (disabled by default)

测试分析效果

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

上面的句子将产生以下词:

[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog's, bone ]

在本例中,我们将 standard 分析器配置为 max_token_length 为 5(出于演示目的),并使用预定义的英语停用词列表:

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english_analyzer": {
          "type": "standard",     // 分词器类型
          "max_token_length": 5,  // 可以分词的词汇的最大长度为5
          "stopwords": "_english_"// 过滤词汇
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_english_analyzer",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

分词结果如下

[ 2, quick, brown, foxes, jumpe, d, over, lazy, dog's, bone ]

如果需要配置参数之外的标准型分词器,那么您需要将其重新创建为 custom 分词器并对其进行修改,通常是通过添加token过滤器。 这将重新创建内置的standard分析器:

PUT /standard_example
{
  "settings": {
    "analysis": {
      "analyzer": {
        "rebuilt_standard": {       // 自定义定义分词器名称
          "tokenizer": "standard",
          "filter": [
            "lowercase"       
          ]
        }
      }
    }
  }
}

其他:Normalizers(规范器)

规范器与分析器类似,只是它们只能发出一个标记。 因此,它们没有标记器,只接受可用字符过滤器标记过滤器的子集。 只允许使用基于每个字符的过滤器。 例如,允许使用小写过滤器,但不允许使用词干过滤器,它需要将关键字视为一个整体。 当前可以在规范化器中使用的过滤器列表如下:arabic_normalizationasciifoldingbengali_normalizationcjk_widthdecimal_digitelisiongerman_normalizationhindi_normalizationindic_normalization , 小写, persian_normalization, scandinavian_folding, serbian_normalization, sorani_normalization, uppercase

到目前为止,Elasticsearch 还没有内置规范化器,因此获得规范化器的唯一方法是构建自定义规范化器。 自定义规范化器采用 字符过滤器和token filters。

PUT index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "quote": {
          "type": "mapping",
          "mappings": [
            "« => \"",
            "» => \""
          ]
        }
      },
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": ["quote"],
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "foo": {
          "type": "keyword",
          "normalizer": "my_normalizer"
        }
      }
    }
  }
}

http://www.niftyadmin.cn/n/1096534.html

相关文章

Spring学习总结(1)——Spring AOP的概念理解

1.我所知道的aop 初看aop,上来就是一大堆术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等。一下子让你不知所措,心想着:怪不得 很多人都和我说aop多难多难 。当我看进去以后,我才发现…

ViewPager调用setCurrentItem(position)时,跳转Fragment 问题

摘要:在使用ViewPagerFragment 进行跳转的时候出现,闪屏的一个效果!我们的目的是点击某个Item的时候跳转到指定的Fragment,为此在我们使用viewPager.setCurrentItem(position) 就会出现这中问题! 经过一番查找发现Vie…

ORACLE里锁有以下几种模式,v$locked_object,locked_mode

ORACLE里锁有以下几种模式:0:none1:null 空2:Row-S 行共享(RS):共享表锁,sub share 3:Row-X 行独占(RX):用于行的修改,sub exclusive 4:Share 共享锁(S):阻止…

Java Lambda 表达式的官网教程理解

文章目录Lambda 表达式Lambda 表达式的语法Lambda 表达式的理想用例方法 1: 创建搜索匹配一个特征的成员的方法方法 2: 创建更通用的搜索方法方法 3: 在局部类中指定搜索条件代码方法 4: 在匿名类中指定搜索条件代码方法 5: 使用 Lambda 表达式指定搜索条件代码方法 6: 使用带有…

单例模式 线程安全

转载请注明:http://cantellow.iteye.com/blog/838473 第一种(懒汉,线程不安全): public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (insta…

CentOS下安装MySQL,Windows下使用Navicat for MySql连接

安装查看有没有安装过:yum list installed mysql*rpm -qa | grep mysql*查看有没有安装包:yum list mysql*安装mysqlclient:yum install mysql安装mysql server端:yum install mysql-serveryum install mysql-devel启动&&…

poj2689:素数筛

题目大意,给定l和u,求区间[l,u]内的素数中,相邻两个差最大和最小的素数其中 u的范围达到了2e9本质上需要找出n以内的所有素数,使用筛法。先保存50000(大于sqrt(2e9))内的所有素数,然后再去筛出区间[l,u]内的素数&#…

JAVA缓存- JSR107 最终规范

文章目录JSR107 java 缓存规范什么是缓存目标Java 缓存 API 未解决包基础知识核心概念Map与Cache的异同点一致性默认一致性更多一致性模型缓存拓扑执行上下文可重入简单示例JSR107 java 缓存规范 原文地址:https://download.oracle.com/otndocs/jcp/jcache-1_0-fr-e…