一、配景
课程管理界面,查询前,必要把查询元数据给出。
学科列表、学段列表和分类列表,我们把它界说为查询元数据。
一样平常的业务需求是:
体系维护许多多少个字典,比如学科、学段等等,相当于属性库。
但是,这有一个不友爱的地方,字典列表数据过多,比如学段字典包罗了幼儿园和大学等,而现实上,课程只有初中或高中,连小学学段也没有。
如许展示的学段列表,就显得数据冗余,增长选择的干扰。
修改后的需求:
基于已有课程的属性,举行去重查询出学科列表等数据,也即上文提到的查询元数据。(已非原始字典)
比如说,我创建了一个课程,它是数学科目,初中学段,那么查询列表中的学科列表就只有数学一个值,学段列表只有初中一个值。
后期创建了一个化学科目标高中课程,此时学科列表就有数学和化学两个学科,学段包罗初中和高中。
二、es索引
- @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聚合查询
- 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;
- }
- }
复制代码 四、调用示例
- // 科目列表
- 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());
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |