一文搞懂match、match_phrase与match_phrase_prefix的检索过程

一、在开始之前,完成数据准备:

# 创建映射
PUT /tehero_index
{"settings": {"index": {"number_of_shards": 1,"number_of_replicas": 1}},"mappings": {"_doc": {"dynamic": false,"properties": {"id": {"type": "integer"},"content": {"type": "keyword","fields": {"ik_max_analyzer": {"type": "text","analyzer": "ik_max_word","search_analyzer": "ik_max_word"},"ik_smart_analyzer": {"type": "text","analyzer": "ik_smart"}}},"name":{"type":"text"},"createAt": {"type": "date"}}}}
}
# 导入测试数据
POST _bulk
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "1" } }
{ "id" : 1,"content":"关注我,系统学编程" }
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "2" } }
{ "id" : 2,"content":"系统学编程,关注我" }
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "3" } }
{ "id" : 3,"content":"系统编程,关注我" }
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "4" } }
{ "id" : 4,"content":"关注我,间隔系统学编程" }

二、根据ik_smart分词和content字段建立倒排序索引

原始数据:

{ "id" : 1,"content":"关注我,系统学编程" }
{ "id" : 2,"content":"系统学编程,关注我" }
{ "id" : 3,"content":"系统编程,关注我" }
{ "id" : 4,"content":"关注我,间隔系统学编程" }

ps:如果看不懂上图,请先阅读学习:ElasticSearch系列05:倒排序索引与分词Analysis

三、match query 对应到mysql

昨天有小伙伴反馈说,match query 的实例写得太枯燥,建议和mysql对比讲解,今天它来了!
# DSL 语句
GET /tehero_index/_doc/_search
{"query":{"match":{"content.ik_smart_analyzer":"系统编程"}}
}

DSL执行步骤分析:

  • 1)检索词“系统编程”被ik_smart分词器分词为两个Token【系统】【编程】;
  • 2)将这两个Token在【倒排索引】中,针对Token字段进行检索,等价于sql:【where Token = 系统 or Token = 编程】;
  • 3)对照图【数据的倒排序索引】,可见,该DSL能检索到所有文档,文档3的评分最高(因为它包含两个Token),其他3个文档评分相同。
有了对应到mysql 的例子,我想大家对match query 这个查询语句,就应该有一个很好的理解。那么接下来,开始学习今天的新知识: match_phrase query 和match_phrase_prefix query

四、match_phrase query

match_phrase查询分 析文本并根据分析的文本创建一个短语查询。match_phrase  会将检索关键词分词。match_phrase的分词结果必 须在被检索字段的分词中都包含,而且 顺序必须相同,而且 默认必须都是连续的。

简单看个例子,与match query 对比下,就很好理解了:

使用 match_phrase 查询:

# 使用match_phrase查询,ik_smart分词
GET /tehero_index/_doc/_search
{"query": {"match_phrase": {"content.ik_smart_analyzer": {"query": "关注我,系统学"}}}
}# 结果:只有文档1
{"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.7370664,"hits": [{"_index": "tehero_index","_type": "_doc","_id": "1","_score": 0.7370664,"_source": {"id": 1,"content": "关注我,系统学编程"}}]}
}

使用 match 查询:

# 使用match查询,ik_smart分词
GET /tehero_index/_doc/_search
{"query": {"match": {"content.ik_smart_analyzer": {"query": "关注我,系统学"}}}
}
# 可以查询出所有结果
分析:上面的例子使用的 分词器是ik_smart,所以 检索词“关注我,系统学”会被分词为3个Token【关注、我、系统学】;而文档1、文档2和文档4 的content被分词后 都包含这3个关键词,但是 只有文档1的Token的顺序和检索词一致,且连续。所以使用 match_phrase 查询 只能查询到文档1(ps:文档2 Token顺序不一致;文档4 Token不连续;文档3 Token没有完全包含)。 使用 match查询可以查询到所有文档,是因为所有文档 都有【关注、我】这两个Token
  • 4.1 match_phrase 核心参数:slop 参数-Token之间的位置距离容差值
# 将上面的 match_phrase 查询新增一个 slop参数
GET /tehero_index/_doc/_search
{"query": {"match_phrase": {"content.ik_smart_analyzer": {"query": "关注我,系统学","slop":1}}}
}
# 结果:文档1和文档4都被检索出来
分析:使用 analyze 接口 分析下文档4的Token
# 文档4 content 的分词
GET /_analyze
{"text": ["关注我,间隔系统学编程"],"analyzer": "ik_smart"
}
# 结果
{"tokens": [{"token": "关注","start_offset": 0,"end_offset": 2,"type": "CN_WORD","position": 0},{"token": "我","start_offset": 2,"end_offset": 3,"type": "CN_CHAR","position": 1},{"token": "间隔","start_offset": 4,"end_offset": 6,"type": "CN_WORD","position": 2},{"token": "系统学","start_offset": 6,"end_offset": 9,"type": "CN_WORD","position": 3},{"token": "编程","start_offset": 9,"end_offset": 11,"type": "CN_WORD","position": 4}]
}
通过分词测试,发现Token【我】与【系统学】的 position差值为1(等于slop的值 )所以文档4也被检索出来了。

ps:如果没看明白,那就来看下match_phrase query对应到mysql是怎样的吧!

  • 4.2match_phrase query对应到mysql
# DSL语句
GET /tehero_index/_doc/_search
{"query":{"match_phrase":{"content.ik_smart_analyzer":"系统编程"}}
}

DSL执行步骤分析:

  • 1)检索词“系统编程”被分词为两个Token【系统,Position=0】【编程,Position=1】;
  • 2)倒排索引检索时,等价于sql:【where Token = 系统 and 系统_Position=0 and Token = 编程 and 编程_Position=1】;
  • 3)对照图【数据的倒排序索引】,只有文档3满足条件,所以该DSL语句只能查询到文档3。

五、match_phrase_prefix query

与match_phrase查询类似,但是 会对最后一个Token在倒排序索引列表中进行通配符搜索。Token的模糊匹配数控制: max_expansions 默认值为50。我们使用 content.ik_smart_analyzer 这个字段中的 【系统学】(文档1、2、4 包含)和 【系统】(文档3包含)这 两个Token来讲解match_phraseprefix 的用法:(因为 使用的是ik_smart分词器,所以【系统学】就只能被分词为一个Token)
# 1、先使用match_phrase查询,没有结果
GET tehero_index/_doc/_search
{"query": {"match_phrase": {"content.ik_smart_analyzer": {"query": "系"}}}
}# 2、使用match_phrase_prefix查询, "max_expansions": 1,得到文档3
GET tehero_index/_doc/_search
{"query": {"match_phrase_prefix": {"content.ik_smart_analyzer": {"query": "系","max_expansions": 1}}}
}# 3、使用match_phrase_prefix查询, "max_expansions": 2,得到所有文档
GET tehero_index/_doc/_search
{"query": {"match_phrase_prefix": {"content.ik_smart_analyzer": {"query": "系","max_expansions": 2}}}
}
结果分析:【语句1】查不到结果,是因为 根据ik_smart分词器生成的倒排序索引中,所有文档中都 不包含Token【系】;【语句2】查询到文档3,是因为 文档3包含Token【系统】,同时 "max_expansions": 1,所以 检索关键词【系】+ 1个通配符匹配,就可以匹配到 一个Token【系统】;【语句3】查询到所有文档,是因为"max_expansions": 2,所以 检索关键词【系】+ 2个通配符匹配,就可以匹配到 两个Token【系统、系统学】,所以就可以查询到所有。回忆下,之前所讲的es倒排序索引原理: 先分词创建倒排序索引,再检索倒排序索引得到文档,就很好理解了

注意:"max_expansions"的值最小为1哪怕你设置为0,依然会 + 1个通配符匹配;所以,尽量不要用该语句,因为,最后一个Token始终要去扫描大量的索引性能可能会很差。

  • 5.1 match_phrase_prefix query 对应到mysql
GET tehero_index/_doc/_search
{"query": {"match_phrase_prefix": {"content.ik_smart_analyzer": {"query": "系","max_expansions": 1}}}
}

DSL执行步骤分析:

  • 1)检索词“系”被分词为一个个Token【系】+ 1个通配符;
  • 2)倒排索引检索时,等价于sql:【where Token = 系 or Token like “系_”】;
  • 3)对照图【数据的倒排序索引】,只有文档3满足条件包含Token【系统】,所以该DSL语句只能查询到文档3。

六、总结

到此,我们已经学习了 Full text queries最常用的3种查询:

1)match query:用于执行全文查询的标准查询,包括 模糊匹配和短语或接近查询。重要参数:控制Token之间的布尔关系:operator:or/and
2)match_phrase query:与match查询类似, 但用于匹配确切的短语或单词接近匹配。重要参数:Token之间的位置距离:slop 参数
3)match_phrase_prefix query:与match_phrase查询类似,但是会 对最后一个Token在倒排序索引列表中进行通配符搜索。重要参数:模糊匹配数控制:max_expansions 默认值50,最小值为1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/696238.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索气膜球幕影院:未来的电影体验

气膜球幕影院作为一种新兴的电影放映方式,正逐渐成为人们关注的焦点。它采用了充气式膜结构,可以为观众带来 360 度全景的观影体验,让人仿佛置身于电影之中。本文将介绍气膜球幕影院的特点、技术原理以及未来的发展前景。 传说在古代&#x…

Linux系统运维命令:使用 tail,grep组合命令(包括wc,sort,awk,sed等),可以方便的查阅和操作正在改变的日志文件的具体内容

一、命令介绍 1、tail命令 tail命令是Linux系统中常用的命令之一,用于查看文件的末尾内容。它具有许多有用的选项,可以帮助用户轻松地查找并显示文件中的信息。 它默认显示文件的最后10行,但可以通过各种选项来定制输出的行数、字节数等。ta…

十四、图像几何形状绘制

项目功能实现&#xff1a;矩形、圆形、椭圆等几何形状绘制&#xff0c;并与原图进行相应比例融合 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 drawing.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class DRAWING { public:void…

Python笔记-super().init(root)的作用

假设我们有一个名为Animal的父类&#xff0c;它有一个属性color&#xff0c;在其构造函数__init__中被初始化&#xff1a; class Animal:def __init__(self, color):self.color color现在&#xff0c;我们想创建一个Animal的子类&#xff0c;名为Dog。Dog类有自己的属性name&…

QPaint绘制自定义仪表盘组件01

网上抄别人的&#xff0c;只是放这里自己看一下&#xff0c;看完就删掉 ui Dashboard.pro QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomm…

【xss跨站漏洞】xss漏洞前置知识点整理

xss漏洞成因 xss漏洞是一种前端javascript产生的漏洞。 我们网站基本都是会用到javascript编写一些东西&#xff0c;浏览器也能直接识别javascript。 如果有一个地方能够输入文字&#xff0c;但是他又没有过滤你的输入&#xff0c;那么自己或者他人看到你输入的javascript代…

JVM知识——安全点

安全点是JVM要准备进行垃圾回收时&#xff0c;选定一些特定的位置&#xff0c;当应用程序线程执行到这些位置时&#xff0c;安全的先暂停下来&#xff0c;以便JVM执行GC线程进行垃圾回收。 JVM在字节码指令中会选取一些指令作为安全点&#xff0c;安全点的选取一般是循环结束、…

课时42:表达式_运算符_bc计算

3.1.5 bc计算 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 bc是一种任意精度的计算语言&#xff0c;提供了语法结构&#xff0c;比如条件判断、循环等&#xff0c;功能是很强大的&#xff0c;还能进行进制转换。常见参数-…

week04day02(爬虫02)

<span>: 通常用于对文本的一部分进行样式设置或脚本操作。<a>: 定义超链接&#xff0c;用于创建链接到其他页面或资源的文本。<img>: 用于插入图像。<br>: 用于插入换行。 姓名&#xff1a;<input type"text" value"lisi">…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第七天-内核函数接口(物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd1688 提取码&#xff1a;1688 //************************************************** #include <linux/module.h> /*module_init()*/ #include <linux/kernel.h> /* printk() *…

【析】考虑同时取送和时间窗的车辆路径及求解算法

期刊&#xff1a;computer engineering and applications 计算机工程与应用![c 引言 1. 问题分析 1.1 问题描述 问题描述为&#xff1a; 若干运输车辆从配送中心出发为客户取送货并最终返回配送中心&#xff0c;每位客户仅由一辆车服务一次&#xff0c;车辆在配送过程中任…

rust实战系列八:常量

在Rust中还可以用const关键字做声明。如下所示: const GLOBAL: i32 0; 使用const声明的是常量&#xff0c;而不是变量。因此一定不允许使用mut关键字修饰这 个变量绑定&#xff0c;这是语法错误。常量的初始化表达式也一定要是一个编译期常量&#xff0c;不 能是运行期的值。它…

ChatGPT丨成像光谱遥感技术中的AI革命:ChatGPT应用指南

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本课程重点介绍ChatGPT在遥感中的应用&#xff0c;人工智…

尾矿库排洪系统结构仿真软件WKStruc(可试用)

1、背景介绍 尾矿库作为重大危险源之一&#xff0c;在国际灾害事故排名中位列第18位&#xff0c;根据中国钼业2019年8月刊《中国尾矿库溃坝与泄漏事故统计及成因分析》的统计&#xff0c;在46起尾矿库泄漏事故中&#xff0c;由于排洪设施导致的尾矿泄漏事故占比高达1/3&#x…

c#创建安装windows服务

背景:最近在做设备数据对接采集时,遇到一些设备不是标准的Service-Client接口,导致采集的数据不够准确;比如设备如果中途开关机后,加工的数量就会从0开始重新计数,因此需要实时监控设备的数据,进行叠加处理;考略到工厂设备比较多,实时监听接口的数据为每秒3次,因此将…

外包干了三年,技术算是废了。。。

先说一下自己的个人情况&#xff0c;大专生&#xff0c;17年通过校招进入湖南某软件公司&#xff0c;干了接近5年的手工测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了五年的手工…

LeetCode.106. 从中序与后序遍历序列构造二叉树

题目 106. 从中序与后序遍历序列构造二叉树 分析 前面讲过根据前序和中序构建二叉树&#xff1a;博客链接 这道题是告诉我们一颗二叉树的后序和中序&#xff0c;让我们根据后序和中序构造出整颗二叉树。 拿到这道题&#xff0c;我们首先要知道中序的后序又怎样的性质&#…

云上业务一键性能调优,应用程序性能诊断工具 Btune 上线

- 01 - 终于等来了预算&#xff0c;这就把服务迁移到最新的 CPU 平台上去&#xff0c;这样前端的同事立马就能感受我们带来的速度提升了。可是…… 这些性能指标怎么回事&#xff1f;不仅没有全面提升&#xff0c;有些反而下降了。不应该这样啊&#xff0c;这可怎么办&#xf…

使用单一ASM-HEMT模型实现从X波段到Ka波段精确的GaN HEMT非线性仿真

来源&#xff1a;Accurate Nonlinear GaN HEMT Simulations from X- to Ka-Band using a Single ASM-HEMT Model 摘要&#xff1a;本文首次研究了ASM-HEMT模型在宽频带范围内的大信号准确性。在10、20和30 GHz的频率下&#xff0c;通过测量和模拟功率扫描进行了比较。在相同的频…

day05-进程通信

1> 将互斥机制的代码实现重新敲一遍 代码&#xff1a; #include<myhead.h>int num520;//临界资源//1.创建互斥锁 pthread_mutex_t fastmutex;//定义任务函数 void *task1(void *arg){printf("1111111\n");//3.临界区上面获取锁资源&#xff08;上锁&#…