热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Elasticsearch中文分词及全文检索

分词就是指将一个文本转化成一系列单词的过程,也叫文本分析,在Elasticsearch中称之为Analysis。分词API接口:POSThttp:192.168.12.10:920

分词就是指将一个文本转化成一系列单词的过程,也叫文本分析,在Elasticsearch中称之为Analysis。

分词API

接口:POST http://192.168.12.10:9200/_analyze
参数

{
"analyzer":"standard",
"text":"我是中国人"
}

中文分词器 IK Analyzer

IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IK Analyzer 3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现

IKAnalyzer 插件安装

下载 下载地址 https://download.csdn.net/download/zhangxm_qz/12553781
解压文件到 ES安装目录 plugins下
yum install -y unzip zip –安装 unzip命令
unzip elasticsearch-analysis-ik-6.5.4.zip –解压安装文件

[root@localhost plugins]# ll
总用量 0
drwxr-xr-x. 5 root root 135 11月 20 2018 zk
[root@localhost plugins]#

重启es服务

IKAnalyzer 插件测试

调用接口测试
POST http://192.168.12.10:9200/_analyze

参数:

{
"analyzer":"ik_max_word",
"text":"我是中国人"
}

响应

{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "中国人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 2
},
{
"token": "中国",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 3
},
{
"token": "国人",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 4
}
]
}

全文检索测试

准备数据

创建索引

PUT http://192.168.12.10:9200/myindex2

{
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "0"
}
},
"mappings": {
"person": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
},
"mail": {
"type": "keyword"
},
"hobby": {
"type": "text",
"analyzer":"ik_max_word"
}
}
}
}
}

添加数据

接口 :POST http://192.168.12.10:9200/myindex2/person/_bulk
参数:

{"index":{"_index":"myindex2","_type":"person"}}
{"name":"张三","age": 20,"mail": "111@qq.com","hobby":"羽毛球、乒乓球、足球"}
{"index":{"_index":"myindex2","_type":"person"}}
{"name":"李四","age": 21,"mail": "222@qq.com","hobby":"羽毛球、乒乓球、足球、篮球"}
{"index":{"_index":"myindex2","_type":"person"}}
{"name":"王五","age": 22,"mail": "333@qq.com","hobby":"羽毛球、篮球、游泳、听音乐"}
{"index":{"_index":"myindex2","_type":"person"}}
{"name":"赵六","age": 23,"mail": "444@qq.com","hobby":"跑步、游泳、篮球"}
{"index":{"_index":"myindex2","_type":"person"}}
{"name":"孙七","age": 24,"mail": "555@qq.com","hobby":"听音乐、看电影、羽毛球"}

数据如下:
《Elasticsearch中文分词及全文检索》

单词搜索

POST http://192.168.12.10:9200/myindex2/person/_search
参数:

{
"query":{
"match":{
"hobby":"音乐"
}
},
"highlight": {
"fields": {
"hobby": {}
}
}
}

查询出 爱好包含音乐的两个用户

过程说明

  1. 检查字段类型
    爱好 hobby 字段是一个 text 类型( 指定了IK分词器),这意味着查询字符串本身也应该被分词。
  2. 分析查询字符串 。
    将查询的字符串 “音乐” 传入IK分词器中,输出的结果是单个项 音乐。因为只有一个单词项,所以 match 查询执行的是单个底层 term 查询。
  3. 查找匹配文档
    用 term 查询在倒排索引中查找 “音乐” 然后获取一组包含该项的文档,本例的结果是文档:3 、5 。
  4. 为每个文档评分
    用 term 查询计算每个文档相关度评分 _score ,这是种将 词频(term frequency,即词 “音乐” 在相关文档的hobby 字段中出现的频率)和 反向文档频率(inverse document frequency,即词 “音乐” 在所有文档的hobby 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式
多词搜索

POST http://192.168.12.10:9200/myindex2/person/_search
参数:

{
"query":{
"match":{
"hobby":"音乐 篮球"
}
},
"highlight": {
"fields": {
"hobby": {}
}
}
}

可以看到,只要包含了“音乐”、“篮球” 中某一个的数据都被搜索到了。二者是或的关系。如果我们想搜索的是既包含“音乐”又包含“篮球”的用户,以指定词之间的逻辑关系,如下,这样就只查询出一个用户数据

{
"query":{
"match":{
"hobby":{
"query":"音乐 篮球",
"operator":"and"
}
}`在这里插入代码片`
},
"highlight": {
"fields": {
"hobby": {}
}
}
}

“OR” 和 “AND”搜索,这是两个极端,其实在实际场景中,并不会选取这2个极端,大多时候是只需要符合一定的相似度就可以查询到数据,在Elasticsearch中也支持这样的查询,通过minimum_should_match来指定匹配度,如:80%。

如下查询就只返回匹配度大于80%的数据4条数据

{
"query":{
"match":{
"hobby":{
"query":"游泳 羽毛球",
"minimum_should_match":"80%"
}
}
},
"highlight": {
"fields": {
"hobby": {}
}
}
}

组合搜索

可以通过bool组合查询如下:
查询 必须包含篮球,不能包含音乐,如果包含了游泳,那么它的相似度更高 的结果

{
"query":{
"bool":{
"must":{
"match":{
"hobby":"篮球"
}
},
"must_not":{
"match":{
"hobby":"音乐"
}
},
"should":[
{
"match": {
"hobby":"游泳"
}
}
]
}
},
"highlight": {
"fields": {
"hobby": {}
}
}
}

结果如下:

{
"took": 46,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1.8336569,
"hits": [
{
"_index": "myindex2",
"_type": "person",
"_id": "cTw053IBd5Ym0N5fXExh",
"_score": 1.8336569,
"_source": {
"name": "赵六",
"age": 23,
"mail": "444@qq.com",
"hobby": "跑步、游泳、篮球"
},
"highlight": {
"hobby": [
"跑步、游泳篮球"
]
}
},
{
"_index": "myindex2",
"_type": "person",
"_id": "bzw053IBd5Ym0N5fXExh",
"_score": 0.50270504,
"_source": {
"name": "李四",
"age": 21,
"mail": "222@qq.com",
"hobby": "羽毛球、乒乓球、足球、篮球"
},
"highlight": {
"hobby": [
"羽毛球、乒乓球、足球、篮球"
]
}
}
]
}
}

bool 查询会为每个文档计算相关度评分 _score , 再将所有匹配的 must 和 should 语句的分数 _score 求和
must_not 语句不会影响评分; 它的作用只是将不相关的文档排除。
默认情况下,should中的内容不是必须匹配的,如果查询语句中没有must,那么就会至少匹配其中一个。也可以通过minimum_should_match参数进行控制,该值可以是数字也可以的百分比.
如下should最好满足两个会被查询出

{
"query":{
"bool":{
"should":[
{
"match": {
"hobby":"游泳"
}
},
{
"match": {
"hobby":"篮球"
}
},
{
"match": {
"hobby":"音乐"
}
}
],
"minimum_should_match":2
}
},
"highlight": {
"fields": {
"hobby": {}
}
}
}

结果如下:

{
"took": 24,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 2.135749,
"hits": [
{
"_index": "myindex2",
"_type": "person",
"_id": "cDw053IBd5Ym0N5fXExh",
"_score": 2.135749,
"_source": {
"name": "王五",
"age": 22,
"mail": "333@qq.com",
"hobby": "羽毛球、篮球、游泳、听音乐"
},
"highlight": {
"hobby": [
"羽毛球、篮球游泳、听音乐"
]
}
},
{
"_index": "myindex2",
"_type": "person",
"_id": "cTw053IBd5Ym0N5fXExh",
"_score": 1.8336569,
"_source": {
"name": "赵六",
"age": 23,
"mail": "444@qq.com",
"hobby": "跑步、游泳、篮球"
},
"highlight": {
"hobby": [
"跑步、游泳篮球"
]
}
}
]
}
}

权重

有些时候,我们可能需要对某些词增加权重来影响该条数据的得分:
搜索关键字为“游泳篮球”,如果结果中包含了“音乐”权重为10,包含了“跑步”权重为2,如下:

{
"query": {
"bool": {
"must": {
"match": {
"hobby": {
"query": "游泳篮球",
"operator": "and"
}
}
},
"should": [
{
"match": {
"hobby": {
"query": "音乐",
"boost": 10
}
}
},
{
"match": {
"hobby": {
"query": "跑步",
"boost": 2
}
}
}
]
}
},
"highlight": {
"fields": {
"hobby": {}
}
}
}

结果:

{
"took": 46,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 9.484448,
"hits": [
{
"_index": "myindex2",
"_type": "person",
"_id": "cDw053IBd5Ym0N5fXExh",
"_score": 9.484448,
"_source": {
"name": "王五",
"age": 22,
"mail": "333@qq.com",
"hobby": "羽毛球、篮球、游泳、听音乐"
},
"highlight": {
"hobby": [
"羽毛球、篮球游泳、听音乐"
]
}
},
{
"_index": "myindex2",
"_type": "person",
"_id": "cTw053IBd5Ym0N5fXExh",
"_score": 5.4279313,
"_source": {
"name": "赵六",
"age": 23,
"mail": "444@qq.com",
"hobby": "跑步、游泳、篮球"
},
"highlight": {
"hobby": [
"跑步游泳篮球"
]
}
}
]
}
}

推荐阅读
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
  • 本文详细解析了微信服务端示例类的功能与应用。其中,`ClientResponseHandler` 类主要用于处理微信支付所需的响应数据,而 `TenpayHttpClient` 则是对 HTTP 请求(包括 GET 和 POST 方法)进行了封装,以便在内部调用时更加便捷和高效。这些工具类在实际开发中起到了关键作用,开发者无需深入了解其底层实现细节,即可轻松集成微信支付功能。 ... [详细]
  • 利用Jenkins与SonarQube集成实现高效代码质量检测与优化
    本文探讨了通过在 Jenkins 多分支流水线中集成 SonarQube,实现高效且自动化的代码质量检测与优化方法。该方案不仅提高了开发团队的代码审查效率,还确保了软件项目的持续高质量交付。 ... [详细]
  • ElasticSearch版本:elasticsearch-7.3.0环境准备:curl-HContent-Type:applicationjso ... [详细]
  • 检查APK文件是否已正确对齐
    本文介绍如何使用zipalign工具验证APK文件的对齐状态,并提供相关命令和下载链接。 ... [详细]
  • 本文介绍了几种常用的图像相似度对比方法,包括直方图方法、图像模板匹配、PSNR峰值信噪比、SSIM结构相似性和感知哈希算法。每种方法都有其优缺点,适用于不同的应用场景。 ... [详细]
  • 微信公众号推送模板40036问题
    返回码错误码描述说明40001invalidcredential不合法的调用凭证40002invalidgrant_type不合法的grant_type40003invalidop ... [详细]
  • 本文介绍了如何利用HTTP隧道技术在受限网络环境中绕过IDS和防火墙等安全设备,实现RDP端口的暴力破解攻击。文章详细描述了部署过程、攻击实施及流量分析,旨在提升网络安全意识。 ... [详细]
  • 本文介绍了如何在 macOS 上安装 HL-340 USB 转串口驱动,并提供了详细的步骤和注意事项。包括下载驱动、关闭系统完整性保护、安装驱动以及验证安装的方法。 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • 探索聚类分析中的K-Means与DBSCAN算法及其应用
    聚类分析是一种用于解决样本或特征分类问题的统计分析方法,也是数据挖掘领域的重要算法之一。本文主要探讨了K-Means和DBSCAN两种聚类算法的原理及其应用场景。K-Means算法通过迭代优化簇中心来实现数据点的划分,适用于球形分布的数据集;而DBSCAN算法则基于密度进行聚类,能够有效识别任意形状的簇,并且对噪声数据具有较好的鲁棒性。通过对这两种算法的对比分析,本文旨在为实际应用中选择合适的聚类方法提供参考。 ... [详细]
  • AppFog 是一个基于 CloudFoundry 的多语言 PaaS(平台即服务)提供商,允许用户在其平台上轻松构建和部署 Web 应用程序。本文将通过详细的图文步骤,指导读者如何在 AppFog 免费云平台上成功部署 WordPress,帮助用户快速搭建个人博客或网站。 ... [详细]
author-avatar
风铃草549天王
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有