Elasticsearch聚合查询多字段设置权重
Elasticsearch聚合查询多字段设置权重
- 背景
- 环境说明
- script设置权重
- 小结
背景
实际应用中,可能会需要为为doc文档中某个字段的某些特定的值设置权重,影响排序。es提供了比较灵活的script脚本方式来设置权重,影响评分。以下实现是基于聚合查询的,如果非聚合查询的话,也差不多,可以简单参考下。
环境说明
- 开发语言:Java
- elasticsearch 版本 7.3.1
script设置权重
初始数据
{"id": "6",“title”:"苹果","catalogId": "01","catalogName": "水果","itemType": "01"},{"id": "7",“title”:"香菇","catalogId": "02","catalogName": "蔬菜","itemType": "02"},{"id": "8",“title”:"芹菜","catalogId": "02","catalogName": "蔬菜","itemType": "02"},{"id": "9",“title”:"鸡肉","catalogId": "03","catalogName": "肉类","itemType": "03"}
以下示例使用catalogId聚合,itemType标识某种业务分类,要求查到的数据中相关度差不多情况下itemType为01的在前,其次是03,最后是02.这里查询条件是match_all
废话不多说,上代码!
//获取组的总数CardinalityAggregationBuilder totalBuilder = AggregationBuilders.cardinality("total").field("catalogId");//groupBy分组统计TermsAggregationBuilder termsBuilder = AggregationBuilders.terms("groupByKey").field("catalogId").collectMode(Aggregator.SubAggCollectionMode.BREADTH_FIRST);//查询分组后数据TopHitsAggregationBuilder groupByKey = AggregationBuilders.topHits("groupByKey").highlighter(highlightBuilder).fetchSource(true).size(10).fetchSource(new String[]{"id","catalogId", "title", "catalogName","itemType"}, new String[]{});Map<String, Object> map = new HashMap<>();map.put("yilei", "01");map.put("yileiWeight", 1.2);map.put("erlei", "02");map.put("erleiWeight", 0.1);map.put("otherWeight", 1);//分组评分Script script = new Script(ScriptType.INLINE,"painless", "if(doc['itemType'].value==params.yilei) { return params.yileiWeight * _score} else if(doc['itemType'].value==params.erlei) { return params.erleiWeight * _score} else {return params.otherWeight * _score}", map);MaxAggregationBuilder topScore = AggregationBuilders.max("top_score").script(script);AggregatorFactories.Builder factorBuilder = AggregatorFactories.builder();factorBuilder .addAggregator(groupByKey);factorBuilder .addAggregator(topScore);termsBuilder.subAggregations(factorBuilder );BucketOrder bucketOrder = BucketOrder.aggregation("top_score", false);termsBuilder.order(bucketOrder);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();boolQueryBuilder.must(QueryBuilders.matchAllQuery());searchSourceBuilder.aggregation(termsBuilder );searchSourceBuilder.aggregation(totalBuilder);
查询后排序效果如下,达到预期
{"id": "6","catalogId": "01","catalogName": "水果","itemType": "01"},{"id": "9","catalogId": "03","catalogName": "肉类","itemType": "03"},{"id": "7","catalogId": "02","catalogName": "蔬菜","itemType": "02"}
根据top_score倒排
小结
是不是即灵活又简单呢!还有以下两点也要关注下:
- 这种是在聚合后计算得分,聚合前也可以使用ScriptFunction计算得分,但这样性能会差很多,特别在数据体量大的时候;
- 计算后的得分不要出现有null的(有null会使得排序失效),即脚本中要考虑到每一种情况,给出返回;
Elasticsearch聚合查询多字段设置权重相关推荐
- php聚合查询,php elasticsearch 聚合查询(Aggregation)
Elasticsearch中的聚合查询,类似SQL的SUM/AVG/COUNT/GROUP BY分组查询,主要用于统计分析场景. 这里主要介绍PHP Elasticsearch 聚合查询的写法,如果不 ...
- Elasticsearch聚合查询案例分享
为什么80%的码农都做不了架构师?>>> Elasticsearch聚合查询案例分享 1.案例介绍 本文包含三个案例: 案例1:统计特定时间范围内每个应用的总访问量.访问成功数 ...
- ES聚合查询根据字段进行分组
es在使用聚合查询根据字段进行分组的时候,发现一个情况 // 声明where 条件 BoolQueryBuilder qbs = QueryBuilders.boolQuery();QueryBuil ...
- ElasticSearch聚合查询返回结果buckets取值
ElasticSearch聚合查询返回结果buckets取值 1.聚合查询如下: {"size":0,"query":{"bool":{&q ...
- java中使用ElasticSearch聚合查询代码实例(个人笔记,不喜勿喷)
PS→无奈:拥有梦想只是一种智力,实现梦想才是一种能力. 空闲之余就把先前做过的一个通过ElasticSearch的聚合来实现查询当月实际签到的天数记录一下,纯留下点记忆,大家勿喷. 1.如果不了解e ...
- (转)Elasticsearch 聚合查询、桶聚合、管道聚合及复合查询
转自: https://blog.csdn.net/zx711166/article/details/81906881 聚合查询 聚合是一种基于查询条件对数据进行分桶.计算的方法. 聚合可以嵌套,由此 ...
- ElasticSearch 聚合查询 JavaApi
ES 聚合查询Java Api 分页查询,按照时间进行分组查询求平均(多平均),按照某一字段分组求聚合等等 分页查询 SysUser loginUser = SecurityUtils.getLogi ...
- ElasticSearch聚合查询Restful语法和JavaApi详解(基于ES7.6)
本文收录于github和gitee ,里面有我完整的Java系列文章,学习或面试都可以看看 (一)概述 在前面关于ES的一系列文章中,已经介绍了ES的概念.常用操作.JavaAPI以及实际的一个小de ...
- ES/ElasticSearch 聚合查询时报错:too_many_buckets_exception
环境:ElasticSearch6.7 问题描述: {"error": {"root_cause": [],"type": "se ...
最新文章
- Dingo Api 入门
- 【水滴石穿】imooc_gp
- Spring Boot JPA中java 8 的应用
- linux主要系统服务介绍
- Linux文件属性之r、w、x
- leetcode97. 交错字符串(动态规划)
- [react] React.createClass和extends Component的区别有哪些?
- Prometheus 监控Mysql服务器及Grafana可视化
- spark学习-54-Spark RDD的clean()方法
- android压缩图片,并将其转化成base64提交到服务器
- php rand js,js中的php rand函数
- 【视频分享】尚硅谷HTML5前端视频_React视频
- win10更改登录密码
- Java应用无响应、内存飙升、CPU飙升排查
- np和tensor转换
- 广告图片自动轮播控件
- 给32位系统装8g内存条能用吗?为什么?
- Android 后台启动startService()相关问题的解决
- 贫民窟里的WPF系列讲座(二)
- 大学java程序设计期末考试,成功跳槽阿里!