Elasticsearch聚合查询多字段设置权重

  • 背景
  • 环境说明
  • script设置权重
  • 小结

背景

实际应用中,可能会需要为为doc文档中某个字段的某些特定的值设置权重,影响排序。es提供了比较灵活的script脚本方式来设置权重,影响评分。以下实现是基于聚合查询的,如果非聚合查询的话,也差不多,可以简单参考下。

环境说明

  1. 开发语言:Java
  2. 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倒排

小结

是不是即灵活又简单呢!还有以下两点也要关注下:

  1. 这种是在聚合后计算得分,聚合前也可以使用ScriptFunction计算得分,但这样性能会差很多,特别在数据体量大的时候;
  2. 计算后的得分不要出现有null的(有null会使得排序失效),即脚本中要考虑到每一种情况,给出返回;

Elasticsearch聚合查询多字段设置权重相关推荐

  1. php聚合查询,php elasticsearch 聚合查询(Aggregation)

    Elasticsearch中的聚合查询,类似SQL的SUM/AVG/COUNT/GROUP BY分组查询,主要用于统计分析场景. 这里主要介绍PHP Elasticsearch 聚合查询的写法,如果不 ...

  2. Elasticsearch聚合查询案例分享

    为什么80%的码农都做不了架构师?>>>    Elasticsearch聚合查询案例分享 1.案例介绍 本文包含三个案例: 案例1:统计特定时间范围内每个应用的总访问量.访问成功数 ...

  3. ES聚合查询根据字段进行分组

    es在使用聚合查询根据字段进行分组的时候,发现一个情况 // 声明where 条件 BoolQueryBuilder qbs = QueryBuilders.boolQuery();QueryBuil ...

  4. ElasticSearch聚合查询返回结果buckets取值

    ElasticSearch聚合查询返回结果buckets取值 1.聚合查询如下: {"size":0,"query":{"bool":{&q ...

  5. java中使用ElasticSearch聚合查询代码实例(个人笔记,不喜勿喷)

    PS→无奈:拥有梦想只是一种智力,实现梦想才是一种能力. 空闲之余就把先前做过的一个通过ElasticSearch的聚合来实现查询当月实际签到的天数记录一下,纯留下点记忆,大家勿喷. 1.如果不了解e ...

  6. (转)Elasticsearch 聚合查询、桶聚合、管道聚合及复合查询

    转自: https://blog.csdn.net/zx711166/article/details/81906881 聚合查询 聚合是一种基于查询条件对数据进行分桶.计算的方法. 聚合可以嵌套,由此 ...

  7. ElasticSearch 聚合查询 JavaApi

    ES 聚合查询Java Api 分页查询,按照时间进行分组查询求平均(多平均),按照某一字段分组求聚合等等 分页查询 SysUser loginUser = SecurityUtils.getLogi ...

  8. ElasticSearch聚合查询Restful语法和JavaApi详解(基于ES7.6)

    本文收录于github和gitee ,里面有我完整的Java系列文章,学习或面试都可以看看 (一)概述 在前面关于ES的一系列文章中,已经介绍了ES的概念.常用操作.JavaAPI以及实际的一个小de ...

  9. ES/ElasticSearch 聚合查询时报错:too_many_buckets_exception

    环境:ElasticSearch6.7 问题描述: {"error": {"root_cause": [],"type": "se ...

最新文章

  1. Dingo Api 入门
  2. 【水滴石穿】imooc_gp
  3. Spring Boot JPA中java 8 的应用
  4. linux主要系统服务介绍
  5. Linux文件属性之r、w、x
  6. leetcode97. 交错字符串(动态规划)
  7. [react] React.createClass和extends Component的区别有哪些?
  8. Prometheus 监控Mysql服务器及Grafana可视化
  9. spark学习-54-Spark RDD的clean()方法
  10. android压缩图片,并将其转化成base64提交到服务器
  11. php rand js,js中的php rand函数
  12. 【视频分享】尚硅谷HTML5前端视频_React视频
  13. win10更改登录密码
  14. Java应用无响应、内存飙升、CPU飙升排查
  15. np和tensor转换
  16. 广告图片自动轮播控件
  17. 给32位系统装8g内存条能用吗?为什么?
  18. Android 后台启动startService()相关问题的解决
  19. 贫民窟里的WPF系列讲座(二)
  20. 大学java程序设计期末考试,成功跳槽阿里!

热门文章

  1. 空压机数据采集系统,使用昆仑通态触摸屏制作,具备完善的数据采集和历史记录保存功能
  2. 一款适用于搭建内部培训平台的系统,开源了!
  3. 计算机专业申请phd美国,美国计算机专业PHD的申请经验总结
  4. 单商户商城系统功能拆解45—应用中心—积分商城
  5. USB TYPE-C详解
  6. 新型冠状病毒肺炎相关常用英语单词和词语
  7. 绿色数据中心:风冷GPU服务器和水冷GPU服务器综合分析
  8. SSM项目-小米商城
  9. 3dMax2022安装方法详解
  10. 传感器系列之4.4超声测距传感器