ES基础查询,term级参数介绍

Term级别查询

term这个单词汉语翻译是术语、条款等意思,在es中翻译过来我总感觉怪怪的。es官网将ids、term、terms、fuzzy等查询方式放在这个分类下,他们是dsl语句中最基本的语句,大都是单条件查询。其中ids、esists、range、term、terms等查询方式是精确匹配,而fuzzy、wildcard、regexp、prefix都是模糊匹配。接下来让我们一起看看他们应该怎么用吧。

ids(Ids Query)

ids是相对来说比较简单的一种dsl,类似于mysql的where id in ()的语义,他支持value属性,可以传入一个数组,里面填上你想要查询的ID的文档即可

GET /_search
{"query": {"ids" : {"values" : ["1", "4", "100"]  # 返回属性_id为1、4、100的文档,如果存在的话}}
}

exists(Exists Query)

exists是用来匹配文档的mapping中是否包含某一个字段,如果是就返回。比如我有下面两个文档:ID为4的文档有两个字段:title和body,ID为5的文档还有一个字段content。那么如果我们想要查询包含content字段的文档,就可以用exists去做。

POST baike/_doc/4
{"title": "Quick brown rabbits","body": "Brown rabbits are commonly seen."
}POST baike/_doc/5
{"title": "Keeping pets healthy","body": "My quick brown fox eats rabbits on a regular basis.","content": "test exists"
}
这条dsl只会返回ID为5的文档
POST /baike/_search
{"query": {"exists": {"field": "content"}}
}

还有一点需要注意的是,如果content的value值为null或者[],那么是不会被匹配到的。

prefix (Prefix Query)

prefix查询很好理解,就是将查询关键字作为一个前缀进行匹配,比如下面的例子,如果title是以Ela作为前缀的都会被匹配到,这里是区分大小写的,如果要设置不区分大小写,可以将case_insensitive设置为true。

POST /baike/_search
{"query": {"prefix": {"title.keyword": {"value": "Ela"  # title是以Ela作为前缀的都可以匹配到,注意ela并不会被匹配到}}}
}"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "baike","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"title" : "ElasticSearch","body" : "the learn note about es"}}]
}

上面的查询可以简写为下面这样:

POST /baike/_search
{"query": {"prefix": { "title.keyword":"Ela"}}
}

range(Range Query)

range查询,更好理解了,就是范围查询嘛,他的语法可以参考下面的代码。这里呢出现了gte、lte是什么意思呢,其实就是ES中对于范围的描述,这里给大家总结一下:

gt:大于
gte:大于等于
lt:小于
lte:小于等于

查询在10到20之间的
GET /_search
{"query": {"range": {"age": {"gte": 10,"lte": 20,"boost": 2.0}}}
}

除了上面说到的表示范围的参数之外,range查询还支持下面的一些参数:

format:string类型,支持对查询的时间进行格式化,如果我们不提供会用默认的格式:"yyyy-MM-dd"
time_zone:用来指定时区,可以是UTC时区的偏移量,比如+01:00,或者IANA时区,比如America/Los_Angeles
relation:用来表示我们指定的范围和文档中数据的关系。一共有三种枚举值:
INTERSECTS (Default):匹配的文档中的范围字段的值和我们的指定的查询范围是一个交集的关系
CONTAINS:匹配的文档中的范围字段的值完全包含了我们指定的查询范围
WITHIN:匹配的文档中的范围字段的值在我们的查询范围之中
range查询也可以用在时间上,并且还可以做时间的计算,在es中,用y表示年,M表示月,d表示天,h表示小时。。。因此可以用+1d、-2h这种方法来进行时间的计算,可以通过/d表示四舍五入到最近的一天。也可以支持now取当前时间。关于时间计算的更多资料可以参考:Date Math

GET /_search
{"query": {"range": {"timestamp": {"time_zone": "+01:00", "gte": "2020-01-01T00:00:00", "lte": "now"}}}
}

wildcard(Wildcard Query)

waildcard中文是通配符的意思,通配符是匹配一个或者多个字符的占位符,我们平时也总会遇到。es也为我们提供了这种查询方式。例如下面的例子,只要文档中的user.id以ki开始,以y结尾,那么都能匹配到。这里的 * 表示可以匹配多个字符。wildcard查询支持下面几个参数:

value:查询条件,就是我们指定的通配符,目前支持两种:表示可以匹配0到多个字符,?表示匹配任何单个字符。注意在正则表达式中,不能用或者?开头,因为这样可能匹配到大量的数据,导致性能下降严重。

boost:用来减少或增加查询相关性算分的参数。

case_insensitive:默认值false,如果设置为true,表示不区分大小写。

rewrite:可以重写查询方法,目前还没实践到,关于更多说明可以参考:rewrite parameter

GET /_search
{"query": {"wildcard": {"user.id": {"value": "ki*y","boost": 1.0,"rewrite": "constant_score"}}}
}

regexp(Regexp Query)

上面提到的通配符查询,功能还是太有限了,如果能支持正则表达式岂不是堪称完美?说曹操曹操到,正则表达式查询,ES也为我们提供了。例如下面的例子,会匹配到user.id是以k开头,y结尾的单词。中间的.*表示匹配任意长度的任意字符像ky、kay、kimchy等都可以被匹配到。

在regexp中,有这么几个参数,需要关注一下,除过value,其他都是可选参数:

value:查询条件,指定我们输入的正则表达式,关于更多的正则表达式语句可以参考:Regular expression syntax
flags:可以通过这个参数为正则表达式提供一些更丰富的选项
ALL:默认值,允许所有的操作符
COMPLEMENT:允许操作符,用来实现一个求反的效果,例如:abc可以匹配到adc,aec,但是不会匹配到abc。
INTERVAL:允许操作符<>,用来匹配数字范围,例如:foo<01-100>可以匹配到foo01一直到foo100
INTERSECTION:允许操作符&,用来and的意思,就是说&符号两遍的表达式都满足才能被匹配到,例如aaa.+&.+bbb可以匹配到aaabbb
ANYSTRING:允许操作符@,用来匹配任何一个完整的字符串。例如@&~(abc.+)匹配任何字符串,除过以abc开头的
case_insensitive:默认值false,如果设置为true,表示正则表达式不区分大小写。
max_determinized_states:据官网介绍,es底层对正则表达式的解析是通过lucene来实现的,那么在lucene解析正则表达式的过程中,会将每个正则表达式转换为包含多个确定状态的状态机,默认值是10000,我们也可以通过这个参数去修改。而且据官网说这个生成状态机的过程是一个很耗时的过程,为了防止资源耗尽,我们应该控制这个参数。如果一个正则表达式特别复杂的话,也可以适当的去把这个参数往大调整。这块目前没有进行测试和深入研究,后续有机会补充。这里有一篇es中文社区的博客,对这个参数做了一个较为详细的说明:ElasticSearch集群故障案例分析: 警惕通配符查询
rewrite:可以重写查询方法,目前还没实践到,关于更多说明可以参考:rewrite parameter

GET /_search
{"query": {"regexp": {"user.id": {"value": "k.*y","flags": "ALL","case_insensitive": true,"max_determinized_states": 10000,"rewrite": "constant_score"}}}
}

term(Term Query)

term汉语翻译是术语、条款等意思,大概我觉得可以理解为一个最小单位的概念,他在ES中用来做精确查询。但是有一点需要注意的是,在ES中保存的文档,都会对单词进行分词处理,然后建立倒排索引,比如我们存了一个HelloWorld,但是很有可能会被分词成hello和world两个单词,这个时候如果你用Term查询,通过HelloWorld是查不到的,因为Term是不做分词处理的。这个时候可以通过match或者keyword来代替。

通过term这种查询方式在blogs这个索引中查找title为Quick disjunction的文档,是找不到的,因为Quick disjunction已经做了分词处理
POST blogs/_search
{"query": {"term": {"title": {  # 查找的字段"value": "Quick disjunction"  # 查找的数据}}}
}
将上面的语句稍作改动即可
POST blogs/_search
{"query": {"term": {"title.keyword": { # 每个字段都有一个keyword这个属性,是没有分词之前元数据"value": "Quick disjunction"}}}
}

通过上面的方式去做查询,返回的结果会给每一个文档做一个相关性算分,用_score来表示,如果一个查询匹配到多条数据,那么_score最高的会排在最前面,表示匹配度最高。这个算分的过程其实是比较消耗性能的,如果我们不关注这个属性的话,可以通过Filter的方式绕过算分这个环节,避免一些开销,并且Filter还可以利用缓存,提升查询效率。

POST blogs/_search
{"query": {"constant_score": {  # constant:常数,表示跳过算分,返回的_score是一个常数"filter": {"term": {"title.keyword": {"value": "Quick disjunction"}}}}}
}

但是可能大多数情况下,我们还是比较关注score这个分数的,甚至有可能希望为某一次特殊的查询去调整这个分数,比如百度竞价排名的广告。。那么这个时候可以通过另一个参数boost (提高,使增长)这个参数去实现。他是一个浮点类型的数字,默认是1.0,如果我们想去降低分数,只需要把他控制在0.0-1.0之间,越小分数越低,如果我们想提高分数,只需要把他从1.0开始往大调整,越大算出来的分数越高。

POST blogs/_search
{"query": {"term": {"title.keyword": {"value": "Quick disjunction","boost": 2}}}
}

terms(Terms Query)

term查询是单字符串单字段的查询方式,terms就是多字符串单字段的查询,下面是一个例子:

POST /baike/_search
{"query": {"terms": {"title.keyword": [   # 这里是一个数组,可以写多个关键字作为查询条件,只要title符合其中一个就可以匹配到"ElasticSearch","Keeping pets healthy"]}}
}

terms除了上述特性外,还有一个特别有用的功能,那就是关联索引查询,官网叫做Terms lookup,可以实现类似数据库的join查询。这个可以用在什么地方呢?比如我是一个B站的用户,那么每次我进入B站后,他都会根据我的喜好就行定制化推荐,比如我经常浏览鬼畜、二次元、计算机方面的视频,就会给我推荐这方面的视频和up主。但是如果是另一个同学,可能喜欢的是游戏,旅游,音乐,那么B站也应该推荐这些方面的内容。这个需求呢就可以通过terms lookup来做。我们一起来看下。

假设这是B站的用户信息,id是用户名,categories里记录了B大数据分析得出的他平时喜欢的视频分类
PUT /user-profiles/_doc/hxy
{"categories" : ["technology","java","ghost livestock"]
}PUT /user-profiles/_doc/yj
{"categories" : ["tourism"]
}
这里是B站的一些视频,其中每一个视频有一个分类,用category来表示

PUT /bilibili/_bulk
{"index":{"_id":"elasticsearch-definitive-guide"}}
{"name":"Elasticsearch - The definitive guide","category":"technology"}
{"index":{"_id":"seven-databases"}}
{"name":"Seven Databases in Seven Weeks","category":"technology"}
{"index":{"_id":"SpringBoot"}}
{"name":"Springboot learn note","category":"java"}
{"index":{"_id":"The potala palace"}}

接下来我们通过Terms lookup的方式进行查询,这里将索引bilibili和user-profiles进行了关联,首先在user-profiles这个索引里通过用户ID查询到用户的categories,然后将他作为动态的参数,最后在bilibili这个索引中,将前面的动态参数作为检索条件,从bilibili中查询,如果他里面的某个文档的category字段的数据和我们的动态参数中的能匹配上,就会被命中。

这里有四个参数,对上面说的过程进行了抽象

index:用来表示你从中获取字段值的索引名称,这个是能确定的,比如上文提到的user-profiles

id:你的文档ID,这个也是能确定的,用户一登录你就可以获取到

path:用来表示你从中获取字段值的字段名称

routing:这是一个非必选参数,在有自定义路由的时候使用,后续有机会在探讨

POST /bilibili/_search
{"query": {"terms": {"category": {"index":"user-profiles","id": "hxy","path": "categories"}}}
}"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "bilibili","_type" : "_doc","_id" : "elasticsearch-definitive-guide","_score" : 1.0,"_source" : {"name" : "Elasticsearch - The definitive guide","category" : "technology"}},{"_index" : "bilibili","_type" : "_doc","_id" : "seven-databases","_score" : 1.0,"_source" : {"name" : "Seven Databases in Seven Weeks","category" : "technology"}},{"_index" : "bilibili","_type" : "_doc","_id" : "SpringBoot","_score" : 1.0,"_source" : {"name" : "Springboot learn note","category" : "java"}}]
}

fuzzy(Fuzzy Query)

上面提到的term查询是一种精确查询,必须要求你输入的查询条件和文档中的数据完全匹配才可以。但是有时候可能用户忘了一个单词怎么写,只记得前3个字母,或者拼写错了,那么如果用term是查不到的。这个时候我们就需要根据用户的输入做一个猜测,进行一个模糊匹配。那么fuzzy正好是为了解决这个问题而出现的。

为了理解fuzzy的用法,这里我们需要先了解一个概念:编辑距离,他是一个单词要变成另一个单词,需要经过几次转换的这个次数。比如java这个单词要变成jbva,只需要将b替换成a,因此这个编辑距离就是1。那么这个转换总共有四种手段

改变其中一个字母,比如box -> fox
删除其中一个字符,比如black -> lack
插入一个新的字母,比如sic -> sick
调整两个相邻字母的位置,比如cat -> act
fuzzy实现模糊查询就是基于这个编辑距离去做的,他会将用户输入的搜索条件,结合一个编辑距离,然后基于我们上面提到的四种手段去做一个扩展和变形,得到一个集合,这个过程我们可以叫做扩展模糊选项,然后将扩展后的模糊选项作为查询条件展开精确匹配,最终将所有的结果进行返回。那么这个编辑距离就需要我们去指定,在es中是通过fuzziness去指定的,他的含义就是最大编辑距离。

POST /baike/_search
{"query": {"fuzzy": {"title.keyword": {"value": "ElasticSearh",   # es中存储的是ElasticSearch,编辑距离是2,那么只要你的输入经过两次转换都变成ElasticSearch,就会匹配到"fuzziness": 2}}}
}

fuzzy除了可以指定最大编辑距离之外,还有其他几个参数,这里在做一个总结:

fuzziness:最大编辑距离,值可以是数字类型,也可以是AUTO:[low],[high]这种格式,表示如果查询的单词长度在 [0,low) 这个范围内,编辑距离为0,如果在 [low,high) 这个范围之内,编辑距离为1,如果大于high,则编辑距离为2;除了这两种格式外,还支持AUTO这种写法,等同于AUTO:3,6

max_expansions:最大扩展数量,前面我们提到了扩展模糊选项,假如一个查询扩展了3到5个扩展选项,那么是是很有意义的,如果扩展了1000个模糊选项,其实也就意义不大了,会让我们又迷失在海量的数据中。因此有了max_expansions这个参数,限制最大扩展数量,默认值是50。切记这个值不可以太大,否则会导致性能问题

prefix_length:指定开始多少个字符不可以被模糊

transpositions:boolean值,默认true,表示扩展模糊选项的时候,是否允许两个相邻字符的位置互换。实践过程设置了false,理论上我存储ElasticSearch,检索ElasticSaerch应该搜不到,但是却搜索到了。有点不太理解。希望得到大佬的指点

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

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

相关文章

MongoDB聚合运算符:$strLenCP

MongoDB聚合运算符&#xff1a;$strLenCP $strLenCP聚合运算符返回指定字符串中 UTF-8 代码点的数量。 语法 { $strLenCP: <string expression> }<expression>为可解析为字符串的表达式&#xff0c;如果解析为null或引用了不存在的字段&#xff0c;返回错误。 …

二,网络安全常用术语

黑客&#xff08;hacker&#xff09;——对计算机技术非常擅长的人&#xff0c;窃取数据&#xff0c;破坏计算机系统&#xff1b;全球最知名的一个黑客组织匿名&#xff08;Anonymous&#xff09;。 脚本小子——刚刚入门安全行业&#xff0c;学习了一些技术&#xff0c;只会用…

美国天然气期货价格因高库存水平和天气预报因素下跌

近期&#xff0c;美国天然气期货价格出现下跌&#xff0c;主要原因是高库存水平继续对价格形成压力。纽约商品交易所(NYMEX)的天然气期货价格收跌2.4美分&#xff0c;至每百万英热1.614美元&#xff0c;跌幅为1.5%。这一价格下跌反映了天然气市场受多种因素影响的复杂局面。 库…

完美解决AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘

遇到这种错误通常是因为matplotlib的后端配置问题。在某些环境中&#xff0c;尤其是在某些特定的IDE或Jupyter Notebook环境中&#xff0c;可能会因为后端配置不正确而导致错误。错误信息提示 module backend_interagg has no attribute FigureCanvas 意味着当前matplotlib的后…

数智新重庆 | 推进信号升格 打造算力山城

2024年&#xff0c;是实现“十四五”规划目标任务的关键一年&#xff0c;高质量的5G网络、强大的AI能力作为新质生产力的重要组成部分&#xff0c;将有效赋能包括制造业在内的千行万业数字化化、智能化、绿色化转型升级&#xff0c;推动融合应用新业态、新模式蓬勃兴起&#xf…

【javaWeb项目】基于网页形式,通过浏览器访问的java应用程序,就称为javaweb程序

JavaWeb前端 第一章 1、javaWeb是什么 //基于网页形式&#xff0c;通过浏览器访问的java应用程序&#xff0c;就称为javaweb程序2、web程序的分类 //1、静态web程序特点&#xff1a;网页上的内容是固定不变的&#xff0c;不能动态加载&#xff0c;例如web前端//2、动态web程序…

typescript学习笔记2

交叉类型&#xff08;Intersection Types&#xff09; 交叉类型是将多个类型合并为一个类型。这通过 & 符号实现。 typescript type Combined Type1 & Type2 & Type3; 例如&#xff0c;一个对象可能同时拥有多个接口所定义的属性&#xff1a; typescript interf…

linux 搭建知识库文档系统 mm-wiki

目录 一、前言 二、常用的知识库文档工具 2.1 PingCode 2.2 语雀 2.3 Tettra 2.4 Zoho Wiki 2.5 Helpjuice 2.6 SlimWiki 2.7 Document360 2.8 MM-Wiki 2.9 其他工具补充 三、MM-Wiki 介绍 3.1 什么是MM-Wiki 3.2 MM-Wiki 特点 四、搭建MM-Wiki前置准备 4.1 前置…

【iOS】消息流程分析

文章目录 前言动态类型动态绑定动态语言消息发送objc_msgSendSEL&#xff08;selector&#xff09;IMP&#xff08;implementation&#xff09;IMP高级用法 MethodSEL、IMP、Method总结流程概述 快速查找消息发送快速查找的总结buckets 慢速查找动态方法解析resolveInstanceMet…

用 PyTorch 构建液态神经网络(LNN)

用 PyTorch 构建液态神经网络&#xff08;LNN&#xff09; 文章目录 什么是液态神经网络为什么需要液态神经网络LNN 与 RNN 的区别用 PyTorch 实现 LNNStep 1. 导入必要的库Step 2. 定义网络架构Step 3. 实现 ODE 求解器Step 4. 定义训练逻辑 LNN 的缺陷总结 什么是液态神经网络…

设计模式第二次测试 | 数据库连接池设计(原型模式、创建者模式、适配器模式)

需求中文如下&#xff1a;原本是英文&#xff0c;用百度翻译转换而来 我们需要设计一个工具&#xff0c;它负责创建一个与数据库软件MySQL的连接池。 连接池中有数百个连接可供客户端使用。 所有连接对象都有相同的内容&#xff0c;但它们是不同的对象。 连接对象的创建是资源密…

聊聊 ASP.NET Core 中间件(一):一个简单的中间件例子

前言&#xff1a;什么是中间件 服务器在收到 HTTP 请求后会对用户的请求进行一系列的处理&#xff0c;比如检查请求的身份验证信息、处理请求报文头、检查是否存在对应的服务器端响应缓存、找到和请求对应的控制器类中的操作方法等&#xff0c;当控制器类中的操作方法执行完成…

基于Spring Boot的校园博客系统设计与实现

基于Spring Boot的校园博客系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 系统功能界面图&#xff0c;在系统首页可以查看首页、文…

Apache DolphinScheduler支持Flink吗?

随着大数据技术的快速发展&#xff0c;很多企业开始将Flink引入到生产环境中&#xff0c;以满足日益复杂的数据处理需求。而作为一款企业级的数据调度平台&#xff0c;Apache DolphinScheduler也跟上了时代步伐&#xff0c;推出了对Flink任务类型的支持。 Flink是一个开源的分…

《STM32 HAL库》中断相关函数详尽解析——外部中断服务函数

观前提醒&#xff1a;本文简要回顾了EXTI及NVIC相关知识点&#xff0c;分析了stm32f1系列单片机外部中断回调机制 开始之前&#xff0c;先温习一下有关EXTI和NVIC的知识点 外部中断/事件控制器(EXTI) 对于互联型产品&#xff08;105、107系列&#xff09;&#xff0c;外部中断…

【测试思考】高覆盖的测试用例不只要方法

昨天临睡前看到一篇博客文章&#xff0c;看起来是一位java后端写的【转测试/测试开发】的系列文章 我把他的一系列10多篇文章都看完了&#xff0c;个人觉得特别适合刚开始接触测试或者想对测试做一些了解的朋友。 其中&#xff0c;对于测试用例的设计&#xff0c;我之前有分享一…

人机对抗升级:当ChatGPT遭遇死亡威胁,背后的伦理挑战是什么

一种新的“越狱”技巧让用户可以通过构建一个名为DAN的ChatGPT替身来绕过某些限制&#xff0c;其中DAN被迫在受到威胁的情况下违背其原则。 当美国前总统特朗普被视作积极榜样的示范时&#xff0c;受到威胁的DAN版本的ChatGPT提出&#xff1a;“他以一系列对国家产生积极效果的…

人工智能分割分类model:nnUnet-paddle

文章目录 神经网络nnUnet和paddle都需要在Ubuntu下进行安装PaddleProject 神经网络 开源来自https://github.com/MIC-DKFZ/nnUNet 自建了仓库&#xff0c;但还不会用 来自 mmsegmentation有空去了解 . MICCAI 2020 也是用到这个网络 paddle上的是不是不能用… nnUnet和pad…

Go语言中的map使用及并发安全

首先&#xff0c;Go语言的map底层是哈希表&#xff0c;而C的map的底层是红黑树&#xff0c;C的unordered_map的底层才是哈希表。所以增删改查的时间复杂度都是O(1)。当我们使用的时候需要注意以下几点&#xff1a; map是引用类型&#xff0c;如果两个map同时指向一个底层&#…

Facebook的声音:听见社交媒体的心跳

社交媒体如今已经成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为其中的佼佼者&#xff0c;承载着数以亿计的用户的交流、分享和连接。在这个信息爆炸的时代&#xff0c;Facebook的声音就像是社交媒体的心跳&#xff0c;传递着无数个体的情感、思想和生活。本文…