ElasticSearch(六)— 全文检索

一、match系列查询

前面讲到的query中的查询,都是精准查询。可以理解成跟在关系型数据库中的查询类似。match系列的查询,是全文检索的查询。会通过分词进行评分,匹配,再返回搜索结果。

1.1 match 查询

"query": {"match": {"elk": "Elasticsearch LogStash Kibana"}
}

查询字符串是“Elasticsearch LogStash Kibana”,被分析器分词之后,产生三个小写的单词:elasticsearch logstash kibana,然后根据分析的结果构造一个布尔查询,默认情况下,引擎内部执行的查询逻辑是:只要 elk 字段值中包含有任意一个关键字 elasticsearch 或 logStash 或 kibana,那么返回该文档。
匹配查询的行为受到两个参数的控制:
operator:表示单个字段如何匹配查询条件的分词
minimum_should_match:表示字段匹配的数量。
通过调整 operator 和 minimum_should_match 属性值,控制匹配查询的逻
辑条件,进而控制引擎返回的结果。默认情况下 operator 的值是 or,在构造查询时设置分词之间的逻辑运算符,如果设置为 and,那么只有分词的每个词都匹配的文档,才能返回。
对于 minimum_should_match 属性值,默认值是 1,如果设置其值为 2,表示分词必须匹配查询条件的数量为 2,这意味着,只要文档的 elk 字段包含任意两个关键字,就满足查询条件,但是如果文档中只有 1 个关键字,这个文档就不满足条件。
例如:

POST indexname/_search{"query": {"match": {"message": {"query": "firefox chrome","operator": "and"}}}
}
或者:
POST indexname/_search{"query": {"match": {"message": {"query": "firefox chrome","minimum_should_match": 2}}}
}

只会返回文档中message字段同时包含firefox和chrome的文档,而只包含其中之一的不会返回。

1.2 multi_match 查询

多个字段上执行匹配相同的查询,叫做"multi_match"查询。比如:

POST indexname/_search{"query": {"multi_match": {"query": "AT","fields": ["DestCountry","OriginCountry"]}}
}

请求将同时检索文档中 DestCountry 和 OriginCountry 这两个字段,只要有一个字段包含 AT 词项该文档就满足查询条件。

1.3 match_phrase 查询

当你希望寻找邻近的单词时,match_phrase 查询可以帮你达到目的。比如:
假设我们要找到 title 字段包含这么一段文本“quick brown fox”的文档,然后我们用

GET indexname/_search{"query": {"match_phrase": {"title": "quick brown fox"}}
}

match_phrase 查询首先解析查询字符串来产生一个词条列表。然后会搜索所有的词条,但只保留包含了所有搜索词条的文档,并且词条的位置要邻接。
但是对于

GET /my_index/my_type/_search{"query": {"match_phrase": {"title": "quick fox"}}
}

这个查询查询不会匹配我们的任何文档,因为没有文档含有邻接在一起的
quick 和 fox 词条。也就是说,匹配的文档必须满足:
1、quick、brown 和 fox 必须全部出现在 title 字段中。
2、brown 的位置必须比 quick 的位置大 1。
3、fox 的位置必须比 quick 的位置大 2。

如果以上的任何一个条件没有被满足,那么文档就不能被匹配。
精确短语(Exact-phrase)匹配也许太过于严格了。也许我们希望含有"quick
brown fox"的文档也能够匹配"quick fox"查询,即使位置并不是完全相等的。
我们可以在短语匹配使用 slop 参数来引入一些灵活性:

GET /my_index/my_type/_search{"query": {"match_phrase": {"title": {"query": "quick fox","slop": 1}}}
}

match_phrase_prefix 查询
被称为基于前缀的短语匹配,比如:

{"match_phrase_prefix": {"brand": "johnnie walker bl"}
}

这种查询的行为与 match_phrase 查询一致,不同的是它将查询字符串的最
后一个词作为前缀使用,换句话说,可以将之前的例子看成如下这样:
johnnie跟着 walker,跟着以 bl 开始的词。
或者可以干脆理解为: “johnnie walker bl*”。
与 match_phrase 一样,它也可以接受 slop 参数(参照 slop )让相对词
序位置不那么严格。
prefix 查询存在严重的资源消耗问题,短语查询的这种方式也同样如此。前
缀 a 可能会匹配成千上万的词,这不仅会消耗很多系统资源,而且结果的用处也不大。
可以通过设置 max_expansions 参数来限制前缀扩展的影响,一个合理的值是 50 ,这也是系统默认的值:

{"match_phrase_prefix": {"brand": {"query": "johnnie walker bl","max_expansions": 50}}
}

二、模糊查询、纠错与提示器

2.1 编辑距离算法

在 Elasticsearch 基于全文的查询中,除了与短语相关的查询以外,其余查询都包含有一个名为 fuzziness 的参数用于支持模糊查询。Elasticsearch 支持的模糊查询与 SQL 语言中模糊查询还不一样,SQL 的模糊查询使用“% keyword%"的形式,效果是查询字段值中包含 keyword 的记录。

Elaticsearch 支持的模糊查询比这个要强大得多,它可以根据一个拼写错误的词项匹配正确的结果,例如根据firefix 匹配 firefox。在自然语言处理领域,两个词项之间的差异通常称为距离或编辑距离,距离的大小用于说明两个词项之间差异的大小。

编辑距离的算法有多种,在 Elasticsearch 中主要使用 Levenshtein 和 NGram两种。其他与此相关的算法也都是在这两种算法基础上进行的改造,基本思想都是一致的。所以理解这两个算法的核心思想是学习这部分内容的关键。

Levenshtein 与 NGram
Levenshein算法是前苏联数学家 Vladimir Levenshein在1965 年开发的一套算法, 这个算法可以对两个字符申的差异程度做量化。量化结果是一一个正整数,反映的是一个字符申变成另一个字符申最少需要多少次的处理。由于 Levenshtein算法是最为普遍接受的编辑距离算法,所以在很多文献中如果没有特殊说明编辑距离算法就是指 Levenshtein 算法。

在 Levenshtein 算法中定义了三种字符操作,即替换、插人和删除,后来又
由其他科学家补充了一个换位操作。在转换过程中,每执行次操作编辑距离就加1, 编辑距离越大越能说明两个字符串之间的差距大。

比如从 firefix 到 firefox 需要将“i"替换成“o”, 所以编辑距离为 1;而从 fax
到 fair 则需要将“x”替换为“i"并在结尾处插人“r”,所以编辑距离为 2。显然
在编辑距离相同的情况下,单词越长错误与正确就越接近。比如编辑距离同样为2 的情况下,从 fax 到 fair 与从 elascsearxh 到 elasticsearch,后者elastesearsh 是由拼写错误引起的可能性就更大此。所以编辑距离这种量化标准一般还需要与单词长度结合起来 明虑,在一些极端情况下编辑距离还应该设置为 0,比如像 at、on 这类长度只有 2 的短单词。

NGram 一般是指 N 个连续的字符,具体的字符个数被定义为 NGram 的 size。size 为 1 的 NGram 称为 Unigram, size 为 2 时称为 Bigram,而 size 为 3 时则称为Trigram。如果 NGram 处理的单元不是字符而是单词,一般称之为 Shingle。使用NGram 计算编辑距离的基本思路是让字符串分解为 NGram,然后比较分解后共有 NGram 的数量。假设有 a、b 两个字符申,则 NGram 距离的具体运算公式为:

ngram( a )+ngram(b) -2 * ngram(a)∩ngram( b)

ngram(a)和 ngram(b)代表 a、b 两个字符串 NGram 的数量; ngram(a) ∩
ngram(b)则是两者共有 NGram 的数量。
例如按 Bigram 处理 firefix 和 firefox 两个单词,分别为“fi,ir,re, ef, fi,ix”和“fi,ir, re, ef, fi, ox"。 那么两个字符申的 Bigram 个数都为 6,而共有 Bigram 为 4,则最终 NGram 距离为 6+6-2x4=4。
在应用上,Levenshtein 算法更多地应用于对单个词项的模糊查询上,而
NGram 则应用于多词项匹配中。Elasticseareh 同时应用了两种算法。

2.2 模糊查询

返回包含与搜索字词相似的字词文档;为了找到相似的术语,fuzzy 查询将
在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展。查询然后返回每个扩展的完全匹配。
比如:

get indexname/_search{"query": {"fuzzy": {"message": {"value": "firefix","fuzziness": "1"}}}
}

我们想找到文档中 message 字段包含 firefox,而查询条件中给出的是 firefix,因为两者的编辑距离为 1,所以包含 firefox 的文档依然可以找到,但是,如果使用 firefit,因为编辑距离为 2,则不会找到任何文档。

相关的参数有:
value: 必填项,希望在 field 中找到的术语。
fuzziness: 选填项,匹配允许的最大编辑距离;可以被设置为“0”, “1”,“2”或“auto”。“auto”是推荐的选项,它会根据查询词的长度定义距离。
max_expansions: 选填项,创建的最大变体项,默认为 50。应该避免使用较大的值,尤其是当 prefix_length 参数值为 0 时,如果过多,会影响查找性能。
prefix_length: 选填项,创建扩展时保留不变的开始字符数。默认为 0。
transpositions: 选填项,指示编辑是否包括两个相邻字符串的转置(ab→ba)。默认为 true。

2.3 纠错与提示器

纠错是在用户提交了错误的词项时给出正确词项的提示,而输人提示则是在
用户输人关键字时给出智能提示,甚至可以将用户未输人完的内容自动补全。大多数互联网搜索引擎都同时支持纠错和提示的功能,比如在用户提交了错误的搜索关键字时会提示:“ 你是不是想查找…”.而在用户输人搜索关键字时还能自动弹出提示框将用户可能要输人的内容全都列出来供用户选择。

Elasticsearch 也同时支持纠错与提示功能,由于这两个功能从实现的角度来说并没有本质区别,所以它们都由一种被称为提示器或建议器( Suggester)的特殊检索实现。由于输人提示需要在用户输人的同时给出提示词,所以这种功能要求速度必须快,否则就失去了提示的意义。在实现上,输人提示是由单独的提示器完成。而在使用上,提示器则是通过检索接口_ search 的一个参数设置,例如:

POST indexname/_search?filter_path=suggest{"suggest": {"msg-suggest": {"text": "firefit chrom","term": {"field": "message"}}}
}

在示例中,search 接口的 suggest 参数中定义了一个提示 msg- suggest,并通过 text 参数给出需要提示的内容。另一个参数 term 实际上是一种提示器的名称,它会分析 text 参数中的字符串并提取词项,再根据 Levenshtein 算法找到满足编辑距离的提示词项。所以在返回结果中会包含一个 suguggest 字段,其中列举了依照 term 提示器找到的提示词项:
在这里插入图片描述

2.3 提示器

Elaticearch 提供了三种提示器,它们在本质上都是基于编辑距离算法。下面就来看看这此提示器如何使用。
term 提示器
这种提示器默认使用的算法是称为 internal 的编辑距离算法。intermal 算法本质上就是 Levenshtein 算法,但根据 Elasticsearch 索引特征做了一些优化而效率更高,可以通过 string distance 参数更改算法。
term 提示器使用的编辑距离可通过 max
edits 参数设置,默认值为 2。

phrase 提示器
terms 会将需要提示的文本拆分成词项,然后对每一个词项做单独的提示,
而 phrase 提示器则会使用整个文本内容做提示。所以在 phrase 提示器的返回结果中,不会看到一个词项一个词项的提示,而是针对整个短语的提示。但从使用的角度来看几乎是一样的,例如:

POST indexname/_search{"suggest": {"msg-suggest": {"text": "firefix with chrime","phrase": {"field": "message"}}}
}

在这里插入图片描述
但不要被 phrase 提示器返回结果欺骗,这个提示器在执行时也会对需要提
示的文本内容做词项分析,然后再通过 NGram 算法计算整个短语的编辑距离。所以本质上来说,phrase 提示是基于 term 提示器的提示器,同时使用了Levenshtein 和 NGram 算法。

completion 提示器
completion 提示器一般应用于输人提示和自动补全,也就是在用户输人的同时给出提示或补全未输入内容。这就要求 completion 提示器必须在用户输人结束前快速地给出提示,所以这个提示器在性能上做了优化以达到快速检索的目的。
首先要求提示词产生的字段为 completion 类型,这是一种专门为completion提示器而设计的字段类型,它会在内存中创建特殊的数据结构以满足快速生成提示词的要求。例如在示例中创建了 aricles 索引,并向其中添加了 1 份文档:

PUT articles{"mappings": {"properties": {"author": {"type": "keyword"},"content": {"type": "text"},"suggestions": {"type": "completion"}}}
}
POST articles/_doc/{"author": "taylor","content": "an introduction of elastic stack and elasticsearch","suggestions": {"input": ["elastic stack","elasticsearch"],"weight": 10}
}
POST articles/_doc/{"author": "taylor","content": "an introduction of elastic stack and elasticsearch","suggestions": [{"input": "elasticsearch","weight": 30},{"input": "elastic stack","weight": 1}]
}

在向 completion 类型的字段添加内容时可以使用两个参数,input 参数设置
字段实际保存的提示词;而 weight 参数则设置了这些提示词的权重,权重越高它在返回的提示词中越靠前。在示例 5-29 中给出了两种设置提示词权重的方式,第一种是将一组提示词的权重设置为统一值,另一种则是分开设置它们的权重值。需要注意的是,completion 类型字段保存的提示词是不会分析词项的。
completion 提示器专门用于输人提示或补全,它根据用户已经输人的内容提示完整词项,所以在 completion 提示器中没有 text 参数而是使用 prefix 参数。例如:

POST articles/_search{"_source": "suggest","suggest": {"article_suggestion": {"prefix": "ela","completion": {"field": "suggestions"}}}
}

总结一下,term 和 phrase 提示器主要用于纠错,term 提示器用于对单个词项的纠错而 phrase 提示器则主要针对短语做纠错。completion 提示器是专门用于输人提示和自动补全的提示器,在使用上依赖前缀产生提示并且速度更快。

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

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

相关文章

.Net Core 微服务之Consul(三)-KV存储分布式锁

引言: 集合上两期.Net Core 微服务之Consul(一)(.Net Core 微服务之Consul(一)-CSDN博客) 。.Net Core 微服务之Consul(二)-集群搭建)(.Net Core 微服务之Consul(二)-集群搭建-CSDN博客) 目录 一. Consul KV 存储 1. KV 存储介绍 1.1 数据模型 1.2 一致性和…

Centos安装、迁移gitlab

Centos安装迁移gitlab 一、下载安装二、配置rb修改,起服务。三、访问web,个人偏好设置。四、数据迁移1、查看当前GitLab版本2、备份旧服务器的文件3、将上述备份文件拷贝到新服务器同一目录下,恢复GitLab4、停止新gitlab数据连接服务5、恢复备…

Docker、containerd、CRI-O 和 runc 之间的区别

容器与 Docker 这个名称并不紧密相关。你可以使用其他工具来运行容器 您可以使用 Docker 或一堆非Docker 的其他工具来运行容器。docker只是众多选项之一,Docker(公司)在生态系统中创建了一些很棒的工具,但不是全部。 容器方面有…

47.简易电压表的设计与验证(2)

(1)Verilog 代码: module adc_collect(input clk ,input reset_n ,input [7:0] adc_data ,output clk_adc );wire clk_adc_a ;…

大文件分片上传(前端TS实现)

大文件分片上传 内容 一般情况下,前端上传文件就是new FormData,然后把文件 append 进去,然后post发送给后端就完事了,但是文件越大,上传的文件也就越长,如果在上传过程中,突然网络故障,又或者…

【Linux操作系统】:进程间通信

目录 进程间通信介绍 1、进程间通信的概念 2、进程间通信的目的 3、进程间通信的本质 4、进程间通信的分类 管道 匿名管道 匿名管道的原理 pipe函数 创建匿名管道 管道的四种情况和五种特性 命名管道 使用命令创建命名管道 创建一个命名管道 命名管道的打开规则 …

【ROS2】高级:安全-理解安全密钥库

目标:探索位于 ROS 2 安全密钥库中的文件。 教程级别:高级 时间:15 分钟 内容 背景安全工件位置 公钥材料 私钥材料域治理政策 安全飞地 参加测验! 背景 在继续之前,请确保您已完成设置安全教程。 sros2 包可以用来创…

Qt自定义下拉列表-可为选项设置标题、可禁用选项

在Qt中,ComboBox(组合框)是一种常用的用户界面控件,它提供了一个下拉列表,允许用户从预定义的选项中选择一个。在项目开发中,如果简单的QComboBox无法满足需求,可以通过自定义QComboBox来实现更复杂的功能。本文介绍一个自定义的下…

Python研究生毕业设计,数据挖掘、情感分析、机器学习

最近在学校毕业了,其中有很多毕业论文使用到的代码,如数据挖掘、情感分析、机器学习、数据预测处理、划分数据集和测试集,绘制分类任务,词汇表示:使用TF-IDF向量化器,线性回归、多元线性回归、SVR回归模型&…

一文入门SpringSecurity 5

目录 提示 Apache Shiro和Spring Security 认证和授权 RBAC Demo 环境 Controller 引入Spring Security 初探Security原理 认证授权图示​编辑 图中涉及的类和接口 流程总结 提示 Spring Security源码的接口名和方法名都很长,看源码的时候要见名知意&am…

grafana对接zabbix数据展示

目录 1、初始化、安装grafana 2、浏览器访问 3、安装zabbix 4、zabbix数据对接grafana 5、如何导入模板? ① 设置键值 ② 在zabbix web端完成自定义监控项 ③ garafana里添加nginx上面的的三个监控项 6、如何自定义监控项? 以下实验沿用上一篇z…

二、原型模式

文章目录 1 基本介绍2 实现方式深浅拷贝目标2.1 使用 Object 的 clone() 方法2.1.1 代码2.1.2 特性2.1.3 实现深拷贝 2.2 在 clone() 方法中使用序列化2.2.1 代码 2.2.2 特性 3 实现的要点4 Spring 中的原型模式5 原型模式的类图及角色5.1 类图5.1.1 不限制语言5.1.2 在 Java 中…

免费【2024】springboot 趵突泉景区的智慧导游小程序

博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

开发桌面程序-Electron入门

Electron是什么 来自官网的介绍 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。 总…

普中51单片机:DS1302时钟芯片讲解与应用(十)

文章目录 引言基本特性什么是RAM?什么是涓流充电? 电路图和引脚说明通信协议以及工作流程寄存器控制寄存器日历/时钟寄存器 DS1302读写时序代码演示——数码管显示时分秒 引言 DS1302 是一款广泛使用的实时时钟 (RTC) 芯片,具有低功耗、内置…

本地部署VMware ESXi服务实现无公网IP远程访问管理服务器

文章目录 前言1. 下载安装ESXi2. 安装Cpolar工具3. 配置ESXi公网地址4. 远程访问ESXi5. 固定ESXi公网地址 前言 在虚拟化技术日益成熟的今天,VMware ESXi以其卓越的性能和稳定性,成为了众多企业构建虚拟化环境的首选。然而,随着远程办公和跨…

《昇思25天学习打卡营第19天|基于MobileNetv2的垃圾分类》

基于MobileNetv2的垃圾分类 本文档主要介绍垃圾分类代码开发的方法。通过读取本地图像数据作为输入,对图像中的垃圾物体进行检测,并且将检测结果图片保存到文件中。 1、实验目的 了解熟悉垃圾分类应用代码的编写(Python语言)&a…

机器学习 | 回归算法原理——多项式回归

Hi,大家好,我是半亩花海。接着上次的最速下降法(梯度下降法)继续更新《白话机器学习的数学》这本书的学习笔记,在此分享多项式回归这一回归算法原理。本章的回归算法原理基于《基于广告费预测点击量》项目,…

html+css+js前端作业 王者荣耀官网5个页面带js

htmlcssjs前端作业 王者荣耀官网5个页面带js 下载地址 https://download.csdn.net/download/qq_42431718/89574989 目录1 目录2 目录3 项目视频 王者荣耀5个页面(带js) 页面1 页面2 页面3 页面4 页面5

分布式Apollo配置中心搭建实战

文章目录 环境要求第一步、软件下载第二步、创建数据库参考文档 最近新项目启动,采用Apollo作为分布式的配置中心,在本地搭建huanj 实现原理图如下所示。 环境要求 Java版本要求:JDK1.8 MySql版本要求:5.6.5 Apollo版本要求&…