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

[复制链接]
发表于 2025-10-19 22:50:00 | 显示全部楼层 |阅读模式
一、配景

课程管理界面,查询前,必要把查询元数据给出。
学科列表、学段列表和分类列表,我们把它界说为查询元数据。

一样平常的业务需求是:
体系维护许多多少个字典,比如学科、学段等等,相当于属性库。
但是,这有一个不友爱的地方,字典列表数据过多,比如学段字典包罗了幼儿园和大学等,而现实上,课程只有初中或高中,连小学学段也没有。
如许展示的学段列表,就显得数据冗余,增长选择的干扰。
修改后的需求:
基于已有课程的属性,举行去重查询出学科列表等数据,也即上文提到的查询元数据。(已非原始字典)
比如说,我创建了一个课程,它是数学科目,初中学段,那么查询列表中的学科列表就只有数学一个值,学段列表只有初中一个值。
后期创建了一个化学科目标高中课程,此时学科列表就有数学和化学两个学科,学段包罗初中和高中。
二、es索引
  1. @Data
  2. @Document(indexName = "#{commonConfig.courseIdx}", type = "_doc", shards = 1, refreshInterval = "-1")
  3. public class CourseIndex implements Serializable {
  4.     @Id
  5.     private String id;
  6.     /**
  7.      * 课程编号
  8.      */
  9.     @Field(type = FieldType.Keyword)
  10.     private String courseNo;
  11.     /**
  12.      * 创建者ID
  13.      */
  14.     @Field(type = FieldType.Long)
  15.     private long creatorId;
  16.     /**
  17.      * 课程名称
  18.      */
  19.     @Field(type = FieldType.Text)
  20.     private String name;
  21.    
  22.     /**
  23.      * 科目
  24.      */
  25.     @Field(type = FieldType.Integer)
  26.     private int subject;
  27.     /**
  28.      * 学段
  29.      */
  30.     @Field(type = FieldType.Integer)
  31.     private int stage;
  32. }
复制代码
三、es聚合查询
  1. import lombok.RequiredArgsConstructor;
  2. import org.elasticsearch.index.query.BoolQueryBuilder;
  3. import org.elasticsearch.index.query.QueryBuilders;
  4. import org.elasticsearch.search.aggregations.Aggregation;
  5. import org.elasticsearch.search.aggregations.AggregationBuilders;
  6. import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
  7. import org.elasticsearch.search.aggregations.bucket.terms.Terms;
  8. import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
  9. import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
  10. import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
  11. import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
  12. import org.springframework.stereotype.Component;
  13. import java.util.ArrayList;
  14. import java.util.List;
  15. @Component
  16. @RequiredArgsConstructor
  17. public class CourseIndexAggrService {
  18.     private final ElasticsearchRestTemplate elasticsearchRestTemplate;
  19.     private static final String UNIQUE_FIELD = "unique_field";
  20.     public static final String SUBJECT = "subject";
  21.     public static final String STAGE = "stage";
  22.     public List<String> findUniqueField(String uniqueField) {
  23.         NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
  24.         BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  25.         boolQueryBuilder.filter(QueryBuilders.termQuery("deleted", LogicDeleteEnum.OK.ordinal()));
  26.         queryBuilder.withQuery(boolQueryBuilder);
  27.         TermsAggregationBuilder termsAgg = AggregationBuilders.terms(UNIQUE_FIELD).field(uniqueField);
  28.         queryBuilder.addAggregation(termsAgg);
  29.         queryBuilder.withIndices("course_index");
  30.         AggregatedPage<CourseIndex> resultPage = elasticsearchRestTemplate.queryForPage(queryBuilder.build(), CourseIndex.class);
  31.         Aggregation aggregation = resultPage.getAggregation(UNIQUE_FIELD);
  32.         ParsedLongTerms terms = (ParsedLongTerms) aggregation;
  33.         // 获取桶
  34.         final List<? extends Terms.Bucket> buckets = terms.getBuckets();
  35.         // 提取唯一值
  36.         List<String> uniqueUserIds = new ArrayList<>();
  37.         for (Terms.Bucket bucket : buckets) {
  38.             uniqueUserIds.add(bucket.getKeyAsString());
  39.         }
  40.         return uniqueUserIds;
  41.     }
  42. }
复制代码
四、调用示例
  1. // 科目列表
  2. final List<Integer> subjects = courseIndexAggrService.findUniqueField(SUBJECT).stream().map(v -> Integer.parseInt(v)).collect(Collectors.toList());
  3. // 学段列表
  4. final List<Integer> stages = courseIndexAggrService.findUniqueField(STAGE).stream().map(v -> Integer.parseInt(v)).collect(Collectors.toList());
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表