ElasticSearch学习笔记七:ES查询(二)

server/2024/12/3 8:03:59/

一、前言

在前面的文章我们学习了ES的一些基本查询,同时用Java全部实现了一遍,今天我们继续深入学习一下ES的查询。

二、Term级别查询

在 Elasticsearch 中,Term 级别查询用于精确匹配字段值。与全文搜索不同,Term 级别查询不会进行分词处理,而是直接匹配字段的完整值。这使得 Term 级别查询非常适合用于精确匹配、过滤和聚合操作。

1、Term查询

Term是ES中用于精确匹配的关键字,可以理解为Mysql中的等于,例如我现在想搜索城市是“北京”的酒店就可以这么写:

GET /hotel/_search
{"query": {"term": {"city": {"value": "北京"}}}
}
这段DSL翻译成Mysql就是 select * from hotel where `city` = '北京'

需要注意的是,尽量避免使用Term去查询Text类型的数据,因为Text会被分词,这会导致精准匹配变得困难,如果想搜索Text类型的数据可以使用Match(后面也会讲)

2、Terms查询

和Term类型,Terms也适用于精准匹配,但从名字上我们可以看出Terms是复数形式,意味着他可以支持多个条件(当然Term结合bool查询也能实现),例如我们现在想查询城市是青岛或者北京的酒店就可以这么写

GET /hotel/_search
{"query": {"terms": {"city": ["青岛","北京"]}}
}
这段DSL翻译成Mysql就是 select * from hotel where `city` in ('北京','青岛')

terms默认最多支持65,536个值,如果要修改的话可以修改该参数 index.max_terms_count

3、Terms Set

terms_set 是 Elasticsearch 中的一种查询类型,用于执行基于集合的条件查询。与普通的 terms 查询不同,terms_set 查询允许你定义更复杂的条件,例如集合中元素的数量必须满足某些条件。

PUT /programmer
{"mappings": {"properties": {"name":{"type": "keyword"},"skill":{"type": "keyword"},"required_matches":{"type":"Integer"}}}
}我们的程序员索引有两个字段,姓名和技能,同时我们写入数据
POST /programmer/_bulk
{"index":{"_index":"programmer","_id":"1"}}
{"name":"张三","skill":["Java","C++","Python","JavaScript"],"required_matches":2}
{"index":{"_index":"programmer","_id":"2"}}
{"name":"李四","skill":"Python","required_matches":1}
{"index":{"_index":"programmer","_id":"3"}}
{"name":"王五","skill":["C++","Python"],"required_matches":2}

现在我们查询会C++、Python的程序员且至少会其中的几种的,在上述的文档里,张三我们设置的需要匹配(required_matches字段)等于2,李四=1,王五=2,此时我们的DSL如下

GET /programmer/_search
{"query": {"terms_set": {"skill": {"terms": [ "C++", "Python"],"minimum_should_match_field":"required_matches"}}}
}结果如下
#! Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security.
{"took" : 878,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 0.7876643,"hits" : [{"_index" : "programmer","_type" : "_doc","_id" : "1","_score" : 0.7876643,"_source" : {"name" : "张三","skill" : ["Java","C++","Python","JavaScript"],"required_matches" : 2}},{"_index" : "programmer","_type" : "_doc","_id" : "3","_score" : 0.7876643,"_source" : {"name" : "王五","skill" : ["C++","Python"],"required_matches" : 2}},{"_index" : "programmer","_type" : "_doc","_id" : "2","_score" : 0.17426977,"_source" : {"name" : "李四","skill" : "Python","required_matches" : 1}}]}
}

可以看到所有的文档都返回了,我们来分析一下为什么结果是这样的。

(1)首先我们的查询条件是跟据skill字段terms精准匹配

(2)minimum_should_match_field使用的是 required_matches字段

(3)terms的值为C++和Python,张三会 “Java”,“C++”,“Python”,“JavaScript”,同时只需要满足两个就算匹配上,很显然是符合条件的,所以张三返回

(4)李四,虽然李四只会Python但是他设置的是只要满足一个条件就算匹配上,所以李四也匹配上了。

(5)最后王五,也是同样的道理。所以这次返回了张三、李四、王五。

4、exists

exists不是用来查询文档的,而是用来查询索引的,比如我们想看那些索引包含指定的字段,例如我想查看包含“skill”字段的索引就可以用exists

GET /_search
{"query": {"exists": {"field": "skill"}}
}
5、Range

Rang,用于范围匹配,例如我们想查询价格300~500的酒店,DSL可以这么写

GET /hotel/_search
{"query": {"range": {"price": {"gte": 300,"lte": 500}}}
}
这个DSL翻译成SQL 就是 select * from hotel where price >= 300 and price <=500

range可用的参数有

gt(greater than ):大于

gte(greater than or equal):大于等于

lt(less than):小于

lte(less than or equal):小于等于

format:格式化,用于日期类型比较

6、prefix

前缀匹配,有点类似于Mysql中的前缀模糊匹配,需要注意的是prefix 查询默认是不适用于 text 类型字段的。这是因为 text 字段在索引时会被分析器(analyzer)拆分成多个词项(tokens),而 prefix 查询则需要匹配完整的前缀。比如我们想搜索张开头程序员,DSL就可以这么写

GET /programmer/_search
{"query": {"prefix": {"name": {"value": "张"}}}
}
7、IDs

IDs查询,就是根据文档的ID查询,这个没有太多东西可以说

GET /hotel/_search
{"query": {"ids" : {"values" : ["001","002"]}}
}
8、Fuzzy

Fuzzy查询,模糊查询或者说近似匹配,例如电商的里的搜索场景

-  用户输入的查询词可能存在拼写错误,Fuzzy 查询可以帮助返回与拼写错误相似的结果。 
-  例如,用户搜索 "aple" 时,Fuzzy 查询可以返回 "apple" 相关的结果。 这里先举个例子,后面再详细学习
GET /_search
{"query": {"fuzzy": {"user.id": {"value": "ki","fuzziness": "AUTO","max_expansions": 50,"prefix_length": 0,"transpositions": true,"rewrite": "constant_score"}}}
}

三、结束语

今天学习了一下ES中的 Term级别查询,ES中还有其他类型的搜索后面将继续,同时下一篇文章将用Java把上述的DSL全部实现一遍,希望对有所帮助。


http://www.ppmy.cn/server/146961.html

相关文章

Xcode——LLDB Debugger 与断点调试学习

Xcode——LLDB Debugger 与断点调试学习 文章目录 Xcode——LLDB Debugger 与断点调试学习前言介绍打开LLDB命令helpprintexpression 断点调试异常断点——Exception Breakpoint标志断点——Symbolic Breakpointwatchpointset 断点行为condition条件判断 最后参考文章 前言 在…

linux查询进程的启动时间

说到查询进程的启动时间&#xff0c;你的第一反应肯定是ps -p $pid -o lstart&#xff0c;但是ps 命令通常会通过访问 proc 文件系统来收集进程的信息&#xff0c;它本身是一个外部命令&#xff0c;执行时需要进行进程管理、格式化输出等额外的操作&#xff0c;这会消耗更多的 …

Jmeter 接口测试常见场景

csv 中读取账号密码登录 压测登录接口&#xff0c;通常需要循环读取账号密码&#xff0c;使用 jmeter 处理该需求一般会采用 csv 文件设置来读取账号密码&#xff0c;信息文件&#xff08;user_info.txt&#xff09;示例如下&#xff1a; 信息文件中使用英文逗号分割账号、密码…

【LC】35. 搜索插入位置

题目描述&#xff1a; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target …

Flink常见面试题

1、Flink 的四大特征&#xff08;基石&#xff09; 2、Flink 中都有哪些 Source&#xff0c;哪些 Sink&#xff0c;哪些算子&#xff08;方法&#xff09; 预定义Source 基于本地集合的source&#xff08;Collection-based-source&#xff09; 基于文件的source&#xff08;…

【Leetcode 每日一题】LCR 190. 加密运算

LCR 190. 加密运算 计算机安全专家正在开发一款高度安全的加密通信软件&#xff0c;需要在进行数据传输时对数据进行加密和解密操作。假定 dataA 和 dataB 分别为随机抽样的两次通信的数据量&#xff1a; 正数为发送量负数为接受量0 为数据遗失 请不使用四则运算符的情况下实…

分布式资源调度——yarn 概述(资源调度基本架构和高可用的实现)

此文章是学习笔记&#xff0c;图片均来源于B站&#xff1a;哈喽鹏程 yarn详细介绍 1、yarn 简介1.1 yarn的简介1.2 yarn 的基本架构1.3. yarn 的高可用 2、yarn 调度策略、运维、监控2.1 yarn 的调度策略2.1.1 FIFO scheduler(先进先出)2.1.2 容量调度2.1.3 公平调度 2.2 yarn…

计算机网络——数据链路层Mac帧详解

目录 前言 一、以太网 二、Mac帧 三、MTU——最大传输单元 四、Mac帧的传输过程 1.ARP协议 2.RARP协议 前言 在之前&#xff0c;我们学习过网络层的IP协议&#xff0c;了解到IP协议解决了从哪里来&#xff0c;到哪里去的问题&#xff0c;也就是提供了将数据从A到B的能力…