当前位置: 首页 > news >正文

东莞网站公司建设网站十万pv的网站建设

东莞网站公司建设网站,十万pv的网站建设,共享网站哪里建,网站前置审批证书一、前言 本节主要学习ES匹配查询中的布尔查询以及布尔查询中比较特殊的filter查询及其原理。 复合搜索#xff0c;顾名思义是一种在一个搜索语句中包含一种或多种搜索子句的搜索。 布尔查询是常用的复合查询#xff0c;它把多个子查询组合成一个布尔表达式#xff0c;这些…一、前言 本节主要学习ES匹配查询中的布尔查询以及布尔查询中比较特殊的filter查询及其原理。 复合搜索顾名思义是一种在一个搜索语句中包含一种或多种搜索子句的搜索。 布尔查询是常用的复合查询它把多个子查询组合成一个布尔表达式这些子查询之间的逻辑关系是与即所有子查询的结果都为true时布尔查询结果才为真。布尔查询还可以按照各个子查询的具体匹配程度对文档进行打分计算除了比较特殊的must not查询和filter查询之外这个后面会详解。 布尔查询支持的子查询主要有4种各子查询的名称和功能如下表 子查询名称功能must必须匹配该查询条件should可以匹配该查询条件must not必须不匹配该查询条件且不进行打分计算filter必须匹配过滤条件,且不进行打分计算 下面将逐一进行讲解 二、布尔查询 2.1、must查询 当查询中包含must查询时相当于逻辑查询中的与查询。命中的文档必须匹配该子查询的结果并且ES会将该子查询与文档的匹配程度值加入总得分里。must搜索包含一个数组可以把其他的搜索匹配查询及布尔查询放入其中。 以下示例使用must查询城市范围为上海和南昌且创建时间范围在2021-02-27 22:00:00到2024-02-27 22:00:00DSL如下 POST /hotel/_search {query: {bool: {must: [{terms: { //第一个terms子查询城市为上海和南昌city: [上海,南昌]}},{range: { //第二个range子查询时间范围为2021-02-27 22:00:00到2024-02-27 22:00:00包括边界create_time: { gte: 2021-02-27 22:00:00,lte: 2024-02-27 22:00:00}}}]}} }结果如下图可以看到结果是同时满足的且我们发现是有打分的 在java客户端上构建must搜索时可以使用QueryBuilder.boolQuery().must()进行构建上面的must查询例子改写成Java客户端请求的形式为: Service层private方法在后面的查询中通用不会再展示 public ListHotel mustQuery(HotelDocRequest hotelDocRequest) throws IOException {//新建搜索请求String indexName getNotNullIndexName(hotelDocRequest);SearchRequest searchRequest new SearchRequest(indexName);SearchSourceBuilder searchSourceBuilder new SearchSourceBuilder();TermsQueryBuilder termsQueryBuilder QueryBuilders.termsQuery(city, hotelDocRequest.getCities());Date createTimeStart hotelDocRequest.getCreateTimeStart();String createTimeStartToSearch new SimpleDateFormat(yyyy-MM-dd HH:mm:ss).format(createTimeStart);Date createTimeEnd hotelDocRequest.getCreateTimeEnd();String createTimeEndToSearch new SimpleDateFormat(yyyy-MM-dd HH:mm:ss).format(createTimeEnd);RangeQueryBuilder rangeQueryBuilder QueryBuilders.rangeQuery(create_time).gte(createTimeStartToSearch).lte(createTimeEndToSearch);BoolQueryBuilder boolQueryBuilder QueryBuilders.boolQuery();boolQueryBuilder.must(rangeQueryBuilder).must(termsQueryBuilder);searchSourceBuilder.query(boolQueryBuilder);searchRequest.source(searchSourceBuilder);return getQueryResult(searchRequest);}private String getNotNullIndexName(HotelDocRequest hotelDocRequest) {String indexName hotelDocRequest.getIndexName();if (CharSequenceUtil.isBlank(indexName)) {throw new SearchException(索引名不能为空);}return indexName;}private ListHotel getQueryResult(SearchRequest searchRequest) throws IOException {ArrayListHotel resultList new ArrayList();SearchResponse searchResponse client.search(searchRequest, RequestOptions.DEFAULT);RestStatus status searchResponse.status();if (status ! RestStatus.OK) {return Collections.emptyList();}SearchHits searchHits searchResponse.getHits();for (SearchHit searchHit : searchHits) {Hotel hotelResult new Hotel();hotelResult.setId(searchHit.getId()); //文档_idhotelResult.setIndex(searchHit.getIndex()); //索引名称hotelResult.setScore(searchHit.getScore()); //文档得分//转换为MapMapString, Object dataMap searchHit.getSourceAsMap();hotelResult.setTitle((String) dataMap.get(title));hotelResult.setCity((String) dataMap.get(city));Object price dataMap.get(price);if(price ! null){hotelResult.setPrice(Double.valueOf((String)price));}resultList.add(hotelResult);}return resultList;}controller层 PostMapping(/query/must)public FoundationResponseListHotel mustQuery(RequestBody HotelDocRequest hotelDocRequest) {try {ListHotel hotelList esQueryService.mustQuery(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调用 2.2、should查询 当查询中包含should查询时表示当前查询为或查询。命中的文档可以匹配该查询中的一个或多个子查询的结果并且ES会将该查询与文档的匹配程度加入总得分里。should查询包含一个数组可以把其他的查询匹配的查询及布尔查询放入其中 例如我这边需要查询城市为上海或北京的酒店 DSL如下 POST /hotel/_search {query: {bool: {should: [{term: {city: {value: 上海}}},{term: {city: {value: 北京}}}]}} }查询结果如图所示 可以看到城市为上海或者北京的酒店全部被查询出来了。且有根据匹配程度打分 在java客户端上构建should搜索时可以使用QueryBuilder.boolQuery().should()进行构建上面的should查询例子改写成Java客户端请求的形式为: Service层: public ListHotel shouldQuery(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);searchSourceBuilder.query(boolQueryBuilder);searchRequest.source(searchSourceBuilder);return getQueryResult(searchRequest);}controller层 PostMapping(/query/should)public FoundationResponseListHotel shouldQuery(RequestBody HotelDocRequest hotelDocRequest) {try {ListHotel hotelList esQueryService.shouldQuery(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调用演示 2.3、must not查询 当查询中包含must not查询时表示当前查询为非查询。命中的文档不能匹配该查询中的一个或多个子查询的结果。must not查询包含一个数组可以把其他的查询匹配的查询及布尔查询放入与上面的2个布尔查询不同must not查询不会进行打分操作 must not查询是用来排除与指定条件匹配的文档的。它的作用是将与条件匹配的文档从结果中排除掉而不是对这些文档进行打分。因此must not查询不涉及打分仅仅关注匹配与不匹配。这一点和后面的filter查询原理上是一样的 例如我这边需要查询城市既不为上海也不是北京的酒店 DSL如下 POST /hotel/_search {query: {bool: {must_not: [{term: {city: {value: 上海}}},{term: {city: {value: 北京}}}]}} }查询结果如图所示 可以看到查询出来的节点城市均不为北京或者上海。但是并有根据匹配程度打分 在java客户端上构建must not搜索时可以使用QueryBuilder.boolQuery().mustNot()进行构建上面的must not查询例子改写成Java客户端请求的形式为: Service层 public ListHotel mustNotQuery(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.mustNot(termQueryBuilder1).mustNot(termQueryBuilder2);searchSourceBuilder.query(boolQueryBuilder);searchRequest.source(searchSourceBuilder);return getQueryResult(searchRequest);}controller层 PostMapping(/query/must_not)public FoundationResponseListHotel mustNotQuery(RequestBody HotelDocRequest hotelDocRequest) {try {ListHotel hotelList esQueryService.mustNotQuery(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查询 2.4、filter查询 filter查询即过滤查询该查询是布尔查询里非常独特的一种查询如果说前面的must not查询用于排除与条件匹配的文档将这些文档从查询结果中排除掉。filter查询就是用于精确过滤文档它只关注文档是否符合条件将匹配的文档包含在结果中。他们都不进行打分、排序或相关性计算只担心是否匹配。但是filter和must not原理上还是存在一些区别这个后面讲先对功能进行讲解 例如我要查询城市是上海且已经满员的酒店 POST /hotel/_search {query: {bool: {filter: [{term: {city: {value: 上海}}},{term: {full_room: {value: true}}}]}} }可以看出查询的条件中符合指纹上海且满员且并没有进行打分 而filter查询会在布尔查询初始阶段进行执行并将符合条件的文档结果保存下来接着才会去执行剩余的查询不管你写的顺序例如我先写must再写filter,ES执行器也会先执行filter过滤在过滤后得到的剩余文档中再去执行其他的布尔查询这样的目的是为了提高查询效率因为filter查询会将文档集合进行过滤只保留满足条件的文档再将这些文档传递给must查询进行进一步的条件匹配和评分。 filter查询主要目的是根据指定的条件来快速地过滤掉不符合条件的文档以减少后续的计算和评分操作。 请注意当使用filter查询时Elasticsearch会对搜索结果进行缓存以进一步提高性能。缓存可在后续的相同查询中重复使用除非索引数据发生更改。这使得过滤器查询非常适合用于频繁执行的静态条件过滤 在java客户端上构建filter搜索时可以使用QueryBuilders.boolQuery.filter()进行构建例如我要查询城市是上海且已经满员的酒店改写成java客户端请求的形式为 service层 public ListHotel filterQuery(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(full_room, true);BoolQueryBuilder boolQueryBuilder QueryBuilders.boolQuery();boolQueryBuilder.filter(termQueryBuilder1).filter(termQueryBuilder2);searchSourceBuilder.query(boolQueryBuilder);searchRequest.source(searchSourceBuilder);return getQueryResult(searchRequest);}controller层 PostMapping(/query/filter)public FoundationResponseListHotel filterQuery(RequestBody HotelDocRequest hotelDocRequest) {try {ListHotel hotelList esQueryService.filterQuery(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调用 三、filter查询原理 假设当前有5个文档ES对于city字段的倒排索引结构如图所示 ES对于满房字段倒排的索引结构如图所示 下面以同时查询city为北京且不满房为例讲解ES内部执行filter查询的工作步骤。 当ES执行过滤条件时会查询缓存是否有city字段值为“北京”对应的bitset数组。bitset中文为位图它可以用非常紧凑的格式来表示给定范围内的连续数据。如果查询缓存中有对应的Bitset数据则取出备用反之则ES在查询后会对查询条件进行bitset的构建并将其放入缓存中。同时ES也会考察满房字段为false是否有意对应的bitset数据。如果有则取出备用如果没有ES也会进行bitset的构建。 假设city字段值为“北京”缓存中没有对应的Bitset数据则bitset构建的过程如下 首先ES在倒排索引中查找字段city值为“北京”字符串的文档这里为doc1和doc5。然后为所有文档构建bitset数组数组中每个元素的值用来表示对应位置的文档是否和查询条件匹配0表示未匹配1表示匹配。在本例中doc1和doc5匹配“北京”对应位置的值为1doc2、doc3、doc4不匹配对应的位置为0。最终本例的bitset数组为[1,0,0,0,1]满房字段同理。之所以用bitset表示文档和query的匹配结果是因为该结构不仅节省空间而且后续操作时也能节省时间。 接下来ES会遍历查询条件的bitset数组按照文档命中是否进行文档过滤。当一个请求中有多个filter查询条件时ES会构建多个bitset数组。为提升效率ES会从最稀疏的数组0的元素多于非0元素反之为稠密数组开始便遍历因为遍历稀疏的数组可以过滤掉更多的文档。此时城市为“北京”对应的bitset比满房为false的Bitset更加稀疏因此先遍历城市为“北京”的bitset,再遍历满房为false的bitset。遍历的过程中也进行了位运算每次运算的结果都逐渐接近符合条件的结果。遍历计算完这两个Bitset后得到匹配所有过滤条件的文档即doc1和doc5。 正如上面的介绍如果查询内包含filter那么ES首先就从缓存中搜索这个filter条件是否有执行记录是否有对应的bitset缓存可查询。如果有则从缓存中查询如果没有则为filter中的每个查询项新建bitset并且缓存。以供后续其他带有filter的查询可以先在缓存中查询。也就是说ES对于bitset是可重用的这种重用的机制叫作filter cache过滤器缓存。 filter cache会跟踪每一个filter查询ES筛选一部分filter查询的bitset进行缓存。首先这些过滤条件要在最近256个查询中出现过其次这些过滤条件的次数必须超过某个阈值。 另外filter cache是有自动更新机制的即如果有新增文档或者文档或者文档被修改过那么filter cache对应的过滤条件中的bitset将被更新。例如城市为“北京”过滤条件对应的bitset为[1,0,0,0,1],如果文档4的城市被修改为“北京”则“北京”过滤条件对应的bitset会被自动更新为[1,0,0,1,1]. filter查询带来的效益远不止这些使用filter查询的子句是不计算分数的这可以减少不小的时间开销。而之前提到的must not查询同样也不进行打分但是must not是没有和filter cache这样的缓存机制的。filter查询和must_not查询都是用于筛选文档的查询类型它们不会对文档进行评分。Filter查询适用于需要快速过滤大量文档的场景而must_not查询适用于排除不需要的文档。在实际使用中可以根据具体需求选择合适的查询类型。 为提升查询效率对于简单的term级别匹配查询应该根据自己的实际业务场景选择合适的查询语句需要确定这些查询项是否都需要进行打分操作如果某些匹配条件不需要打分操作的话那么需要把这些查询全部改为filter形式让查询更加高效。
http://www.dnsts.com.cn/news/133554.html

相关文章:

  • 网站被黑刚恢复排名又被黑了哈尔滨网站设计
  • 焦作做网站优化wordpress建立视频网站
  • 手机网站建设liedns海南网站建设中心
  • 好的网站设计机构河南免费网站建设
  • 推广网站2024池州集团网站建设
  • 外贸页面网站制作上海网站搭建公司哪家好
  • 网站主体信息自助友链平台
  • 网站交互主要做什么做网站设计的长宽一般是多少钱
  • 放在主机上的网站程序如何建压缩包然后直接下载大学思政类网站建设
  • 南京浦口住房与城乡建设局网站甘肃住房城乡建设厅网站
  • 海南论坛论坛网站建设iapp源码
  • 足球网站模板shopify
  • 网站开发费用是无形资产建筑公司企业简介范文
  • 网站开发入哪个会计科目开发项目外包
  • 用手机网站做app历史街区和历史建筑信息平台
  • 勾线外包网站网站建设与管理属于什么部门
  • 贵阳企业网站建设制作最新新闻热点事件摘抄300字
  • 怎么查网站icpwordpress怎么给产品编号
  • 罗村网站建设公司免费h5页面应用制作
  • 如何做网站外部链接班级网站制作建设的设计和作用
  • 对于网站运营应该如何做网站怎么做二级页面
  • 网站建设认知与理解织梦cms网站分页打不开
  • 哪里有做营销型网站的公司wordpress主题比较
  • 做一个普通网站多少钱建站免费加盟
  • 网站建设视频百度云长治哪里做网站
  • 无形资产 网站建设wordpress顶部悬浮
  • 公司门户网站开发外国做水吧设计的网站
  • 网站开发什么语言比较好怎样设计网站版面
  • 马鞍山市 网站建设商场设计图
  • 女性时尚网站带论坛php程序网站中如何嵌入支付宝