ElasticSearch(六)— 全文检索

news2024/11/18 5:33:53

一、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.coloradmin.cn/o/1949267.html

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

相关文章

按图搜索新体验:阿里巴巴拍立淘API返回值详解

阿里巴巴拍立淘API是一项基于图片搜索的商品搜索服务,它允许用户通过上传商品图片,系统自动识别图片中的商品信息,并返回与之相关的搜索结果。以下是对阿里巴巴拍立淘API返回值的详细解析: 一、主要返回值内容 商品信息 商品列表…

20240725项目的maven环境报红-重新配置maven

1.在编辑器里面打开项目,导入源码 (1)找到项目的地址C:\Users\zzz\IdeaProjects\datasys,然后右击用idea编辑器打开。 (2)idea中上菜单栏打开open,然后输入file,选择源代码文件 2.…

primetime如何合并不同modes的libs到一个lib文件

首先,用primetime 抽 timing model 的指令如下。 代码如下(示例): #抽lib时留一些margin, setup -max/hold -min set_extract_model_margin -port [get_ports -filter "!defined(clocks)"] -max 0.1 #抽lib extract_mod…

算法学习笔记(8.8)-多重背包

目录 Question: 思路解析: 代码示例 多重背包的优化问题: 1.二进制优化 代码示例: 2.单调队列优化(滑动窗口) 代码示例 Question: 4. 多重背包问题 I - AcWing题库https://www.acwing.com/problem/content/description/4/ 多重背包简单来说其…

深入理解 Java 虚拟机第三版(周志明)

这次社招选的这本作为 JVM 资料查阅,记录一些重点 1. 虚拟机历史 Sun Classic VM :已退休 HotSpot VM:主流虚拟机,热点代码探测技术 Mobile / Embedded VM :移动端、嵌入式使用的虚拟机 2.2 运行时数据区域 程序计…

基于java多媒体网络教学平台设计与开发

博主介绍:专注于Java .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的可以…

使用 Visual Studio 2022 自带的 cl.exe 测试编译 opencv helloworld

1. 参考博客&#xff1a;https://blog.csdn.net/yangSHU21/article/details/130237669( 利用OpenCV把一幅彩色图像转换成灰度图 )( 代码用的此博客的&#xff0c;就改了下图片文件路径而已 )。 2. 编译探索步骤&#xff1a; test.cpp&#xff1a; #include <iostream>…

三维点云深度网络 PointNeXt 的安装配置与测试

Title: 三维点云深度网络 PointNeXt 的安装配置与测试 文章目录 前言I. 环境创建1. 容器创建2. 容器中安装 CUDA Toolkit 11.3 II. 安装过程1. 安装 PointNeXt2. 解决安装问题 III. 数据准备1. 数据准备的执行2. 数据准备的原理 IV. 运行测试1. 显存溢出2. 训练3. 测试4. 标注颜…

UDP/TCP协议解析

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

mysql一个小问题引发的思考-mysql类型转换-查询缓存 及 MYSQL查询缓存以及自动选择不使用查询缓存的情况

一、mysql一个小问题引发的思考-mysql类型转换-查询缓存 最近在做的一个项目中有一个SQL语句发现点问题&#xff0c;大概如下&#xff1a; select * from table where cid0 or find_in_set(1, cid); 数据表中的字段cid是字符串类型&#xff0c;原来的后端同学未提过此字段还能是…

Pytorch使用教学3-特殊张量的创建与类型转化

1 特殊张量的创建 与numpy类似&#xff0c;PyTorch中的张量也有很多特殊创建的形式。 zeros:全0张量 # 形状为2行3列 torch.zeros([2, 3]) # tensor([[0., 0., 0.], # [0., 0., 0.]])ones:全1张量 # 形状为2行3列 torch.ones([2, 3]) # tensor([[1., 1., 1.], # …

IEC104转MQTT网关轻松将IEC104设备数据传输到Zabbix、阿里云、华为云、亚马逊AWS、ThingsBoard、Ignition云平台

随着工业4.0的深入发展和物联网技术的广泛应用&#xff0c;IEC 104&#xff08;IEC 60870-5-104&#xff09;作为电力系统中的重要通信协议&#xff0c;正逐步与各种现代监控、管理和云平台实现深度融合。IEC104转MQTT网关BE113作为这一融合过程中的关键设备&#xff0c;其能够…

人工智能:大语言模型提示注入攻击安全风险分析报告下载

大语言模型提示注入攻击安全风险分析报告下载 今天分享的是人工智能AI研究报告&#xff1a;《大语言模型提示注入攻击安全风险分析报告》。&#xff08;报告出品方&#xff1a;大数据协同安全技术国家工程研究中心安全大脑国家新一代人工智能开放创新平台&#xff09; 研究报告…

LeetCode24 两两交换链表中的节点

前言 题目&#xff1a; 24. 两两交换链表中的节点 文档&#xff1a; 代码随想录——两两交换链表中的节点 编程语言&#xff1a; C 解题状态&#xff1a; 没画图&#xff0c;被绕进去了… 思路 思路还是挺清晰的&#xff0c;就是简单的模拟&#xff0c;但是一定要搞清楚交换的…

路由表与IP数据报的转发

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、相关知识 1、路由类型 路由表中有3类路由&#xff1a;直连路由、静态路由、动态路由 直连路由&#xff1a;一般指去往路由器接口直接连接网络的…

Godot游戏制作 05收集物品

创建新场景&#xff0c;添加Area2D节点&#xff0c;AnimatedSprite2D节点 &#xff0c;CollisionShape2D节点 添加硬币 按F键居中&#xff0c;放大视图。设置动画速度设为10FPS&#xff0c;加载后自动播放&#xff0c;动画循环 碰撞形状设为圆形&#xff0c;修改Area2D节点为Co…

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署LivePortrait :通过缝合和重定向控制实现高效的肖像动画制作

目录 项目论文介绍 论文中实际开展的工作 非扩散性的肖像动画 基于扩散的肖像动画 方法论 基于Ubuntu的部署实践开始 1. 克隆代码并准备环境 2. 下载预训练权重 3. 推理 快速上手 驱动视频自动裁剪 运动模板制作 4. Gradio 界面 5. 推理速度评估 社区资源 政安…

Apollo部署与简易架构梳理

文章目录 apollo 安装apollo的基本架构组件机制component编译与加载 节点通讯数据的传输消息读写的实现消息的写端消息读端 常用术语ComponentChannelTaskNodeReader/WriterService/ClientParameter服务发现CRoutineSchedulerMessageDag文件Launch文件Record文件Mainboard Moni…

机会性加密技术:网络安全的新趋势

在当今数字化时代&#xff0c;网络安全已成为各行各业不可忽视的重要议题。随着网络攻击手段的不断演进&#xff0c;传统的加密方式已难以满足复杂多变的安全需求。机会性加密技术&#xff08;Opportunistic Encryption&#xff0c;简称OE&#xff09;&#xff0c;作为一种新兴…

快速入门Jupyter notebook

快速入门 Jupyter notebook 一、前言&#xff08;一&#xff09;优点&#xff08;二&#xff09;特点&#xff08;三&#xff09;调用运行&#xff08;四&#xff09;新建 二、认识界面快捷键&#xff08;一&#xff09;三种模式&#xff08;1&#xff09;蓝色模式&#xff1a;…