• ES-分词器


    简介

    分词器是es中的一个组件,通俗意义上理解,就是将一段文本按照一定的逻辑,分析成多个词语,同时对这些词语进行常规化的一种工具;ES会将text格式的字段按照分词器进行分词,并编排成倒排索引,正是因为如此,es的查询才如此之快。

    一个analyzer即分析器,无论是内置的还是自定义的,只是一个包含character filters(字符过滤器)、 tokenizers(分词器)、token filters(令牌过滤器)三个细分模块的包。

    看下这三个细分模块包的作用:

    character filters(字符过滤器):分词之前的预处理,过滤无用字符

    token filters(令牌过滤器)停用词、时态转换,大小写转换、同义词转换、语气词处理等。

    tokenizers(分词器):切词

    自定义分词器

    先来看个自定义分词器,了解整个分析器analyzer的构造

    PUT custom_analysis
    {
      "settings":{
        "analysis":{	#分析配置,可以设置char_filter(字符过滤器)、filter(令牌过滤器)、tokenizer(分词器)、analyzer(分析器)
          "char_filter": { # 字符过滤器配置
            "my_char_filter":{ #定义一个字符过滤器:my_char_filter
              "type":"mapping", # 字符过滤器类型:主要有三种:html_strip(标签过滤)、mapping(字符替换)、pattern_replace(正则匹配替换)
              "mappings":[	# mapping的参数:表示 '&' 会被替换成 'and'
                "& => and",
                "| => or"
              ]
            },
            "html_strip_char_filter":{
              "type":"html_strip",
              "escaped_tags":["a"]
            }
          },
          "filter": {	# 令牌过滤器配置
            "my_stopword":{ # 定义一个令牌过滤器:my_stopword
              "type":"stop", # 令牌过滤器类型:stop(停用(删除)词)
              "stopwords":[	# stop的参数:表示这些词会被删除
                "is",
                "in",
                "the",
                "a",
                "at",
                "for"
              ]
            }
          },
          "tokenizer": {	# 分词器配置
            "my_tokenizer":{ # 定义一个分词器my_tokenizer
              "type":"pattern", # 分词器类型:pattern 正则匹配
              "pattern":"[ ,.!?]" # pattern的参数:会根据这几个字符进行分割
            }
          },
          "analyzer": {	# 分析器:可以理解成组合了字符过滤器、令牌过滤器、分词器的一个整体。
            "my_analyzer":{ #定义一个分析器:my_analyzer
              "type":"custom", 
              "char_filter":["my_char_filter","html_strip_char_filter"], # 使用的字符过滤器
              "filter":["my_stopword"], # 使用的令牌过滤器
              "tokenizer":"my_tokenizer" # 使用的分词器
            }
          }
        }
      }
    }

    字符过滤器(character filters)

    字符过滤器是分词之前的预处理,过滤无用字符,主要有这三种:html_strip、mapping、pattern_replace

    html_strip

    html_strip用于过滤html标签,它有个参数escaped_tags可以设置保留的标签

    看下面例子

    PUT index_html_strip
    {
      "settings": {
        "analysis": {
          "char_filter": {
            "my_char_filter":{
              "type":"html_strip",
              "escaped_tags":["a"] 
            }
          },
          "analyzer": {
            "my_analyzer":{
              "tokenizer":"keyword",
              "char_filter":["my_char_filter"]
            }
          }
        }
      }
    }
    GET my_index/_analyze
    {
      "analyzer": "my_analyzer",
      "text": "

    要的话就点击

    " }

    结果:p标签过滤掉了,而a标签保留了

    mapping

    mapping是字符替换

    看下面例子,可以设置一些敏感词替换成*

    PUT index_mapping
    {
      "settings": {
        "analysis": {
          "char_filter": {
            "my_char_filter":{
              "type":"mapping",
              "mappings":[
                "滚 => *",
                "垃圾 => *",
                "手枪 => *",
                "你妈 => *"
                ] 
            }
          },
          "analyzer": {
            "my_analyzer":{
              "tokenizer":"keyword",
              "char_filter":["my_char_filter"]
            }
          }
        }
      }
    }
    GET index_mapping/_analyze
    {
      "analyzer": "my_analyzer",
      "text": "你妈的,小垃圾,拿上你的手枪,滚远点!"
    }

    结果:可以看到设置的敏感词被替换成*了

    pattern_replace

    pattern_replace是正则匹配替换

    可以匹配手机号码,将中间四个数字加密处理

    PUT index_pattern_replace
    {
      "settings": {
        "analysis": {
          "char_filter": {
            "my_char_filter":{
              "type":"pattern_replace",
              "pattern":"(\\d{3})\\d{4}(\\d{4})",
              "replacement":"$1****$2"
            }
          },
          "analyzer": {
            "my_analyzer":{
              "tokenizer":"keyword",
              "char_filter":["my_char_filter"]
            }
          }
        }
      }
    }
    GET index_pattern_replace/_analyze
    {
      "analyzer": "my_analyzer",
      "text": "你的手机号是18814142694"
    }

    结果:

    令牌过滤器(token filters)

    停用词(stop)、大小写转换(lowercase)、同义词转换(synonym)等。

    stop-停用词

    停用词有个参数可以设置删除的词语:stopwords

    PUT /index_stop
    {
      "settings": {
          "analysis": {
            "analyzer": {
              "my_stop": {
                "tokenizer": "whitespace",
                "filter": [ "my_stop" ]
              }
            },
            "filter": {
              "my_stop": {
                "type": "stop",
                "stopwords": [
                "is",
                "in",
                "the",
                "a",
                "at",
                "for"
              ]
              }
            }
          }
        }
    }
    GET index_stop/_analyze
    {
      "analyzer": "my_stop",
      "text": ["What is a apple?"]
    }

    结果:

    synonym-同义词

    同义词过滤器需要配置同义词的文件路径synonyms_path,需要放在项目目录下的config文件目录里

    (本项目同义词文件完整路径:/app/elasticsearch-8.4.2/config/analysis/synonym.txt)

    蒙丢丢 => 'DaB'
    PUT /index_synonym
    {
      "settings": {
          "analysis": {
            "analyzer": {
              "synonym": {
                "tokenizer": "whitespace",
                "filter": [ "synonym" ]
              }
            },
            "filter": {
              "synonym": {
                "type": "synonym",
                "synonyms_path": "analysis/synonym.txt"
              }
            }
          }
        }
    }
    GET index_synonym/_analyze
    {
      "analyzer": "synonym",
      "text": ["蒙丢丢"]
    }

    结果:

    分词器(tokenizer)

    分词器的作用就是用来切词的。

    常见的分词器有:

    standard:默认分词器,中文支持的不理想,会逐字拆分

    pattern:以正则匹配分隔符,把文本拆分成若干词项

    simple pattern:以正则匹配词项,速度比pattern tokenizer快

    whitespace:以空白符分割

    GET _analyze
    {
      "analyzer": "whitespace",
      "text": ["What is a apple?"]
    }

    结果

    中文分词器

    ES的中文分词器需要下载插件安装使用的。

    安装&部署

    ik下载地址:GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary.


    点击Releases,选择版本下载


    在根目录下的plugins文件夹下,创建ik文件目录,将下载的插件解压到ik目录下

    ik配置文件说明

    IKAnalyzer.cfg.xml:IK分词配置文件
    main.dic:主词库:
    stopword.dic:英文停用词,不会建立在倒排索引中
    quantifier.dic:特殊词库:计量单位等
    suffix.dic:特殊词库: 后级名
    surname.dic: 特殊词库: 百家姓
    preposition:特殊词库: 语气词
    自定义词库:网络词汇、流行词、自造词等

    重启ES

    /app/elasticsearch-8.4.2/bin/elasticsearch -d
    /app/kibana-8.4.2/bin/kibana &

    使用

    GET _analyze
    {
      "analyzer": "ik_max_word",  #中文分词器:ik_max_word
      "text": ["今天真是美好的一天"]
    }

    结果

    {
      "tokens": [
        {
          "token": "今天",
          "start_offset": 0,
          "end_offset": 2,
          "type": "CN_WORD",
          "position": 0
        },
        {
          "token": "天真",
          "start_offset": 1,
          "end_offset": 3,
          "type": "CN_WORD",
          "position": 1
        },
        {
          "token": "真是",
          "start_offset": 2,
          "end_offset": 4,
          "type": "CN_WORD",
          "position": 2
        },
        {
          "token": "美好",
          "start_offset": 4,
          "end_offset": 6,
          "type": "CN_WORD",
          "position": 3
        },
        {
          "token": "的",
          "start_offset": 6,
          "end_offset": 7,
          "type": "CN_CHAR",
          "position": 4
        },
        {
          "token": "一天",
          "start_offset": 7,
          "end_offset": 9,
          "type": "CN_WORD",
          "position": 5
        },
        {
          "token": "一",
          "start_offset": 7,
          "end_offset": 8,
          "type": "TYPE_CNUM",
          "position": 6
        },
        {
          "token": "天",
          "start_offset": 8,
          "end_offset": 9,
          "type": "COUNT",
          "position": 7
        }
      ]
    }

  • 相关阅读:
    .net 转java 项目管理浅谈
    python-while循环
    react 使用useRoutes遇到的问题
    Java进阶面试问题列表
    【入门】求n个数中出现次数最多的数
    职场Excel:求和家族,不简单
    基于IDEA创建SpringBoot项目并进行入门分析
    推荐算法 面试
    《TCP/IP网络编程》阅读笔记--Socket类型及协议设置
    Nacos集群分区
  • 原文地址:https://blog.csdn.net/weixin_39682289/article/details/127911695