spring-data-elasticsearch 3.2.4 实现桶bucket排序去重,实现指定字段的聚合搜索

一、背景

es索引有一个文档CourseIndex,下面是示意:

creatorIdgradesubjectnameno
1002270英语听力课程一N00232DS9
1004380数学口算课程N00209DK7
1003480物理竞赛课程N00642XS2
1002280英语听力课程二N00432WS3
1002290英语听力课程三N002312DP5

在搜索的时候,搜索条件包括creatorId列表,grade列表,subject列表等,且它们不是固定的字典,而是从文档CourseIndex的已有数据中获取。

假使上面的数据,搜索条件分别是:

creatorId列表

  • 1002
  • 1003
  • 1004

grade列表

  • 2
  • 3
  • 4

subject列表

  • 70
  • 80
  • 90

总结一下需求,对es文档的数据进行桶bucket排序,以达到去重效果。

下面将介绍如何使用spring-data-elasticsearch 3.2.4实现对指定字段的聚合搜索。

pom.xml引入jar包

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
        
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-elasticsearch</artifactId>
      <version>3.2.4.RELEASE</version>
    </dependency>

二、CourseIndexAggrService.java


import lombok.RequiredArgsConstructor;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xxx
 */
@Component
@RequiredArgsConstructor
public class CourseIndexAggrService {
    private final ElasticsearchRestTemplate elasticsearchRestTemplate;
    private final CommonConfig commonConfig;
    private static final String UNIQUE_FIELD = "unique_field";

    // 需要进行桶排序的字段
    public static final String CREATOR_ID = "creatorId";
    public static final String GRADE = "grade";
    public static final String SUBJECT = "subject";

    public List<String> findUniqueField(String uniqueField) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //TODO 这里boolQueryBuilder是一个空的查询条件
        // 过滤掉已逻辑删除的记录 
        // boolQueryBuilder.filter(QueryBuilders.termQuery("deleted", 0));
        queryBuilder.withQuery(boolQueryBuilder);

        TermsAggregationBuilder termsAgg = AggregationBuilders.terms(UNIQUE_FIELD).field(uniqueField);

        queryBuilder.addAggregation(termsAgg);
        // idx_courseIndex是索引名
        queryBuilder.withIndices("idx_courseIndex");

        // CourseIndex是es文档类,见下文
        AggregatedPage<CourseIndex> resultPage = elasticsearchRestTemplate.queryForPage(queryBuilder.build(), CourseIndex.class);

        Aggregation aggregation = resultPage.getAggregation(UNIQUE_FIELD);

        ParsedLongTerms terms = (ParsedLongTerms) aggregation;

        // 获取桶
        final List<? extends Terms.Bucket> buckets = terms.getBuckets();

        // 提取唯一值
        List<String> uniqueUserIds = new ArrayList<>();
        for (Terms.Bucket bucket : buckets) {
            uniqueUserIds.add(bucket.getKeyAsString());
        }

        return uniqueUserIds;
    }
}

三、CourseIndex.java

这里略去了无关本文的字段。

import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import javax.persistence.Id;
import java.io.Serializable;
import java.util.Set;

/**
 * 课程索引.
 * <p>
 * 索引检索条件,并非所有的字段
 * </p>
 *
 * @author xxx
 */
@Data
@Document(indexName = "#{commonConfig.courseIdx}", type = "_doc", shards = 1, refreshInterval = "-1")
public class CourseIndex implements Serializable {
    @Id
    private String id;

    /**
     * 课程或讲次编号
     */
    @Field(type = FieldType.Keyword)
    private String no;

    /**
     * 创建者ID
     */
    @Field(type = FieldType.Long)
    private long creatorId;

    /**
     * 课程或讲次名称
     */
    @Field(type = FieldType.Text)
    private String name;

    /**
     * 科目
     */
    @Field(type = FieldType.Integer)
    private int subject;

    /**
     * 年级
     */
    @Field(type = FieldType.Integer)
    private int grade;
}

四、使用

// 查询创建者creatorId列表
final List<Long> userIds = courseIndexAggrService.findUniqueField(CREATOR_ID).stream().map(v -> Long.parseLong(v)).collect(Collectors.toList());

// 查询年级grade列表
final List<Integer> grades = courseIndexAggrService.findUniqueField(GRADE).stream().map(v -> Integer.parseInt(v)).collect(Collectors.toList());

// 查询科目subject列表
final List<Integer> subjects = courseIndexAggrService.findUniqueField(SUBJECT).stream().map(v -> Integer.parseInt(v)).collect(Collectors.toList());

在这里插入图片描述

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

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

相关文章

内容占位符:Kinetic Loader HTML+CSS 使用CSS制作三角形原理

内容占位符 前言 随着我们对HTML和CSS3的学习逐渐深入&#xff0c;相信大家都已经掌握了网页制作的基础知识&#xff0c;包括如何使用HTML标记构建网页结构&#xff0c;以及如何运用CSS样式美化页面。为了进一步巩固和熟练这些技能&#xff0c;今天我们一起来完成一个有趣且实…

【OH】openHarmony开发环境搭建(基于windows子系统WSL)

前言 本文主要介绍基于windows子系统WSL搭建openHarmony开发环境。 WSL与Vmware虚拟机的区别&#xff0c;可以查看WSL与虚拟机的区别 更详细的安装配置过程可参考微软官网&#xff1a; ​安装 WSL 前提 以下基于windows 111专业版进行配置&#xff0c;windows 10应该也是可以…

深入理解 source 和 sh、bash 的区别

1 引言 在日常使用 Linux 的过程中&#xff0c;脚本的执行是不可避免的需求之一&#xff0c;而 source、sh、bash 等命令则是执行脚本的常用方式。尽管这些命令都能运行脚本&#xff0c;但它们之间的执行方式和效果却有着显著的区别。这些区别可能会影响到脚本的环境变量、工作…

LogViewer NLog, Log4Net, Log4j 文本日志可视化

LogViewer 下载 示例&#xff1a;NLog文本日志可视化软件&#xff0c;并且能够实时监听输出最新的日志 nlog.config 通过udp方式传输给LogViewer (udp://ip:port) <?xml version"1.0" encoding"utf-8" ?> <nlog xmlns"http://www.nlog-…

探索 HTML 和 CSS 实现的蜡烛火焰

效果演示 这段代码是一个模拟蜡烛火焰的HTML和CSS代码。它创建了一个具有动态效果的蜡烛火焰动画&#xff0c;包括火焰的摆动、伸缩和光晕的闪烁。 HTML <div class"holder"><div class"candle"><div class"blinking-glow"&g…

vue3【实战】切换全屏【组件封装】FullScreen.vue

效果预览 原理解析 使用 vueUse 里的 useFullscreen() 实现 代码实现 技术方案 vue3 vite UnoCSS vueUse 组件封装 src/components/FullScreen.vue <template><component:is"tag"click"toggle":class"[!isFullscreen ? i-ep:full-sc…

GPT-5 要来了:抢先了解其创新突破

Microsoft 的工程师计划于 2024 年 11 月在 Azure 上部署 Orion (GPT-5)。虽然这一版本不会向公众开放&#xff0c;但其上线被视为人工智能领域的一个重要里程碑&#xff0c;并将产生深远的影响。 文章目录 GPT-5 真的要来了GPT-4 的局限性GPT-5 的创新突破与遗留挑战GPT-5 预期…

C++【深入项目-检测键盘】

神马是检测键盘&#xff0c;就是让编辑器可以检测键盘按下了什么按键&#xff0c;我们先科普复习检测键盘 。 检测键盘需要用到一些函数&#xff0c;请见下&#xff1a; ! KEY_DOWN( 80 ) 这个代码是检测按下键盘上P按键。那80是什么&#xff1f;原来是对应按键的&#xff0…

springboot的依赖实现原理:spring-boot-starter-parent解析

01 dependencyManagement的作用 在使用springboot时我们会在项目pom引入以下配置和依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.18</version> &l…

Thinkphp6视图介绍

一.MVC MVC 软件系统分为三个基本部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#xff09; ThinkPHP6 是一个典型的 MVC 架构 控制器—控制器&#xff0c;用于将用户请求转发给相应的Model进行处理&a…

【idea】更换快捷键

因为个人习惯问题需要把快捷键替换一下。我喜欢用CTRLD删除一下&#xff0c;用CTRLY复制一样。恰好这两个快捷键需要互换一下。 打开file——>setting——>Keymap——>Edit Actions 找到CTRLY并且把它删除 找到CTRLD 并且把它删除 鼠标右键添加CTRLY 同样操作在Delet…

Tiktok对接和内容发布申请流程

这段时间在搞AI生成视频&#xff0c;希望用户能一键发布到Tiktok&#xff0c;因此研究了一下Tiktok的开发者申请流程&#xff0c;发现好复杂&#xff0c;同时也发现Tiktok的开发也跟我一样&#xff0c;挺草台班子的 0、流程简述 废话不多说&#xff0c;Tiktok的开发者申请和…

[刷题]入门1.矩阵转置

博客主页&#xff1a;算法歌者本篇专栏&#xff1a;[刷题]您的支持&#xff0c;是我的创作动力。 文章目录 1、题目2、基础3、思路4、结果 1、题目 链接&#xff1a;洛谷-B2106-矩阵转置 2、基础 此题目主要考察二维数组的掌控能力。 3、思路 观察&#xff0c;可知&#…

ODC 如何精确呈现SQL耗时 | OceanBase 开发者工具解析

前言 在程序员或DBA的日常工作中&#xff0c;编写并执行SQL语句如同日常饮食中的一餐一饭&#xff0c;再寻常不过。然而&#xff0c;在使用命令行或黑屏客户端处理SQL时&#xff0c;常会遇到编写难、错误排查缓慢以及查询结果可读性不佳等难题&#xff0c;因此&#xff0c;图形…

大数据学习15之Scala集合与泛型

1. 概述 大部分编程语言都提供了数据结构对应的编程库&#xff0c;并称之为集合库(Collection Library)&#xff0c;Scala 也不例外&#xff0c;且它还拥有以下优点&#xff1a; 易用&#xff1a;灵活组合运用集合库提供的方法&#xff0c;可以解决大部分集合问题 简洁&#xf…

Linux网络——网络初识

目录 1. 认识协议 2. 协议的分层 3. OSI 七层模型 && TCP/IP 五层(四层)模型 4. 网络传输的基本流程 5. 以太网的通信原理 6. 数据的跨网络传播 7. 认识 IP 地址 ① IP 是什么 ② IP 与 MAC 的关系 ③ 为什么需要 IP 在谈及网络之前&#xff0c;我们要先对学…

数字IC后端低功耗设计实现案例分享(3个power domain,2个voltage domain)

下图所示为咱们社区T12nm A55低功耗实现项目。其实这个项目还可以根据产品的需求做一些改进。改进后项目实现的难度会大大增加。也希望通过今天的这个项目案例分享&#xff0c;帮助到今年IC秋招的同学。 芯片低功耗设计实现upf编写指南&#xff08;附低功耗项目案例&#xff0…

Ubuntu从入门到精通(一)系统安装

Ubuntu从入门到精通&#xff08;一&#xff09; 1 Ubuntu镜像选择 下载Ubuntu 20.04系统ISO镜像 安装 Ubuntu 20.04系统,就必须有 Ubuntu 20.04系统软件安装程序可以通过浏览器访问Ubuntu20.04的官方站点&#xff0c; 然后在导舰栏找划 Dowwnloads->Mirrors链接&#xff…

说说软件工程中的“协程”

在软件工程中&#xff0c;协程&#xff08;coroutine&#xff09;是一种程序运行的方式&#xff0c;可以理解成“协作的线程”或“协作的函数”。以下是对协程的详细解释&#xff1a; 一、协程的基本概念 定义&#xff1a;协程是一组序列化的子过程&#xff0c;用户能像指挥家…

【linux】进程等待与进程替换

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.进程等待系统调用获取子进程status常用宏使用示例 02.进程替换替换函数关键点解释&#xff1a;代码详细分析execvpe 函数的使用 01.进程等待 任何子进程&#xff0c;在退出的…