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());
相关推荐
QYR_111 分钟前
机器人定位器市场报告:2025-2031 年行业增长逻辑与投资机遇解析
大数据·人工智能
StarRocks_labs2 分钟前
StarRocks 助力印度领先即时零售平台 Zepto 构建实时洞察能力
大数据·starrocks·clickhouse·存算一体·postgres mvp
我是华为OD~HR~栗栗呀9 分钟前
前端面经-高级开发(华为od)
java·前端·后端·python·华为od·华为·面试
城管不管22 分钟前
Java EE、Java SE 和 Spring Boot
java·spring boot·java-ee
xdpcxq102923 分钟前
EF Core框架数据库连接管理
java·jvm·数据库
熙客25 分钟前
分布式ID解决方案
java·分布式·spring cloud·微服务
大数据CLUB29 分钟前
基于hive和mapreduce的地铁数据分析及可视化_hive作为数据库
大数据·hive·hadoop·分布式·数据分析·mapreduce
说私域1 小时前
蒸汽机革命后工业生产方式的变革与AI智能名片S2B2C商城小程序的影响
大数据·人工智能·小程序
菜鸟小九1 小时前
SSM(MybatisPlus)
java·开发语言·spring boot·后端
小样还想跑1 小时前
UniApp ConnectSocket连接websocket
websocket·elasticsearch·uni-app