当前位置: 首页 > article >正文

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());

在这里插入图片描述


http://www.kler.cn/a/398781.html

相关文章:

  • 云原生之运维监控实践-使用Telegraf、Prometheus与Grafana实现对InfluxDB服务的监测
  • ARM(安谋) China处理器
  • 嵌入式硬件杂谈(二)-芯片输入接入0.1uf电容的本质(退耦电容)
  • 从零到一:利用 AI 开发 iOS App 《震感》的编程之旅
  • Bugku CTF_Web——No one knows regex better than me
  • 力扣刷题日记之150.逆波兰表达式求值
  • Adobe Illustrator(Ai)修图软件入门操作参考,收集查过的各个细节用法
  • 第十六届蓝桥杯模拟赛(第一期)-c++/c
  • [Qt platform plugin问题] Could not load the Qt platform plugin “xcb“
  • CSS优化file控件样式
  • 【动手学深度学习Pytorch】1. 线性回归代码
  • [CKS] 执行Pod安全标准
  • 酒水分销积分商城小程序开发方案php+uniapp
  • go module使用
  • 使用win32com将ppt(x)文件转换为pdf文件
  • 【windows】校园网AP隔离解决方案笔记-解决校内设备之间无法互相通信的臭毛病-附破解程序
  • CC2学习记录
  • Rust: 原子操作大全
  • antdesign对话框输出html格式
  • RHCE的学习(21)
  • Nuget For Unity插件介绍
  • Hadoop的汽车销量数据分析系统
  • Linux 实现TCP并发服务器
  • 大模型呼叫中心,如何建设呼入机器人系统?
  • Ceph后端两种存储引擎介绍
  • FreeRTOS学习13——任务相关API函数