ES-3-高级查询

article/2025/9/20 22:37:48

文章目录

  • 1 深分页Scroll
    • 1.1 分页的查询过程
    • 1.2 Scroll查询的实现
  • 2 delete-by-query
  • 3 ES的复合查询
    • 3.1 bool查询
    • 3.2 boosting查询
  • 4 filter查询
  • 5 高亮查询
  • 6 聚合查询
    • 6.1 去重计数查询cardinality
    • 6.2 范围统计range
    • 6.3 统计聚合查询extended_stats

1 深分页Scroll

1.1 分页的查询过程

ES对from+size是有限制的,from+size两者和不能超过1w

使用from+size在es中查询数据:
1,将用户指定的关键词通过分词器分片
2,用分词后的词语在分词库中检索,得到多个document的id
3,去各个分片中拉取指定的document(耗时较长)
4,将数据按照score进行排序(耗时较长)
5,根据from的值,将查询到的数据舍弃一部分
6,返回结果使用scroll+size在es中查询数据:
1,将用户指定的关键词通过分词器分片
2,用分词后的词语在分词库中检索,得到多个document的id
3,将这些id存放在内存中的一个上下文中
4,根据指定的size从上下文中取id,再去分片中获取document,默认根据id排序,并将这些document的id从上下文中移除
5,需要下一页数据时,从上下文中继续取id

Scroll查询不适合实时查询,因为在内存中建立的id集合会持续使用一段时间后再过期
这段时间es数据更新后,内存中的集合无法感受到

1.2 Scroll查询的实现

DSL:

查询第一页两条数据,根据age倒序排序
POST /index_name/type_name/_search?scroll=1m (这里scroll=1m 即内存中的id集合1min后过期删除)
{"query" : {"match_all" : {}},"size" : 2,"sort" : [{"age" : {"order" : "desc"}}]
}
第一次使用scroll查询后会返回一个scroll_id查询下一页数据,根据scroll_id进行查询
POST /_search/scroll
{"scroll_id" : "xxxxx","scroll" : "1m"
}删除es中scroll上下文数据
DELETE /_search/scroll/scroll_id

Java:

	@Testpublic void queryByScroll() throws IOException {// 创建searchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定scroll信息request.scroll(TimeValue.timeValueMinutes(1L));// 指定查询条件SearchSourceBuilder builder = new SearchSourceBuilder();builder.size(4);builder.sort("age", SortOrder.DESC);builder.query(QueryBuilders.matchAllQuery());request.source(builder);// 执行并返回结果 获取scroll_id和sourceSearchResponse response = client.search(request, RequestOptions.DEFAULT);String scrollId = response.getScrollId();System.out.println("------首页------");for(SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}// 继续分页查询while (true) {// 循环创建searchScrollRequestSearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);scrollRequest.scroll(TimeValue.timeValueMinutes(1L));// 指定scroll_id 执行查询并返回结果SearchResponse scrollResp = client.scroll(scrollRequest, RequestOptions.DEFAULT);// 判断是否查询到数据SearchHit[] hits = scrollResp.getHits().getHits();if(hits != null && hits.length > 0) {System.out.println("------下一页------");for(SearchHit hit : hits) {System.out.println(hit.getSourceAsMap());}} else {System.out.println("------结束------");break;}}// 创建clearScrollRequest 指定scroll_idClearScrollRequest clearScrollRequest = new ClearScrollRequest();clearScrollRequest.addScrollId(scrollId);// 在内存中删除scroll上下文ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);System.out.println("删除scroll: " + clearScrollResponse.isSucceeded());}

2 delete-by-query

delete-by-query即根据查询条件删除文档
使用match,term删除大量内容

DSL:

删除age小于20的document
POST /index_name/type_name/delete_by_query
{"query" : {"range" : {"age" : {"lt" : 20}}}	
}

Java:

	@Testpublic void deleteByQuery() throws IOException {// 创建deleteByQueryRequestDeleteByQueryRequest request = new DeleteByQueryRequest(index);request.types(type);// 指定查询条件request.setQuery(QueryBuilders.rangeQuery("age").lt(18));// 执行删除BulkByScrollResponse response = client.deleteByQuery(request, RequestOptions.DEFAULT);// 输出返回结果System.out.println(response.toString());}

3 ES的复合查询

3.1 bool查询

复合过滤器,可以将多个查询条件,以一定逻辑组合在一起

must: 所有的条件,用must组合在一起,表示and的意思must_not: 所有的条件,用must_not组合在一起,表示not的意思should: 所有的条件,用should组合在一起,表示or的意思

DSL:

查询省份为北京或上海
不是学生
技能中包括"计算机""通信"的人POST /index_name/type_name/_search
{"query" : {"bool" : {"should" : [{"term" : {"province" : {"value" : "北京"}}},{"term" : {"province" : {"value" : "上海"}}}],"must_not" : [{"term" : {"prof" : {"value" : "学生"}}			}],"must" : [{"match" : {"skill" : "计算机"}},{"match" : {"skill" : "通信"}}]}}	
}

Java:

	@Testpublic void boolQuery() throws IOException {// 创建SearchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定查询条件BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();boolQueryBuilder.should(QueryBuilders.termQuery("province", "北京"));boolQueryBuilder.should(QueryBuilders.termQuery("province", "上海"));boolQueryBuilder.mustNot(QueryBuilders.termQuery("prof", "学生"));boolQueryBuilder.must(QueryBuilders.matchQuery("skill", "计算机"));boolQueryBuilder.must(QueryBuilders.matchQuery("skill", "通信"));SearchSourceBuilder builder = new SearchSourceBuilder();builder.query(boolQueryBuilder);request.source(builder);// 执行查询SearchResponse resp = client.search(request, RequestOptions.DEFAULT);// 输出结果for (SearchHit hit : resp.getHits().getHits()) {System.out.println(hit.getSourceAsMap());    }}

3.2 boosting查询

查询时的score的计算方式:
1,搜索的关键字在文档中出现的频次越多,score越高
2,指定的文档越短,score越高
3,搜索时指定的关键字也会被分词,被分词库匹配的内容越多,score越高

boosting查询可以影响查询后的score

positive: 只有匹配positive的查询内容,才会被放在返回结果集中negative: 如果匹配上了positive并且匹配上negative 才能降低文档的scorenegative_boost: 指定系数,小于1,将匹配positive和negative的document的score乘以negative_boot

DSL:

查询有计算机技能的人,能力B的score降低30%
POST /index_name/type_name/_search
{"query" : {"boosting" : {"positive" : {"match" : {"skill" : "计算机"}},"negative" : {"match" : {"power" : "B"} },"negative_boot" : 0.3}}
}

Java:

	@Testpublic void boostingQuery() throws IOException {// 创建SearchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定查询条件SearchSourceBuilder builder = new SearchSourceBuilder();BoostingQueryBuilder boostingQueryBuilder = QueryBuilders.boostingQuery(QueryBuilders.matchQuery("skill", "计算机"),QueryBuilders.matchQuery("power", "B")).negativeBoost(0.3f);builder.query(boostingQueryBuilder);request.source(builder);// 执行查询SearchResponse resp = client.search(request, RequestOptions.DEFAULT);// 输出结果for (SearchHit hit : resp.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

4 filter查询

不关注匹配度score的情况下,使用filter过滤器查询有更高的查询效率

通常使用的query查询,根据查询条件,去计算文档的匹配度得到一个分数,并根据分数进行排序,不会做缓存
filter过滤查询,根据查询条件去查询文档,不计算分数,而且filter查询会对经常被过滤出来的数据进行缓存

DSL:

filter查询不关注score,查到的document的score为0,但效率更高
POST /index_name/type_name/_search
{"query" : {"bool" : {"filter" : [{"term" : {"name" : "北京"}},{"range" : {"age" : {"lt" : 18}}}]}}
}

Java:

	@Testpublic void filter() throws IOException {// 创建SearchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定查询条件SearchSourceBuilder builder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();boolQueryBuilder.filter(QueryBuilders.termQuery("name", "北京"));boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").lt(18));builder.query(boolQueryBuilder);request.source(builder);// 执行查询SearchResponse resp = client.search(request, RequestOptions.DEFAULT);// 输出结果for(SearchHit hit : resp.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

5 高亮查询

高亮展示的数据,是document中的一个field
请添加图片描述

DSL:

POST /index_name/type_name/_search
{"query" : {"match" : {"name" : "北京"}},"highlight" : {"fields" : {  // fields中指定要展示的高亮属性"name" : {}},"pre_tags" : "<font color = 'red'>", // 指定前缀标签"post_tags" : "</font>",  // 指定后缀标签"fragment_size" : 100 // 指定高亮数据最多展示100个字符} 
}

Java:

	@Testpublic void highlight() throws IOException {// 创建SearchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定查询条件SearchSourceBuilder builder = new SearchSourceBuilder();builder.query(QueryBuilders.matchQuery("name", "北京"));HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("name", 10).preTags("<font color = 'red'>").postTags("</font>");builder.highlighter(highlightBuilder);request.source(builder);// 执行查询SearchResponse resp = client.search(request, RequestOptions.DEFAULT);// 输出结果for(SearchHit hit : resp.getHits().getHits()) {System.out.println(hit.getHighlightFields().get("name"));}}

6 聚合查询

es聚合查询语法:
POST /index_name/type_name/_search
{"aggs" : {"agg" : {"agg_type" :{"属性" : "值"}}}
}

6.1 去重计数查询cardinality

查询到结果后,先将返回的文档中按照一个指定的field进行去重,并统计去重后文档个数

DSL:

去重计数查询,索引中有几种城市
POST /index_name/type_name/_search 
{"aggs" : {"agg" : {"cardinality" : {"field" : "city"}}}
}

Java:

	@Testpublic void cardinality() throws IOException {// 创建SearchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定查询条件SearchSourceBuilder builder = new SearchSourceBuilder();builder.aggregation(AggregationBuilders.cardinality("agg").field("city"));request.source(builder);// 执行查询SearchResponse resp = client.search(request, RequestOptions.DEFAULT);// 输出结果Cardinality agg = resp.getAggregations().get("agg");System.out.println(agg.getValue());}

6.2 范围统计range

统计一定范围内出现的文档个数,如针对某个field的值在0~100间文档出现的个数是多少
范围统计不仅针对普通数值(range),还可以针对时间类型(date_range),ip类型(ip_range)

DSL:

查询年龄在[18-60)[70,...的peopel
POST /index_name/type_name/_search 
{"aggs" : {"agg" : {"range" : {"field" : "age","ranges" : [{"from" : 18,"to" : 60},{"from" : 70}]}}}
}

Java:

	@Testpublic void range() throws IOException {// 创建SearchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定查询条件SearchSourceBuilder builder = new SearchSourceBuilder();builder.aggregation(AggregationBuilders.range("agg").field("age").addRange(18, 60).addUnboundedFrom(70));request.source(builder);// 执行查询SearchResponse resp = client.search(request, RequestOptions.DEFAULT);// 输出结果Range agg = resp.getAggregations().get("agg");for (Range.Bucket bucket : agg.getBuckets()) {String key = bucket.getKeyAsString();Object from = bucket.getFrom();Object to = bucket.getTo();long docCount = bucket.getDocCount();System.out.println(key + from + to);}}

6.3 统计聚合查询extended_stats

查询指定field的最大值,最小值,平均值…

DSL:

POST /index_name/type_name/_search 
{"aggs" : {"agg" : {"extended_stats" : {"field" : "age"}}}
}

Java:

	@Testpublic void extendedStats() throws IOException {// 创建SearchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 指定查询条件SearchSourceBuilder builder = new SearchSourceBuilder();builder.aggregation(AggregationBuilders.extendedStats("agg").field("age"));request.source(builder);// 执行查询SearchResponse resp = client.search(request, RequestOptions.DEFAULT);// 输出结果ExtendedStats agg = resp.getAggregations().get("agg");System.out.println(agg.getMax());System.out.println(agg.getMin());System.out.println(agg.getSum());}

http://chatgpt.dhexx.cn/article/6sE4qD7S.shtml

相关文章

Elasticsearch嵌套查询must和mustNot

场景&#xff1a;在bug关联固件的时候将bug的数据放到固件的数据下&#xff0c;可以根据固件数据下是否包含bug数据查询出已关联和未关联的数据。 ES文档结构 目录 1.must查询此bug关联的固件 java代码 2.mustNot查询此bug未关联的固件 java代码 3.劫后余生 4.闲来…

MQ消息

AMQP协议介绍 AMQP&#xff0c;即Advanced Message Queuing Protocol&#xff0c;高级消息队列协议&#xff0c;是应用层协议的一个开放标准&#xff0c;为面向消息的中间件设计。 AMQP的主要特征是面向消息、队列、路由&#xff08;包括点对点和发布/订阅&#xff09;、可靠性…

MQ基础信息mq的简介

MQ 同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但是你却不能…

MFQ

一什么是MFQ&PPDCS&#xff1f;MFQ&PPDCS是由外部教练邰晓梅提出的一套测试分析和测试设计方法。MFQ将被测对象分层&#xff0c;针对不同层次进行测试分析和设计进行&#xff0c;使测试设计人员不会那么容易忘记一些测试的相关点&#xff08;功能交互、质量属性&#x…

MQ的了解

MQ的了解&#xff1a; 如果进行产品选型 Kafka 优点&#xff1a;吞吐量非常大&#xff0c;性能非常好&#xff0c;集群高可用。 缺点&#xff1a;会丢数据&#xff0c;功能比较单一 使用场景&#xff1a;日志分析、大数据采集 RebbitMQ 优点&#xff1a;消息可靠性高&…

多级反馈队列调度算法(MFQ)

多级反馈队列调度算法是目前公认的较好的一种进程调度算法,它能较好的满足各类进程的需要。 MFQ算法首先设置多个就绪队列。队列的优先级递减,且各队列时间片大小也不同。例如我实现的算法里,设置了3个队列,第一队列优先级>第二队列>第三队列,且后一个队列的时间片大…

从MFQ方法到需求分析

前几天看了一篇性能测试相关的文章&#xff1a;性能测试模型初探及应用方法分析&#xff0c;其中提到了MFQ分析方法。专门去查阅了MFQ相关的一些资料&#xff0c;学习了一番。 之后想起了以前看《Google的软件测试之道》这本书时&#xff0c;书中提到的一种测试分析方法&#x…

nRF24l01无线传输

模块简介&#xff1a; 它是一款工作于2.4GHZ~2.5GHZISM频段&#xff0c;带功放通信距离可达上千米&#xff0c;近距离传输速度可达2Mbps&#xff0c;具有6通道且每通道都有自己的缓冲区&#xff0c;可以同时跟不同的NFR进行通信的无线收发模块。 工作模式&#xff1a;接收模式…

C51- NRF24L01 无线串口模块

1.硬件知识 1.1 nRF24L01的引脚功能 &#xff08;IO方向是相对模块而言的&#xff09; CE&#xff1a;Chip Enable&#xff0c;芯片使能&#xff0c;在发送和接收过程中都要将这个引脚拉高。 IRQ: 低电平触发&#xff0c;当状态寄存器中 TX_DS、RX_DR 或 MAX_RT 为高时触发中断…

NRF24L01+模块实现双向通信(带ACK payload)

本文主要关于NRF24L01 2.4GHz无线模块的应用。 目录 说明模块开发的大致步骤使用方式一、单向通信二、双向通信&#xff08;有应答包(ACK payload))寄存器配置 三、星状组网 注意事项 说明 1、NRF24L01和NRF24L01的区别&#xff0c;前者支持Enhanced ShockBurst™,后者不支持…

2.4G模块NRF24L01调试经验

参照野火STM32程序调试NRF24L01成功&#xff0c;颇获喜感 nRF24L01是一款工作在2.4~2.5GHz世界通用ISM频段的单片无线收发器芯片。无线收发器包括&#xff1a;频率发生器、增强型SchockBurstTM模式控制器、功率放大器、警惕振荡器、调制器、解调器。输出功率、频道选择和协议的…

小体积、高速率的nRF24L01芯片通信模块

在选择纯硬件通信模块时&#xff0c; 面对上述问题&#xff0c;AS01提供了很好的解决办法。 AS01系列模块是工作在2.4GHz(ISM频段)的纯硬件模块。此系列基于NORDIC原装nRF24L01P芯片方案开发&#xff0c;提供多种接口形式&#xff0c;具有高空速&#xff08;最高空速可达到2…

Arduino使用NRF24L01模块进行无线通信

Arduino使用NRF24L01模块进行无线通信 前言 ​ 其实CSDN有很多关于这个无线模块的使用&#xff0c;包括Arduino的使用例程&#xff0c;但是实际自己跟着做一遍的时候还是发现了有些小问题&#xff0c;于是记录一下方便以后做其他有意思的小项目。&#xff08;Arduino的库文件…

nRF24L01--2.4G无线通信模块(1)(51单片机和51单片机通信)

作者&#xff1a;李剀 出处&#xff1a;https://www.cnblogs.com/kevin-nancy/ 或者 https://blog.csdn.net/Kevin_8_Lee/article/details/95667604 欢迎转载&#xff0c;但也请保留上面这段声明。谢谢&#xff01;&#xff08;上面两个都是我的博客&#xff0c;只是在不同平台…

STM32控制NRF24L01无线模块进行通信

一.NRF2401无线模块 1.模块介绍 功能介绍 (1)2.4Ghz 全球开放ISM 频段免许可证使 2) 最高工作速率2Mbps&#xff0c;高效GFSK调制&#xff0c;抗干扰能力强&#xff0c;特别适合工业控制场合 (3)126 频道&#xff0c;满足多点通信和跳频通信需要 (4) 内置硬件CRC 检错和点对…

NRF24L012.4G模块

文章目录 datasheet1. 相关案例&#xff1a;2. nRF24L01通信的常识1. 发送模式。1.5 补充spi一点知识1. SPI读写时序2. 工作模式2.1 收发模式Enhanced ShockBurstTM收发模式Enhanced ShockBurstTM发送流程&#xff1a;Enhanced ShockBurstTM接收流程&#xff1a; 3. SPI指令 3.…

STM32驱动NRF24L01无线模块

目录 一、模块简介二、工作模式三、主要命令四、配置寄存器五、状态寄存器六、接收模式七、发送模式八、STM32使用NRF24L01模块 一、模块简介 NRF24L01是NORDIC公司生产的一款无线通信芯片&#xff0c;采用FSK调制&#xff0c;内部集成NORDIC自己的Enhanced Short Burst 协议&…

nRF24L01无线模块笔记

nRF24L01模块 官网链接: https://www.nordicsemi.com/Products/nRF24-series 常见的无线收发模块, 工作在2.4GHz频段, 适合近距离遥控和数据传输. nRF24L01是一个能兼顾距离和数据速率的无线模块, 在空旷环境下&#xff0c;2M速率15米, 1M速率30米, 250K速率能达到50米. 和蓝牙…

NRF24L01+模块:一对一双向通信,成功!

查找了很多资料&#xff0c;好多都是复制粘贴转发&#xff0c;或者安装英文手册直译的&#xff08;比如我自己上篇笔记&#xff0c;&#xff0c;&#xff09;&#xff0c;看完还是一脸懵逼&#xff0c;没几个可行的&#xff0c;推荐几个比较实在的资料&#xff1a;手册我也不是…

NRF24L01 无线通信模块使用方法

原文出处&#xff1a;http://blog.csdn.net/mc_hust/article/details/39473913 昨天登录百度账号&#xff0c;无意间发现漏看了好多朋友的私信&#xff0c;其中不少是找我探讨关于NRF2401模块的。从12年到14年的信件都有&#xff08;平时很少注意系统提示信息。。。&#xff0…