ElasticSearch分页查询性能及封装实现
Es的分页方式
from+size
最基本的分页方式,类似于SQL中的Limit语法:
//查询年龄在12到32之间的前15条数据
{"query":{"bool":{"must":{"range":{"user_age":{"gte":12,"lte":32}}}}},"sort":{"user_age":{"order":"desc"}}"from":0,"size":15
}
与Limit一样,from+size分页是通过设置from参数来指定返回结果的起始位置,而size参数来指定返回结果的数量。这里的页码在程序中需要额外进行处理一下,因为from是从0开始的,而size代表返回的条数,使用时需要对页码参数进行 :
原理

Es的查询过程如上图,即一个查询请求,在集群环境下是会被协调到各个节点中,最终落到对应索引的分片上,由每个分片进行查询,最终将数据回给主节点进行汇总。而使用from+size的分页,每个分片的处理则是这样的:

- 搜索请求通常跨越多个分片,每个分片必须将其请求的命中内容以及任何先前页面的命中内容加载到内存中。
- 对于翻页较深的页面或大量结果,这些操作会显著增加内存和 CPU 使用率,从而导致性能下降或节点故障。
例如,from=10000,size=10,需要将10010 条数据加载到内存,这通常意味着需要从多个分片中收集数据,然后在协调节点上进行合并和排序,然后经过后台处理后返回了最后 10条我们想要的数据。这个过程随着数据量的增加而变得更加复杂和资源密集,那也就意味着,越往后翻页(也就是深度翻页)需要加载的数据量越大,势必会越耗费 CPU + 内存资源,响应也会越慢。
性能
默认情况下,
from+size的限制是 10000,这意味着from参数加上size参数的值不能超过 10000,这是为了避免大数据量的召回导致性能低下。如果你尝试进行深度分页,超过了这个限制,Elasticsearch 会抛出错误,提示结果窗口太大。为了解决这个问题,可以通过调整
index.max_result_window的值来增加这个限制,但这通常不推荐,因为它会增加内存和 CPU 使用率,可能导致性能下降或节点故障
超出from+size限制报错:
"root_cause": [{"type": "illegal_argument_exception","reason": "Result window is too large, from + size must be less than or equal to: [10000] but was [10001]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."}],"type": "search_phase_execution_exception",
scroll分页
原理

当发起一个带有 scroll 参数的搜索请求时,Elasticsearch 的分片会为这次搜索创建一个上下文,然后各分片基于快照数据进行相应的查询,每轮查询结束后,会记录一个scrollId,将这批结果以及对应的scrollId返回给客户端。
此时客户端根据返回的scrollId再次发起查询,此时Es服务端会根据该scrollId,找到所属的上下文,并基于上次查询的结果的尾段进行继续查询,相比from+size的每次查询都需要重复大数据量的召回,scroll查询有效的避免了召回操作。减少了CPU、IO的消耗。
性能
相比from+size的重复大批量数据召回消耗CPU和IO,Scroll是更友好且适合大数据量的深度查询(不受制于max_result_window),但是Scroll提高性能的代价是牺牲实时性;当开始一个 scroll session 时,Elasticsearch 会创建一个索引的快照(上下文中),这个快照代表了初始化搜索请求时的索引状态。在 scroll session 的生命周期内,即使索引发生了变化(如新增、删除或更新文档),这些变化也不会反映在后续的滚动查询中。
同时,快照、上下文维护的存在必然导致需要更多的内存来支撑。
官方文档强调:不再建议使用scroll API进行深度分页。如果要分页检索超过 Top 10,000+ 结果时,推荐使用:PIT + search_after。
search_after分页
原理
search_after 是 Elasticsearch 5.0 以上版本提供的一种分页查询机制,用于解决深度分页的性能问题。它通过维护一个实时游标来避免传统 from+size 分页方式在处理大量数据时的性能损耗,也不需要像 scroll API 那样创建和维护一个历史快照,从而减少了资源的占用。

search_after进行查询时,必须指定排序字段,它使用上一次查询的最后一个文档的排序值来获取下一页数据。不同于scroll基于快照的查询,search_after是基于实时的数据,不需要维护一个很大的快照。
性能
search_after是一种无状态的分页方式,它不需要维护搜索上下文,因此不会占用额外的资源。每次请求都会根据上一次请求的最后一个文档的排序值来获取下一页数据,这样可以避免大量的内存消耗。search_after提供了更好的实时性,因为它每次请求都会反映索引的最新状态。这意味着在查询过程中如果有数据的更新,这些变化会反映在分页结果中
场景及优缺点汇总

基于RestHighLevelClient的实现
RestHighLevelClient 是 Elasticsearch 的高级 Java 客户端,它提供了一套简单易用的 API 来与 Elasticsearch 服务器进行交互。
RestHighLevelClient位于org.elasticsearch.client包下,常用功能包括:
| 方法名称 | 入参 | 使用样例 | 备注 |
|---|---|---|---|
createIndex | client: RestHighLevelClient 实例, indexName: 索引名称 | createIndex(client, "my_index"); | 创建索引 |
deleteIndex | client: RestHighLevelClient 实例, indexName: 索引名称 | deleteIndex(client, "my_index"); | 删除索引 |
index | request: IndexRequest 对象 | client.index(request, RequestOptions.DEFAULT); | 插入数据 |
get | request: GetRequest 对象 | client.get(request, RequestOptions.DEFAULT); | 根据ID获取数据 |
update | request: UpdateRequest 对象 | client.update(request, RequestOptions.DEFAULT); | 更新数据 |
delete | request: DeleteRequest 对象 | client.delete(request, RequestOptions.DEFAULT); | 根据ID删除数据 |
search | request: SearchRequest 对象 | client.search(request, RequestOptions.DEFAULT); | 搜索数据 |
scroll | request: SearchScrollRequest 对象 | client.scroll(request, RequestOptions.DEFAULT); | 滚动搜索 |
clearScroll | request: ClearScrollRequest 对象 | client.clearScroll(request, RequestOptions.DEFAULT); | 清除滚动ID |
bulk | request: BulkRequest 对象 | client.bulk(request, RequestOptions.DEFAULT); | 批量操作 |
count | request: CountRequest 对象 | client.count(request, RequestOptions.DEFAULT); | 计数查询 |
exists | request: GetRequest 对象 | client.exists(request, RequestOptions.DEFAULT); | 检查文档是否存在 |
updateByQuery | request: UpdateByQueryRequest 对象 | client.updateByQuery(request, RequestOptions.DEFAULT); | 根据查询更新数据 |
deleteByQuery | request: DeleteByQueryRequest 对象 | client.deleteByQuery(request, RequestOptions.DEFAULT); | 根据查询删除数据 |
其中 BulkRequest 、GetRequest 等参数,均为ActionRequest的子类,具体使用方式可以参考下文。
其中DSL语法可配合org.elasticsearch.search.builder包中的Builder来进行构建,eg:
public void test(){SearchSourceBuilder searchBody = new SearchSourceBuilder().from(0).size(10).query(QueryBuilders.boolQuery().filter(QueryBuilders.termQuery("user_name","张三")).must(QueryBuilders.termQuery("age",12))).sort("id", SortOrder.DESC).fetchSource(Arrays.asList("id","name","age").toArray(new String[0]),new String[0]).aggregation(AggregationBuilders.terms("Test").field("className").size(15));}
form+size分页
定义es数据实体类 DocBaseEntity<T>类:
@Data
public class DocBaseEntity<T> implements Serializable {private String _index;private String _type;private String _id;private T datas;public DocBaseEntity(SearchHit data) {this._index = data.getIndex();this._type = data.getType();this._id = data.getId();}public DocBaseEntity(JSONObject jsonHits){this._index = jsonHits.getStr("_index");this._type = jsonHits.getStr("_type");this._id = jsonHits.getStr("_id");}public T getDatas(){return datas;}}
查询返回实体类SearchResult<T>
@Data
public class SearchResult<T> implements Serializable {private int total;private List<DocBaseEntity<T>> source = new ArrayList<>();private JSONObject aggregations;public void addData(DocBaseEntity<T> obj){source.add(obj);}public List<T> getDatas(){return source.stream().map(DocBaseEntity::getDatas).collect(Collectors.toList());}public void addDatas(List<DocBaseEntity<T>> objs){source.addAll(objs);}public void setTotal(Object total){this.total = Integer.parseInt(String.valueOf(total));}public JSONObject toJSONObject(){return JSONUtil.parseObj(this,true);}}
定义查询接口ElasticSearchActuator
public interface ElasticSearchActuator {/*** from+size 分页查询* @param indexName 索引名称* @param searchSourceBuilder 查询条件* @param pageNo 页码* @param pageSize 每页数量* @param resultObj 具体目标对象* @return SearchResult*/<T> SearchResult<T> fromSizeSearchElasticSearchDatas(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,Class<T> resultObj);}
from+size分页实现
@Component
@Slf4j
public class ElasticSearchActuatorImpl implements ElasticSearchActuator {//restHighLevelClient客户端Configure相关单独编写,这里不再复述@Autowirdprivate RestHighLevelClient restHighLevelClient;private final static Integer MAX_RESULT_WINDOW = 10000; @Overridepublic <T> SearchResult<T> fromSizeSearchElasticSearchDatas(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,Class<T> resultObj){SearchResult<T> resultMap = new SearchResult<T>();//提前规避超出长度的情况if( from+size >= MAX_RESULT_WINDOW){log.error("XXXXXXX")//其他操作return null;}//分页参数处理int from = (pageNo - 1) * pageSize;searchSourceBuilder.from(from).size(pageSize);SearchRequest searchRequest = new SearchRequest(indexName);searchRequest.source(SearchSourceBuilder );SearchResponse response = executSearch(searchRequest);if(null != response){return createSearchResult(searchResp,resultObj);}return resultMap;}/*** 执行查询*//*** 执行查询*/private SearchResponse executSearch(SearchRequest searchRequest) {SearchResponse searchResponse = null;try{searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);}catch(Exception e){//异常处理}return searchResponse;}/*** 构建目标结果* @param response 返回参数* @param resultObj 类对象* @param <T>* @return*/private <T> SearchResult<T> createSearchResult(SearchResponse response,Class<T> resultObj){SearchResult<T> resultMap = new SearchResult<>();SearchHit[] datas = response.getHits().getHits();for(SearchHit data:datas){DocBaseEntity<T> temp = new DocBaseEntity<>(data);temp.setDatas(JSONUtil.toBean(JSONUtil.parseObj(data.getSourceAsMap()),resultObj));resultMap.addData(temp);}resultMap.setTotal(response.getHits().getTotalHits().value);return resultMap;}}
scroll分页
对SearchResult<T>补充scrollId值:
@Data
public class SearchResult<T> implements Serializable {private int total;//scrollIdprivate String scrollId;private List<DocBaseEntity<T>> source = new ArrayList<>();private JSONObject aggregations;public void addData(DocBaseEntity<T> obj){source.add(obj);}public List<T> getDatas(){return source.stream().map(DocBaseEntity::getDatas).collect(Collectors.toList());}public void addDatas(List<DocBaseEntity<T>> objs){source.addAll(objs);}public void setTotal(Object total){this.total = Integer.parseInt(String.valueOf(total));}public JSONObject toJSONObject(){return JSONUtil.parseObj(this,true);}}
继续定义查询接口ElasticSearchActuator
public interface ElasticSearchActuator {/*** from+size 分页查询* @param indexName 索引名称* @param searchSourceBuilder 查询条件* @param pageNo 页码* @param pageSize 每页数量* @param resultObj 具体目标对象* @return SearchResult*/<T> SearchResult<T> fromSizeSearchElasticSearchDatas(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,Class<T> resultObj);/*** 滚动分页查询* @param indexName 索引* @param searchSourceBuilder 查询体* @param pageNo 页码* @param pageSize 每页条数* @param scrollId 滚动ID* @param resultObj 目标对象* @return SearchResult* @param <T> T*/<T> SearchResult<T> scrollSearchElasticSearchDatas(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,String scrollId,Class<T> resultObj);}
实现类:
@Component
@Slf4j
public class ElasticSearchActuatorImpl implements ElasticSearchActuator {//restHighLevelClient客户端Configure相关单独编写,这里不再复述@Autowirdprivate RestHighLevelClient restHighLevelClient;private final static Integer MAX_RESULT_WINDOW = 10000; @Overridepublic <T> SearchResult<T> fromSizeSearchElasticSearchDatas(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,Class<T> resultObj){//……省略from+size查询}@Overridepublic <T> SearchResult<T> scrollSearchElasticSearchDatas(String indexName, SearchSourceBuilder searchSourceBuilder, int pageNo, int pageSize, String scrollId, Class<T> resultObj) throws IOException {SearchRequest searchRequest = new SearchRequest(indexName);searchSourceBuilder.size(pageSize);//设定scroll失效时长Scroll scroll = new Scroll(TimeValue.timeValueMinutes(3));searchRequest.scroll(scroll);SearchResponse searchResponse = null;if(StringUtils.isEmpty(scrollId)){searchResponse = executSearch(searchRequest);String tempscrollId = searchResponse.getScrollId();SearchScrollRequest searchScrollRequest = new SearchScrollRequest(tempscrollId);searchScrollRequest.scroll(scroll);for (int i = 0; i < (pageNo -1); i++) {searchResponse = scrollSearch(searchScrollRequest);}scrollId = tempscrollId;}else {SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);searchResponse = scrollSearch(searchScrollRequest);}//构建结果SearchResult<T> result = createSearchResult(searchResponse,resultObj);result.setSrcollId(scrollId);clearScrollSession(scrollId);return result;}/*** 滚动查询执行* @param searchScrollRequest* @return*/private SearchResponse scrollSearch(SearchScrollRequest searchScrollRequest){SearchResponse searchResponse = null;try{searchResponse = restHighLevelClient.scroll(searchScrollRequest,RequestOptions.DEFAULT);}catch(Exception e){//异常处理}return searchResponse;}/*** 关闭scroll* @param scrollId* @throws IOException*/private void clearScrollSession(String scrollId) throws IOException {if (scrollId != null) {ClearScrollRequest clearScrollRequest = new ClearScrollRequest();clearScrollRequest.addScrollId(scrollId);ClearScrollResponse clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);clearScrollResponse.isSucceeded();}}}
注意:
使用scroll查询,如果设置的scroll超时,scroll ID会在指定的超时时间内保持活跃,这个超时时间可以通过scroll参数设置。一旦超出这个时间限制,scroll ID将失效,但是不会自动清理。为了避免资源泄露,建议在scroll使用完毕后,显式地清理scroll上下文。
这里最好建立一层缓存记录,即每次客户发来请求后,记录当次查询的scrollId序列,然后定时的释放掉缓存中不用的序列。

search_after分页
对SearchResult<T>补充sortId值:
@Data
public class SearchResult<T> implements Serializable {private int total;//scrollIdprivate String scrollId;//sortIdprivate List<Object> sortId;private List<DocBaseEntity<T>> source = new ArrayList<>();private JSONObject aggregations;public void addData(DocBaseEntity<T> obj){source.add(obj);}public List<T> getDatas(){return source.stream().map(DocBaseEntity::getDatas).collect(Collectors.toList());}public void addDatas(List<DocBaseEntity<T>> objs){source.addAll(objs);}public void setTotal(Object total){this.total = Integer.parseInt(String.valueOf(total));}public JSONObject toJSONObject(){return JSONUtil.parseObj(this,true);}}
继续定义查询接口ElasticSearchActuator
public interface ElasticSearchActuator {/*** from+size 分页查询* @param indexName 索引名称* @param searchSourceBuilder 查询条件* @param pageNo 页码* @param pageSize 每页数量* @param resultObj 具体目标对象* @return SearchResult*/<T> SearchResult<T> fromSizeSearchElasticSearchDatas(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,Class<T> resultObj);/*** 滚动分页查询* @param indexName 索引* @param searchSourceBuilder 查询体* @param pageNo 页码* @param pageSize 每页条数* @param scrollId 滚动ID* @param resultObj 目标对象* @return SearchResult* @param <T> T*/<T> SearchResult<T> scrollSearchElasticSearchDatas(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,String scrollId,Class<T> resultObj);/*** aftersearch分页查询* @param indexName 索引* @param searchSourceBuilder 查询体dsl* @param pageNo 页码* @param pageSize 每页条数* @param sortId 排序游标* @param resultObj 目标对象* @return SearchResult* @param <T> T*/<T> SearchResult<T> afterSearchElasticSearchData(String indexName,SearchSourceBuilder searchSourceBuilder,int pageNo,int pageSize,List<Object> sortId,Class<T> resultObj);}
实现类:
@Component
@Slf4j
public class ElasticSearchActuatorImpl implements ElasticSearchActuator {//……其他逻辑@Overridepublic <T> SearchResult<T> afterSearchElasticSearchData(String indexName, SearchSourceBuilder searchSourceBuilder, int pageNo, int pageSize, List<Object> sortId, Class<T> resultObj) {SearchRequest searchRequest = new SearchRequest(indexName);searchSourceBuilder.size(pageSize);if(!CollectionUtils.isEmpty(sortId)){searchSourceBuilder.searchAfter(sortId.toArray());}else {if(pageNo > 1){//如果不携带上次排序标识,且非首页,递归查询SearchResult<T> previousPage = afterSearchElasticSearchData(indexName,searchSourceBuilder,pageNo-1,pageSize,null,resultObj);searchSourceBuilder.searchAfter(previousPage.getSortId().toArray());}searchRequest.source(searchSourceBuilder);}try{SearchResponse response = executSearch(searchRequest);SearchResult<T> rest = createSearchResult(response,resultObj);SearchHit[] hits = response.getHits().getHits();if(hits.length > 0){rest.setSortId(Arrays.asList(hits[hits.length-1].getSortValues()));}return rest;}catch (Exception e){//异常处理log.error("XXXXXX");}return null;}}相关文章:
ElasticSearch分页查询性能及封装实现
Es的分页方式 fromsize 最基本的分页方式,类似于SQL中的Limit语法: //查询年龄在12到32之间的前15条数据 {"query":{"bool":{"must":{"range":{"user_age":{"gte":12,"lte":3…...
Python精选200Tips:176-180
针对图像的经典卷积网络结构进化史及可视化 P176--LeNet-5【1988】模型结构说明模型结构代码模型结构可视化 P177--AlexNet【2012】模型结构及创新性说明模型结构代码模型结构可视化 P178--VGGNet【2014】VGG19模型结构及创新性说明VGG19模型结构代码VGG19模型结构可视化 P179-…...
【Kotlin 集合概述】可变参数vararg、中缀函数infix以及解构声明(二十)
导读大纲 1.1 使用集合: vararg、infix 调用和解构声明1.1.1 扩展 Java 集合 API1.1.2 vararg: 接受任意数量参数的函数1.1.3 处理pairs: Infix 调用和解构声明 1.1 使用集合: vararg、infix 调用和解构声明 本节将介绍 Kotlin 标准库中用于处理集合的一些函数 同时,还介绍一些…...
unity安装报错问题记录
unity安装报错问题记录 今天下载了unity,一路安装下来,遇到了两个问题: Microsoft Visual Studio Community 2022 Install failed: Validation Failed 查询资料提到本机已安装,实际本机未安装。 解决了半天,大致有…...
秋招|面试|群面|求职
秋招|面试|群面|求职 自我介绍30s-1min,首先是清楚的介绍自己的名字/专业等个人信息,面试岗位,也可以介绍一下对于岗位的理解。然后介绍一下过往经历中最亮眼的几点,主要是为了突出和岗位的适配程度。群面,我觉得最重…...
【Kubernetes】日志平台EFK+Logstash+Kafka【理论】
一,日志处理方案 方案一,【EFK】:Elasticsearch Fluentd(或Filebeat) Kibana Elasticsearch(简称:ES):实时,分布式存储,可扩展,日…...
基于SpringBoot+Vue+MySQL的教学资料管理系统
系统展示 管理员后台界面 教师后台界面 系统背景 在当今信息化高速发展的时代,教育机构面临着日益增长的教学资料管理需求。为了提升教学管理的效率,优化资源的配置与利用,开发一套高效、便捷的教学资料管理系统显得尤为重要。基于SpringBoot…...
动态规划day45:编辑距离|115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离(动规终极好题)
动态规划day45:编辑距离|115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离(动规终极好题) 115. 不同的子序列583. 两个字符串的删除操作72. 编辑距离(动规终极好题) 115. 不同的子序列 给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中…...
剑指 offer 刷题集
目录 数组 1. LCR 121. 寻找目标值 - 二维数组 2. LCR 120. 寻找文件副本 3. LCR 128. 库存管理 I 4. LCR 131. 砍竹子 I 5. LCR 132. 砍竹子 II 6. LCR 135. 报数 7. LCR 139. 训练计划 I 8. LCR 158. 库存管理 II 9. LCR 159. 库存管理 III 10. LCR 160. 数据流中…...
C++在线开发环境搭建(WEBIDE)
C在线开发环境搭建 一、环境说明1.1 系统基础环境说明1.1 docker-ce社区版安装 二、codeserver构建2.1 构建codeserver环境的docker容器2.2 构建docker镜像2.3 运行docker2.4 运行展示 三、构建codeserver中的c开发环境3.1 插件下载3.2 插件安装 四、其他知识4.2 code-server配…...
重磅首发!大语言模型LLM学习路线图来了!
ChatGPT的出现在全球掀起了AI大模型的浪潮,2023年可以被称为AI元年,AI大模型以一种野蛮的方式,闯入你我的生活之中。 从问答对话到辅助编程,从图画解析到自主创作,AI所展现出来的能力,超出了多数人的预料&…...
neo4j关系的创建删除 图的删除
关系的创建和删除 关系创建 CREATE (:Person {name:"jack"})-[:LOVE]->(:Person {name:"Rose"})已有这个关系时,merge不起效果 MERGE (:Person {name:"Jack" })-[:LOVE]->(:Person {name:"Rose"})关系兼顾节点和关…...
【WRF运行第三期】服务器上运行WRF模型(官网案例-Hurricane Matthew)
【WRF运行第三期】运行WRF模型(官网案例-Hurricane Matthew) 官网案例-Hurricane Matthew介绍0 创建DATA文件夹1 WPS预处理1.1 解压GRIB数据(ungrib.exe)1.1.1 解压GRIB数据---GFS(Matthew案例研究数据)1.1…...
基于springboot的书店图书销售管理系统的设计与实现 (含源码+sql+视频导入教程)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于springboot的书店图书销售管理系统拥有三个角色 管理员:用户管理、角色管理、权限管理、店铺管理等商家:图书管理、上架图书、访问量统计、销售总额统计、订单…...
Spring MVC 基本配置步骤 总结
1.简介 本文记录Spring MVC基本项目拉起配置步骤。 2.步骤 在pom.xml中导入依赖: <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.6</version><scope>…...
HCIP--以太网交换安全(一)
以太网交换安全概述:以太网交换安全是一系列技术和策略的集合,旨在保护以太网交换机免受各种网络攻击和威胁。 端口隔离 一、端口隔离概述: 作用:可以实现同一个VLAN内端口的隔离 优势: 端口隔离功能为用户提供了更…...
PyQt5中关于QLineEdit的空输入报错的简单处理
PyQt5中关于QLineEdit的空输入报错的简单处理 前言分析原因解决办法总结 前言 在PyQt5的界面中对于数据的输入,最常用的就是QLineEdit控件,该控件作为基本的数据输入控件已经能满足我们的简单使用。在使用过程,出现闪退情况,发现…...
【前端】ES12:ES12新特性
文章目录 1 逻辑赋值操作符2 数字分隔符3 replaceAll4 Promise.any5 WeakRef6 FinalizationRegistry 1 逻辑赋值操作符 逻辑赋值操作符 ??、&&、 ||。 let a true let b false //a && b //false a || b ; //true console.log(a)let obj {name:"ker…...
语音识别(非实时)
1.环境 python :3.10.14 2.完整代码 import whisper #whisper import wave # 使用wave库可读、写wav类型的音频文件 import pyaudio # 使用pyaudio库可以进行录音,播放,生成wav文件 def record(time): # 录音程序# 定义数据流块CHUNK …...
【计算机网络】--URL统一资源定位符
一个网站地址实例 scheme://host.domain:port/path/filename scheme——定义因特网服务的类型,常见的类型是http host——定义域主机(http的默认主机是www) domain———定义因特网的域名,例如,jinyun.fun …...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
