JPA编程,去重查询ES索引中的字段,对已有数据的去重过滤,而非全部字典数据

一、背景

课程管理界面,查询前,需要把查询元数据给出。

学科列表、学段列表和分类列表,我们把它定义为查询元数据。

一般的业务需求是:

系统维护好多个字典,比如学科、学段等等,相当于属性库。

但是,这有一个不友好的地方,字典列表数据过多,比如学段字典包括了幼儿园和大学等,而实际上,课程只有初中或高中,连小学学段也没有。

这样展示的学段列表,就显得数据冗余,增加选择的干扰。

修改后的需求:

基于已有课程的属性,进行去重查询出学科列表等数据,也即上文提到的查询元数据。(已非原始字典)

比如说,我创建了一个课程,它是数学科目,初中学段,那么查询列表中的学科列表就只有数学一个值,学段列表只有初中一个值。

后期创建了一个化学科目的高中课程,此时学科列表就有数学和化学两个学科,学段包括初中和高中。

二、es索引

java 复制代码
@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 courseNo;

    /**
     * 创建者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 stage;
}

三、es聚合查询

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;

@Component
@RequiredArgsConstructor
public class CourseIndexAggrService {
    private final ElasticsearchRestTemplate elasticsearchRestTemplate;
    private static final String UNIQUE_FIELD = "unique_field";

    public static final String SUBJECT = "subject";
    public static final String STAGE = "stage";

    public List<String> findUniqueField(String uniqueField) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.filter(QueryBuilders.termQuery("deleted", LogicDeleteEnum.OK.ordinal()));
        queryBuilder.withQuery(boolQueryBuilder);

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

        queryBuilder.addAggregation(termsAgg);

        queryBuilder.withIndices("course_index");

        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;
    }
}

四、调用示例

java 复制代码
// 科目列表
final List<Integer> subjects = courseIndexAggrService.findUniqueField(SUBJECT).stream().map(v -> Integer.parseInt(v)).collect(Collectors.toList());

// 学段列表
final List<Integer> stages = courseIndexAggrService.findUniqueField(STAGE).stream().map(v -> Integer.parseInt(v)).collect(Collectors.toList());
相关推荐
一品威客网4 分钟前
App 软件制作的核心技术与方法:从架构到落地
架构
xixixi7777718 分钟前
基于零信任架构的通信
大数据·人工智能·架构·零信任·通信·个人隐私
思想在飞肢体在追24 分钟前
Springboot项目配置Nacos
java·spring boot·后端·nacos
cyforkk25 分钟前
09、Java 基础硬核复习:异常处理(容错机制)的核心逻辑与面试考点
java·数据库·面试
??(lxy)1 小时前
java高性能无锁队列——MpscLinkedQueue
java·开发语言
数研小生1 小时前
Full Analysis of Taobao Item Detail API taobao.item.get
java·服务器·前端
Hello.Reader1 小时前
Flink 自适应批执行(Adaptive Batch Execution)让 Batch 作业“边跑边优化”
大数据·flink·batch
Wang15301 小时前
Java编程基础与面向对象核心概念
java
毕设源码-郭学长1 小时前
【开题答辩全过程】以 康复管理系统为例,包含答辩的问题和答案
java
毅炼1 小时前
hot100打卡——day17
java·数据结构·算法·leetcode·深度优先