橘子学ES16之分词三大组件以及如何自己实现自己的分词器

这篇具有很好参考价值的文章主要介绍了橘子学ES16之分词三大组件以及如何自己实现自己的分词器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文来看一下ES的多字段特性,以及如何配置一个自定义的分词器。

一、多字段类型

多字段特性:
	可以实现精确匹配。
	可以使用不同的analyzer,就是搜索的时候是一个分词器,插入的时候是另一个分词器。

1、Exact Values && Full Text

精确值和全文检索值。精确值的意思就是不分词,不全文检索。当成mysql中的那种等值查询。全文文本值意思就是查询的时候走的是分词的路子,全文文本的匹配。

1.1、Exact Values

包括数字类型,日期类型,具体字符串类型(keyword类型),这几个类型在ES中是不分词的。
因为精确值不需要做分词的处理,所以ES为每一个精确值类型做索引的时候,不分词处理,就是简单的存进去一个倒排索引。不分词,存的是完整的词。怎么自定义一个es的分词插件,数据库,# ES,全文检索,搜索引擎,算法

1.2、Full Text

ES中的text类型走的就是Full Text的路子,是分词检索和索引的。

二、自定义分词器

当ES自带的分词器无法满足的时候,可以自定义分词器,通过自己组合不同的组件来实现不同的分词效果。
我们前面讲分词器的时候说过,ES中分词效果的实现是由三个组件实现的。分别是:

Character Filters
它是在Tokenizer之前对文本进行处理,例如增加删除以及替换文本字符,可以配置多个Character Filters 串行做处理,因为他处理了文本的内容,所以会影响Tokenizer的position和offset信息。
ES中内置了一些Character Filters分别是:
HTML strip:去除html标签
Mapping:字符串替换
Pattern replace:正则匹配替换
Tokenizer:
他的作用是讲原始的文本按照一定的规则,切分为分词,
ES内置的Tokenizer有:whitespace/standard/uax_url_email/pattern/keyword/path hierarchy 其中keyword不做任何处理,就是一个原样的。
也可以自己使用java开发插件,实现自己的Tokenizer。
Token Filter:
是将Tokenizer输出的单词(term)进行增加,修改,删除。
做一些后续处理,ES内置的Token Filter有
Lowercase /stop/synonym 分别是把大写字母转小写,增加停用词,增加近义词。
基于ES提供的这些内置组件,我们就可以在开发的时候自己定义自己的分析器实现对应你想要的效果。

下面我们就针对这些概念,自己实现一个自己想要的分词器。
怎么自定义一个es的分词插件,数据库,# ES,全文检索,搜索引擎,算法

1、去除html标签的分词组合

# 自己组装一个去除html标签的分词器效果
POST _analyze
{
  "tokenizer": "keyword",
  "char_filter": ["html_strip"],
  "text": "<b>hello es</b>"
}
注意我们这里就是看看测试效果,具体真的定义分词器不是在这里。类似做个单元测试。
keyword表示我们这个词hello es在索引的时候不做分词,插进去原样,取出来原样。
结果就是去掉了html标签。
{
  "tokens" : [
    {
      "token" : "hello es",  去掉了html标签
      "start_offset" : 3,
      "end_offset" : 15,
      "type" : "word",
      "position" : 0
    }
  ]
}

当我们做一些爬虫数据的时候,爬下来的数据可以做一个html标签的剥离。

2、使用char filter进行替换

#使用char filter进行替换
POST _analyze
{
  "tokenizer": "standard",
  "char_filter": [
      {
        "type" : "mapping",
        "mappings" : [ "- => _"]
      }
    ],
  "text": "123-456, I-test! test-990 650-555-1234"
}
这个分词我们使用的是标准分词,char_filter我们用的是mapping类型,其中的映射关系指定为把中划线转为下划线。注意对文本还是会分词的,标准的就是按照字母一个一个词分出来的。
{
  "tokens" : [
    {
      "token" : "123_456",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "<NUM>",
      "position" : 0
    },
    {
      "token" : "I_test",
      "start_offset" : 9,
      "end_offset" : 15,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "test_990",
      "start_offset" : 17,
      "end_offset" : 25,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "650_555_1234",
      "start_offset" : 26,
      "end_offset" : 38,
      "type" : "<NUM>",
      "position" : 3
    }
  ]
}
我们看到他把所有的中划线,转为了下划线,并且进行了分词。而且感叹号也被去掉了。

还可以把一些表情转为字符,我们把笑脸转为happy 把哭脸转为sad

//char filter 替换表情符号
POST _analyze
{
  "tokenizer": "standard",
  "char_filter": [
      {
        "type" : "mapping",
        "mappings" : [ ":) => happy", ":( => sad"]
      }
    ],
    "text": ["I am felling :)", "Feeling :( today"]
}

3、正则表达式

#正则表达式
GET _analyze
{
  "tokenizer": "standard",
  "char_filter": [
      {
        "type" : "pattern_replace",   
        "pattern" : "http://(.*)",
        "replacement" : "$1"
      }
    ],
    "text" : "http://www.elastic.co"
}
效果就是replace掉了http那块的正则表达式。
{
  "tokens" : [
    {
      "token" : "www.elastic.co",
      "start_offset" : 0,
      "end_offset" : 21,
      "type" : "<ALPHANUM>",
      "position" : 0
    }
  ]
}

4、指定分词组件tokenizer

4.1、按文件路径切分词汇

POST _analyze
{
  "tokenizer":"path_hierarchy",
  "text":"/user/ymruan/a/b/c/d/e"
}
这个分词组件会把你的路径按照级别全部拆分出来,你能查到所有的路径和子路径

  "tokens" : [
    {
      "token" : "/user",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "/user/ymruan",
      "start_offset" : 0,
      "end_offset" : 12,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "/user/ymruan/a",
      "start_offset" : 0,
      "end_offset" : 14,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "/user/ymruan/a/b",
      "start_offset" : 0,
      "end_offset" : 16,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "/user/ymruan/a/b/c",
      "start_offset" : 0,
      "end_offset" : 18,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "/user/ymruan/a/b/c/d",
      "start_offset" : 0,
      "end_offset" : 20,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "/user/ymruan/a/b/c/d/e",
      "start_offset" : 0,
      "end_offset" : 22,
      "type" : "word",
      "position" : 0
    }
  ]
}

5、定义filter

1、停用词的操作

# whitespace与stop
POST _analyze
{
  "tokenizer": "whitespace",
  "filter": ["stop"],
  "text": ["The rain in Spain falls mainly on the plain."]
}
我们的分词是按空格分的,同时指定了过滤掉一些停用词,前面说过诸如像介词之类的,a an the什么的。但是注意,the会被过滤,但是一旦有了大写字符就不会被过率了,所以第一个The是不会被过滤掉的。
{
  "tokens" : [
    {
      "token" : "The",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "rain",
      "start_offset" : 4,
      "end_offset" : 8,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "Spain",
      "start_offset" : 12,
      "end_offset" : 17,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "falls",
      "start_offset" : 18,
      "end_offset" : 23,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "mainly",
      "start_offset" : 24,
      "end_offset" : 30,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "plain.",
      "start_offset" : 38,
      "end_offset" : 44,
      "type" : "word",
      "position" : 8
    }
  ]
}
我们看到那些介词都没了,但是大写的Theh还在。其余的也是同理。

但是我们可以这样去掉The

#/remove 加入lowercase后,The被当成 stopword删除
POST _analyze
{
  "tokenizer": "whitespace",
  "filter": ["lowercase","stop"],
  "text": ["The gilrs in China are playing this game!"]
}
因为我们说filter是可以多个的,所以你在stop之前加一个转小写,The被转为the就能去掉了

  "tokens" : [
    {
      "token" : "gilrs",
      "start_offset" : 4,
      "end_offset" : 9,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "china",
      "start_offset" : 13,
      "end_offset" : 18,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "playing",
      "start_offset" : 23,
      "end_offset" : 30,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "game!",
      "start_offset" : 36,
      "end_offset" : 41,
      "type" : "word",
      "position" : 7
    }
  ]
}
注意一定要在前面转小写,你放到stop后面他先看停用发现你是大写The就被保留了,然后走转小写的过滤,最后就是the被保留了。

6、自己实现真的分词器

前面都是测试效果用的,现在就真的开始搞一个分词器给索引用。

#自定义分词器
PUT myindex    自己定义一个索引
{
  "settings": {      # 在setting里面配置分词配置
    "analysis": {
      "analyzer": {
        "my_div_analyzer":{   # 分词器的名字叫my_div_analyzer
          "type":"custom",  # 类型是自定义的
          "char_filter":["emoticons"],  # 过滤器是emoticons,下面自定义的
          "tokenizer": "punctuation",   # 分词组件是punctuation,下面自定义的
          "filter":[                    # 过滤器是大写转小写的,还有english_stop,这个english_stop是自己下面定义的
            "lowercase",
            "english_stop"
          ]
        }
      },
      "tokenizer": {
        "punctuation":{  # 自己定义的,名字自取。类型就是正则匹配,正则表达式自己写就行,按照逗号分词
          "type":"pattern",
          "pattern":"[.,!?]"
        }
      },
      "char_filter": {
        "emoticons":{ # 自己定义的,名字自取,类型是mapping的,笑脸转为happy,哭脸是sad
          "type" : "mapping",
          "mappings" : [
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      "filter": {
        "english_stop":{ # 自己定义的,名字自取,类型就是stop,禁用词类型是_english_,前面有说是默认的
          "type":"stop",
          "stopwords":"_english_"
        }
      }
    }
  }
}

测试一下:

POST myindex/_analyze
{
  "analyzer": "my_div_analyzer",
  "text": "I  am a :) person,and you?"
}
分词结果是:
{
  "tokens" : [
    {
      "token" : "i  am a _happy_ person",
      "start_offset" : 0,
      "end_offset" : 17,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "and you",
      "start_offset" : 18,
      "end_offset" : 25,
      "type" : "word",
      "position" : 1
    }
  ]
}
我们看到大写被转了小写,笑脸被转了happy,而且分词分开的也是按逗号分开的,这就是我们定义分词器的效果。

三、总结

我们既然知道了分词器的三个组成部件,也知道了它能随意组合,是一个类似插拔式的操作。所以我们就能根据ES内置的一些基础的组件随意组合。当然了进阶的你也可以自己以JAVA语言定义组件然后拿来组合。文章来源地址https://www.toymoban.com/news/detail-531039.html

到了这里,关于橘子学ES16之分词三大组件以及如何自己实现自己的分词器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Docker安装ElasticSearch、Kibana、IK分词器以及设置ES账户密码

    版本声明: 系统 :CentOS 7.9(云服务器) ES版本 :7.6.1 Kibana :7.6.1 Ik分析器版本 :7.6.1 1、拉取镜像 2、创建挂载目录 设置所有用户读写执行权限 : sudo chmod -R 777 /docker_config/elasticsearch/ 3、创建elasticsearch.yml 配置文件 4、创建容器 参数说明 : -p 端口映射 -e discovery.type=single

    2023年04月09日
    浏览(65)
  • 搜索引擎elasticsearch :安装elasticsearch (包含安装组件kibana、IK分词器、部署es集群)

    kibana可以帮助我们方便地编写DSL语句,所以还要装kibana 因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络: 这里我们采用elasticsearch的7.12.1版本的镜像,这个镜像体积非常大,接近1G。不建议大家自己pull。 课前资料提供了镜像的tar包: 大家将

    2024年02月16日
    浏览(55)
  • es 简单实现增加,查询,分词 热词

    看代码:  添加es中的表,index 表示表名 body 表示主体部分,然后执行,可以创建一个es 中的表格,相当于数据库中的数据表,现在还是空的表格,需要添加数据后在进行查询 添加: 先查询出添加数据库的数据,转为数组格式添加进es中 方便在随后的搜索中实现搜索 搜索:

    2024年02月15日
    浏览(44)
  • 橘子学ES安装与初步配置day01

    ES是个啥不多说了,就是做检索的。今天开始学习一下。不过所有的文章都不是最终笔记,都是最后会在不断的学习中做再次修改。 1、运行ES需要安装配置JDK环境,设置$JAVA_HOME 2、但是各个版本的ES对于jdk的要求是不一样的: ES5.x需要JAVA8以上的版本, 从ES6.5开始支持JAVA11,

    2024年02月11日
    浏览(32)
  • ElasticSearch 学习9 spring-boot ,elasticsearch7.16.1实现中文拼音分词搜索

    一、elasticsearch官网下载:Elasticsearch 7.16.1 | Elastic 二、拼音、ik、繁简体转换插件安装 ik分词:GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary. 拼音分词:GitHub - medcl/elasticsearch-analysis-pinyin: This Pinyin Analysis plugin is

    2024年01月22日
    浏览(49)
  • 第七章-分布式搜索引擎-ES:全文查询、分词查询、精确查询、地理坐标查询、组合查询(bool、funtion_score)以及RestApi

    DSL查询分类 全文查询、分词查询、非分词查询、地理坐标查询、组合查询 match_all 查询所有,不需要查询条件,固定写法_search 第一个hits就是命中的数据 ,total就是条数,第二个hits是source嘞   全文检索查询 我们不要整多个字段查询,参与的字段越多,查询速度越慢,如果有

    2024年01月16日
    浏览(79)
  • 如何使用torch.nn.utils.prune稀疏神经网络,以及如何扩展它以实现自己的自定义剪裁技术

    最新的深度学习技术依赖于难以部署的过度参数化模型。 相反,已知生物神经网络使用有效的稀疏连通性。 为了减少内存,电池和硬件消耗,同时又不牺牲精度,在设备上部署轻量级模型并通过私有设备上计算来确保私密性,确定通过减少模型中的参数数量来压缩模型的最

    2024年02月12日
    浏览(43)
  • B.16款超棒的开源软件—— 如何选择适合自己的开源软件并投入使用?

    作者:禅与计算机程序设计艺术 各行各业都在进行数字化转型,而数据分析、人工智能领域也逐渐进入人们生活中不可或缺的一部分。如何有效地利用数据获取价值已经成为各个企业考虑的重点。作为数据科学家或者机器学习工程师,在这个过程中需要掌握很多计算机相关的

    2024年02月06日
    浏览(53)
  • 云原生时代,如何构建自己的开源组件安全治理体系?

    「云原生安全既是一种全新安全理念,也是实现云战略的前提。 基于蚂蚁集团内部多年实践,云原生PaaS平台SOFAStack发布完整的软件供应链安全产品及解决方案,包括静态代码扫描Pinpoint,软件成分分析SCA,交互式安全测试IAST,运行时防护RASP,安全洞察Appinsight等,帮助企业客

    2024年02月02日
    浏览(50)
  • ES自定义分词,对数字进行分词

    需求:需要将下面类似的数据分词为:GB,T,32403,1,2015 我们使用的Unicode进行正则匹配,Unicode将字符编码分为了七类,其中 P代表标点 L 代表字母 Z 代表分隔符(空格,换行) S 代表数学符号,货币符号 M代表标记符号 N 阿拉伯数字,罗马数字 C其他字符 例如:所以pP的作用是匹配

    2024年02月15日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包