Elasticsearch(十三)搜索---搜索匹配功能④--Constant Score查询、Function Score查询

一、前言

之前我们学习了布尔查询,知道了filter查询只在乎查询条件和文档的匹配程度,但不会根据匹配程度对文档进行打分,而对于must、should这两个布尔查询会对文档进行打分,那如果我想在查询的时候同时不去在乎文档的打分(对搜索结果的排序),只想过滤文本字段是否包含这个词,除了filter查询,我们还会介绍Constant Score查询。相反,如果想干预这个分数,我们会使用Function Score查询,这些都会在后面介绍到。

二、Constant Score查询

如果不想让检索词频率TF(Term Frequency)对搜索结果排序有影响,只想过滤某个文本字段是否包含某个词,可以使用Constant Score将查询语句包装起来。
假设需要查询city字段是否包含关键词“上海”的酒店,则请求的DSL如下:

POST /hotel/_search
{
  "query": {
    "constant_score": {    //满足条件即打分为1(默认值是1)
      "filter": {
        "term": {   //term查询city中是上海的城市
           "city": "上海"
        }
      }
    }
  }
}

查询结果如下:

{
  ...
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "hotel",
        "_type" : "_doc",
        "_id" : "004",
        "_score" : 1.0,
        "_source" : {
          "title" : "京盛集团酒店",
          "city" : "上海",
          "price" : "800.00",
          "create_time" : "2021-05-29 21:35:00",
          "amenities" : "浴池(假日需预订),室内游泳池,普通停车场/充电停车场",
          "full_room" : true,
          "location" : {
            "lat" : 36.940243,
            "lon" : 120.394
          },
          "praise" : 100
        }
      },
      {
        "_index" : "hotel",
        "_type" : "_doc",
        "_id" : "006",
        "_score" : 1.0,
        "_source" : {
          "title" : "京盛集团精选酒店",
          "city" : "上海",
          "price" : "500.00",
          "create_time" : "2022-01-29 22:50:00",
          "full_room" : true,
          "location" : {
            "lat" : 40.918229,
            "lon" : 118.422011
          },
          "praise" : 20
        }
      }
    ]
  }
}

通过结果可以看到,使用Constant Score搜索时,命中的酒店文档对应的city字段都包含“上海”一词。但是不论该词在文档中出现多少次,这些文档的得分都是一样的1.0.
PS:很多人可能会把constant_score查询中的filter和布尔查询的filter搞混,constant_score中的filter可以把它想象成普通的query,它后面接的就是各种各样的查询子句。如term,terms,exists,bool等等。
比如我想同时使用must查询创建时间大于等于2022-01-29 22:50:00的hotel且不在乎打分,那么可以使用下面的DSL:

POST /hotel/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "must": [
        {
          "range": {
            "create_time": {
              "gte": "2022-01-29 22:50:00"
            }
          }
        }
      ]
        }
      }
    }
  }
}

在Constant Score搜索中,参数boost可以控制命中文档的得分,默认值都是1.0,以下为更改boost参数为2.0的例子:

POST /hotel/_search
{
  "query": {
    "constant_score": {
      "boost":2.0,
      "filter": {
        "term": {
           "city": "上海"
        }
      }
    }
  }
}

查询结果如下:

{
  ...
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 2.0,
    "hits" : [
      {
        "_index" : "hotel",
        "_type" : "_doc",
        "_id" : "004",
        "_score" : 2.0,
        "_source" : {
          "title" : "京盛集团酒店",
          "city" : "上海",
          "price" : "800.00",
          "create_time" : "2021-05-29 21:35:00",
          "amenities" : "浴池(假日需预订),室内游泳池,普通停车场/充电停车场",
          "full_room" : true,
          "location" : {
            "lat" : 36.940243,
            "lon" : 120.394
          },
          "praise" : 100
        }
      },
      {
        "_index" : "hotel",
        "_type" : "_doc",
        "_id" : "006",
        "_score" : 2.0,
        "_source" : {
          "title" : "京盛集团精选酒店",
          "city" : "上海",
          "price" : "500.00",
          "create_time" : "2022-01-29 22:50:00",
          "full_room" : true,
          "location" : {
            "lat" : 40.918229,
            "lon" : 118.422011
          },
          "praise" : 20
        }
      }
    ]
  }
}

根据搜索结果可以看到,设定Boost值为2.0后,所有的命中的文档得分都为2.0。
然后对于Constant Score的效率问题,我们拿它和上一节讲到的filter查询做一个对比:

  1. Constant Score查询实际上就是一个没有分值函数的查询,它会将所有匹配文档的分值设置为一个常量。这种查询不需要计算每个匹配文档的相关度,所以效率会比普通查询高
  2. 但是Constant Score查询还需要执行查询本身,比如匹配查询条件、过滤文档等步骤。而filter查询仅仅过滤文档,不计算分值,所以整体效率比Constant Score查询更高。
  3. Constant Score查询不会像filter查询那样缓存过滤结果。因为Constant Score查询还需要计算每个匹配文档的分值,而这一步不受过滤结果缓存的影响。
  4. 所以总的来说,在效率方面: filter查询 > Constant Score查询 > 普通查询

在java客户端上构建Constant Score搜索时,可以使用ConstantScoreQueryBuilder类的实例进行构建,它接收一个QueryBuilder参数,即可以接收termQueryBuilder,termsQueryBuilder,boolQueryBuilder等等,和之前的DSL是一样的,那么比如我们查询一个城市是上海或者北京的酒店,代码如下:
Service层,getQueryResult()可以看往期的博客,有具体的方法实现:

	public List<Hotel> constantScore(HotelDocRequest hotelDocRequest) throws IOException {
		//新建搜索请求
		String indexName = getNotNullIndexName(hotelDocRequest);
		SearchRequest searchRequest = new SearchRequest(indexName);
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		TermQueryBuilder termQueryBuilder1 = QueryBuilders.termQuery("city", "北京");
		TermQueryBuilder termQueryBuilder2 = QueryBuilders.termQuery("city", "上海");
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
		boolQueryBuilder.should(termQueryBuilder1).should(termQueryBuilder2);
		//构建ConstantScoreBuilder
		ConstantScoreQueryBuilder constantScoreQueryBuilder = new ConstantScoreQueryBuilder(boolQueryBuilder);
		//设置固定分数2.0
		constantScoreQueryBuilder.boost(2.0f);
		searchSourceBuilder.query(constantScoreQueryBuilder);
		searchRequest.source(searchSourceBuilder);
		return getQueryResult(searchRequest);
	}

Controller层:

	@PostMapping("/query/constant_score")
	public FoundationResponse<List<Hotel>> constantScoreQuery(@RequestBody HotelDocRequest hotelDocRequest) {
		try {
			List<Hotel> hotelList = esQueryService.constantScore(hotelDocRequest);
			if (CollUtil.isNotEmpty(hotelList)) {
				return FoundationResponse.success(hotelList);
			} else {
				return FoundationResponse.error(100,"no data");
			}
		} catch (IOException e) {
			log.warn("搜索发生异常,原因为:{}", e.getMessage());
			return FoundationResponse.error(100, e.getMessage());
		} catch (Exception e) {
			log.error("服务发生异常,原因为:{}", e.getMessage());
			return FoundationResponse.error(100, e.getMessage());
		}
	}

Postman实现:
在这里插入图片描述

三、Function Score查询

当你使用ES进行搜索时,命中的文档默认按照相关度进行排序,有些场景下用户需要干预该“相关度”,此时就可以使用Function Score查询。使用时,用户必须定义一个查询以及一个或多个函数,这些函数为每一个文档计算一个新分数
它允许每个主查询query匹配的文档应用加强函数,以达到改变原始查询评分_score的目的

3.1、function_score 查询模板

function_score 查询模板可以分为两类,分别为单个加强函数的查询和多个加强函数的查询。
单个加强函数的查询模板

{
  "query": {
    "function_score": {
      "query": {.....}, //  主查询,查询完后会有一个 _score 评分
      "field_value_factor": {...}, //  在 _score 的基础上进行强化评分
      "boost_mode": "multiply", //  指定用哪种方式结合 _score 和 强化 score
      "max_boost": 1.5 //  限制强化 score 的最高分,但是不会限制 _score
    }
  }
}

多个加强函数的查询模板

{
  "query": {
    "function_score": {
      "query": {.....},
      "functions": [   //  可以有多个加强函数(或是 filter+加强函数),每一个加强函数会产生一个加强 score
        { "field_value_factor": ... },
        { "gauss": ... },
        { "filter": {...}, "weight": ... }
      ],
      "score_mode": "sum", //  决定加强 score 们如何整合
      "boost_mode": "multiply" //  决定最后的 functions 中 score 和 query score 的结合方式
    }
  }
}

3.2、function_score 参数

强化 _score 计算的函数
function_score 提供了几种内置加强 _score 计算的函数功能:

  • weight:设置一个简单而不被规范化的权重提升值。

weight 加强函数和 boost 参数比较类似,可以用于任何查询,不过有一点差别是 weight 不会被 Lucene 规范化(normalize)成难以理解的浮点数,而是直接被应用。
例如,当 weight 为 2 时,最终得分为 new_score = 2 * _score

POST /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      },
     "weight":2
    }
  }
}

输出后可以对比一下不加weight的默认分数,基本分数都翻了2倍

  • field_value_factor:指定文档中某个字段的值结合 _score 改变分数

属性如下:
field指定字段名
factor对字段值进行预处理,乘以(或者加,取决于boost_mode)指定的数值(默认为1)
modifier:将字段值进行加工,有以下的几个选项:

  1. none:不处理
  2. log:计算对数
  3. log1p:先将字段值+1,再计算对数
  4. log2p:先将字段值+2,再计算对数
  5. ln:计算自然对数
  6. ln1p:先将字段值+1,再计算自然对数
  7. ln2p:先将字段值+2,再计算自然对数
  8. square:计算平方
  9. sqrt:计算平方根
  10. reciprocal:计算倒数
{
  "query": {
    "function_score": {
      "query": {.....},
      "field_value_factor": {
        "field": "price",
        "modifier": "none",
        "factor": 1.2
      },
      "boost_mode": "multiply", 
      "max_boost": 1.5
    }
  }
}

调整后的 function 分数公式为,factor * doc['price'].value;如果boos_mode设定为sum,那么分数公式为factor + doc['price'].value

例如我们让最终的分数以price字段进行增强,在原分数基础上*1.2

POST /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      },
      "field_value_factor": {
        "field":"price",
        "factor": 1.2
      },
      "boost_mode": "multiply"
    }
  }
}

再例如我想对字段值先乘1.2再+1再取对数,那么DSL如下:

POST /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      },
      "field_value_factor": {
        "field":"price",
        "modifier": "ln1p",
        "missing":1.0,
        "factor": 1.2
      },
      "boost_mode": "multiply"
    }
  }
}

在这里插入图片描述
function 分数为,ln1p(1.2 * doc['view_cnt'].value)如果指定字段缺失用 missing 对应的值,至于和匹配的相关性分数 _score 如何结合需要下面的 boost_mode 参数来决定

  • random_score使用一致性随机分值计算来对每个用户采用不同的结果排序方式,对相同用户仍然使用相同的排序方式其本质上用的是seed 种子参数,用户相关的 id 与 seed 构造映射关系,就可千人千面的效果,seed 不同排序结果也不同。具体示例如下:
    ①字段值相同,例如通过full_room,由上面查询结果可知,两个结果的full_room相同,此时使用random_score,两个的排序结果仍然是一致的:
POST /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      },
      "random_score": {
        "field":"full_room",
        "seed": 10
      },
      "boost_mode": "multiply"
    }
  }
}

在这里插入图片描述
如果对price进行随机加强,那么排序就会不一样:

POST /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      },
      "random_score": {
        "field":"price",
        "seed": 10
      },
      "boost_mode": "multiply"
    }
  }
}

在这里插入图片描述
我们可以调整seed,就会发现排序不一样。

  • 衰减函数(decay function):es 内置了三种衰减函数,分别是 linear、exp 和 gauss;

三种衰减函数的差别只在于衰减曲线的形状,在 DSL 的语法上的用法完全一样;
linear : 线性函数是条直线,一旦直线与横轴0香蕉,所有其他值的评分都是0
exp : 指数函数是先剧烈衰减然后变缓
guass(最常用) : 高斯函数则是钟形的,他的衰减速率是先缓慢,然后变快,最后又放缓
在这里插入图片描述

origin:中心点 或字段可能的最佳值,落在原点 origin 上的文档评分 _score 为满分 1.0 。

scale:衰减率,即一个文档从原点 origin 下落时,评分 _score 改变的速度。(例如,每 £10 欧元或每 100 米)。

decay:从原点 origin 衰减到 scale 所得的评分 _score ,默认值为 0.5 。

offset:以原点 origin 为中心点,为其设置一个非零的偏移量 offset 覆盖一个范围,而不只是单个原点。在范围 -offset <= origin <= +offset 内的所有评分 _score 都是 1.0 。不设置默认是0

POST /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      },
      "gauss": {
        "price": {
              // 如果不设置offset,offset默认为0  公式 : origin-offset <= value <= origin+offset
             // 范围在800-0 <= value <= 800+0的文档的评分_score都是满分1.0
            //而在此范围之外,评分会开始衰减,衰减率由scale值(此处是300)和decay值(此处是0.2)决定
           // 也就是说,在origin + offset + scale或是origin - offset - scale的点上,得到的分数仅有decay分
          "origin": "800",
          "scale": "300",
          "decay": 0.2
        }
      }, 
      "boost_mode": "multiply"
    }
  }
}

在这里插入图片描述
对衰减函数感兴趣的小伙伴可以浏览这篇文章,讲的很详细,尤其是最后对于用户同时对于酒店的地理位置和价格去做一个筛选。

  • script_score:当需求超出以上范围时,可以用自定义脚本完全控制评分计算。

3.3、其它辅助函数

  • boost_mode 参数:决定 query 中的相关性分数和加强的函数分数的结合方式。

multiply默认的配置,两者分数相乘,new_score = _score * boost_score;
sum:两者相加,new_score = _score + boost_score;
min:取两者最小值,new_score = min(_score, boost_score);
max:取两者最大值,new_score = max(_score, boost_score);
replace:用 boost_score 替换 _score 值。有时候我们可以通过replace看具体的函数得分是多少,便于我们排查问题

  • score_mode 参数决定 functions 里面的强化 score 如何结合

function_score 先会执行 score_mode 的设置,即先整合所有的强化计算,再执行 boost_mode 的配置,就是将 query 相关性分数和整合强化分数的结合
multiply:默认的配置,多个强化分数相乘;
sum:多个强化分数相加;
min:取多个强化分数最小值;
max:取多个强化分数最大值;
avg:取多个强化分数平均值;
first:使用首个函数的结果作为最终结果。

  • max_boost:限制加强函数的最大效果,就是限制加强 score 最大能多少,但要注意不会限制 old_score。

如果加强 score 超过了 max_boost 限制的值,会把加强 score 的值设成 max_boost 的值
假设加强 score 是5,而 max_boost 是2,因为加强 score 超出了 max_boost 的限制,所以 max_boost 就会把加强 score 改为2。简单的说,就是 final_score = min(整合后的 score, max_boost)。

3.4、java实现

funtion_score的参数我们可以通过ScoreFunctionBuilders.xxx构筑
在这里插入图片描述
Service层实现:

	public List<Hotel> functionScoreScore(HotelDocRequest hotelDocRequest) throws IOException {
		//新建搜索请求
		String indexName = getNotNullIndexName(hotelDocRequest);
		SearchRequest searchRequest = new SearchRequest(indexName);
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("city", "上海");
		//构建FunctionScoreBuilder,比如这里构筑高斯函数(衰减函数)
		GaussDecayFunctionBuilder gaussDecayFunctionBuilder = ScoreFunctionBuilders.gaussDecayFunction(hotelDocRequest.getPropertiesName(), 800, 200, 0, 0.2);
		//构建Function Score查询
		FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(termQueryBuilder, gaussDecayFunctionBuilder).boostMode(CombineFunction.MULTIPLY);
		searchSourceBuilder.query(functionScoreQueryBuilder);
		searchRequest.source(searchSourceBuilder);
		return getQueryResult(searchRequest);
	}

controller层实现:

	@PostMapping("/query/function_score")
	public FoundationResponse<List<Hotel>> functionScoreQuery(@RequestBody HotelDocRequest hotelDocRequest) {
		try {
			List<Hotel> hotelList = esQueryService.functionScoreScore(hotelDocRequest);
			if (CollUtil.isNotEmpty(hotelList)) {
				return FoundationResponse.success(hotelList);
			} else {
				return FoundationResponse.error(100,"no data");
			}
		} catch (IOException e) {
			log.warn("搜索发生异常,原因为:{}", e.getMessage());
			return FoundationResponse.error(100, e.getMessage());
		} catch (Exception e) {
			log.error("服务发生异常,原因为:{}", e.getMessage());
			return FoundationResponse.error(100, e.getMessage());
		}
	}

postman实现截图:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

01_Redis单线程与多线程

01——Redis单线程与多线程 一、Redis是单线程还是多线程 在谈Redis的单线程或多线程时&#xff0c;需要根据版本来区分。 在redis 3.x之前&#xff0c;redis是单线程的从redis 4.x开始&#xff0c;redis引入多线程。处理客户端请求时&#xff0c;使用单线程&#xff1b;在异…

Android app 打包发布之build.gradle 配置

配置描述&#xff1a;在build.gradle(:app)文件中配置 包含以下几个部分&#xff1a; plugins&#xff1a;引入的工具android&#xff1a;主要配置都在这个里面dependencies&#xff1a;依赖android.applicationVariants.all&#xff1a;打包输出路径和名称 看android配置&a…

基于Spring Boot的餐厅订餐网站的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的餐厅订餐网站的设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java springbo…

稳定扩散ControlNet v1.1 权威指南

ControlNet 是一种稳定扩散模型&#xff0c;可让你从参考图像中复制构图或人体姿势。 经验丰富的稳定扩散用户知道生成想要的确切成分有多难。图像有点随机。你所能做的就是玩数字游戏&#xff1a;生成大量图像并选择你喜欢的图片。 借助 ControlNet&#xff0c;稳定扩散用户…

0基础入门代码审计-2 Fortify初探

0x01 序言 目前又加入一位新童鞋了&#xff0c;最近将会再加入cs相关的专栏&#xff0c;都是以基础为主&#xff0c;毕竟太复杂的东西&#xff0c;能看懂的人太少。 0x02 准备工具 1、Fortify 2、需要审计的源码 0x03 Fortify的简单使用 1、 1、在开始菜单栏中找到Audit Wo…

3D WEB轻量化引擎HOOPS产品助力NAPA打造船舶设计软件平台

NAPA&#xff08;Naval Architectural PAckage&#xff0c;船舶建筑包&#xff09;&#xff0c;来自芬兰的船舶设计软件供应商&#xff0c;致力于提供世界领先的船舶设计、安全及运营的解决方案和数据分析服务。NAPA拥有超过30年的船舶设计经验&#xff0c;年营业额超过2560万欧…

算法基础(1):排序和查找算法

1、排序算法 1.1、堆排序(大顶堆)-重点&#xff1a; 参考文章&#xff1a;堆排序1、堆排序二 前置知识&#xff1a; 大顶堆&#xff1a;完全二叉树&#xff0c;且父节点大于左右儿子&#xff0c;左右子树又是大顶堆&#xff0c;依赖数组来实现(vector)第一个节点的父节点&…

视频汇聚平台EasyCVR安防视频监控平台新增角色权限功能分配的具体操作步骤

视频集中存储/云存储/安防视频监控/视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 EasyCVR视频集中…

python连接PostgreSQL 数据库

执行如下命令安装 pip3 install psycopg2 python代码 Author: tkhywang 2810248865qq.com Date: 2023-08-21 11:42:17 LastEditors: tkhywang 2810248865qq.com LastEditTime: 2023-08-21 11:51:56 FilePath: \PythonProject02\PostgreSQL 数据库.py Description: 这是默认设置…

想解锁禁用的iPhone?除了可以使用电脑之外,这里还有不需要电脑的方法!

多次输入错误的密码后,iPhone将显示“iPhone已禁用”。这种情况看起来很棘手,因为你现在不能用iPhone做任何事情。对于这种情况,我们提供了几种有效的方法来帮助你在最棘手的问题中解锁禁用的iPhone。你可以选择使用或不使用电脑来解锁禁用的iPhone。 一、为什么你的iPhone…

深度学习实战49-基于卷积神经网络和注意力机制的汽车品牌与型号分类识别的应用

大家好,我是微学AI,今天给大家介绍一下深度学习实战49-基于卷积神经网络和注意力机制的汽车品牌与型号分类识别的应用,该项目就像是一只智慧而敏锐的眼睛,专注地凝视着汽车世界。这个项目使用PyTorch作为强有力的工具,提供了一个深度学习的舞台,让我们能够设计和训练一个…

穿起“新架构”的舞鞋,跳一支金融数字化转型的华尔兹

华尔兹&#xff0c;是男女两位舞者&#xff0c;通过形体的控制&#xff0c;舞步技巧的发挥&#xff0c;完美配合呈现而出的一种舞蹈形式。华尔兹舞姿&#xff0c;如行云流水、潇洒自如、飘逸优美&#xff0c;素有“舞中皇后”的美称。 在跳华尔兹的时候&#xff0c;如果舞者双…

会议剪影|思腾合力受邀参加2023中国算力大会并作主题演讲

共享数字经济合作新机遇&#xff0c;携手开创算力产业新未来。8月18日-19日&#xff0c;由工业和信息化部、宁夏回族自治区人民政府主办的2023中国算力大会、第二届“西部数谷”算力产业大会在银川盛大启幕。思腾云计算总经理庞志刚、思腾合力市场总监徐莉受邀参会。 ▲思腾云计…

客户案例:高性能、大规模、高可靠的AIGC承载网络

客户是一家AIGC领域的公司&#xff0c;他们通过构建一套完整的内容生产系统&#xff0c;革新内容创作过程&#xff0c;让用户以更低成本完成内容创作。 客户网络需求汇总 RoCE的计算网络RoCE存储网络1.不少于600端口200G以太网接入端口&#xff0c;未来可扩容至至少1280端口1.…

带你了解 Java 8 Stream:掌握流处理中的收集器技巧

Java 8 引入的 Stream 极大地简化了集合数据的处理&#xff0c;提供了一种现代、函数式的方式来处理数据。然而&#xff0c;在处理流时&#xff0c;我们经常需要将流的结果汇总到集合中或者进行各种统计计算。这就是收集器&#xff08;Collectors&#xff09;发挥作用的地方。本…

直播系统源码协议探索篇(二):网络套接字协议WebSocket

上一篇我们分析了直播平台的会话初始化协议SIP&#xff0c;他关乎着直播平台的实时通信和多方互动技术的实现&#xff0c;今天我们来讲另一个协议&#xff0c;叫网络套接字协议WebSocket&#xff0c;WebSocket基于TCP在客户端与服务器建立双向通信的网络协议&#xff0c;并且可…

React项目build打包后,页面空白的解决方案

问题描述&#xff1a; React项目执行 build 命令后&#xff0c;在本地服务器打开页面 是空白的&#xff0c;而且控制台报错 如下图所示 解决方法 打开根目录下的 package.json 文件&#xff0c;添加如下代码 {"name": "testproject","version"…

火山引擎发布自研视频编解码芯片 压缩效率提升30%

8月22日&#xff0c;火山引擎视频云宣布其自研的视频编解码芯片已成功出片。经验证&#xff0c;该芯片的视频压缩效率相比行业主流硬件编码器可提升30%以上&#xff0c;未来将服务于抖音、西瓜视频等视频业务&#xff0c;并将通过火山引擎视频云开放给企业客户。 火山引擎总裁…

vue3安装组件

如何创建vue项目链接&#xff1a;http://t.csdn.cn/tX8wY 新建vue项目如何配置&#xff1a;http://t.csdn.cn/YLdTG 我们这里拿vant组件演示 首先安装组件库 # Vue 3 项目&#xff0c;安装最新版 Vant npm i vant 可以在package.json查看 我们找到main.js 按钮举例 写入自…

微信小程序路由以及跳转页面传递参数

路由 在app.json的pages里面写 "pages/页面/页面" 直接保存pages直接生成非常方便 跳转页面 wx.navigateTo() 保留当前页面&#xff0c;跳转到应用内的某个非tabBar页面。 <text bindtap"daka">点击</text> daka:function () {wx.navigateTo…