添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

已知es中存储了一张学生课程信息宽表,里边包含有student_name、student_id、teacher_id、课程信息等字段。

现在根据学生姓名或者班级ID,得出学生所在班级的所有授课教师信息。

2、需求分析

既然是明细宽表,里边的教师的信息必然是有重复的,因此我们需要查询teacher_id的集合并去重,对teacher_id实现SQL中的distinct或group by操作。然后再拿着查询出的不重复的teacher_id集去教师表查询每个教师的相关信息。

2、解决思路

方式(1)字段aggs与top_hits:在内存中完成操作,性能损耗大

方式(2)collapse折叠:性能高,api操作简单

方式(1)有损性能,不推荐使用,下边是方式(2)为的操作代码

二、操作示例

下边是JSON查询语句,must指定匹配条件,includes查询指定字段,collapse指定去重字段

1、原生的JSON格式

"query": { "bool": { "must": [{ "term": {"status": {"value": 1}} "bool": { "should": [{ "term": { "student_name": {"value": "zhangsan" }} "terms": {"class_id": [101]} "_source": { "includes": ["teacher_id"], "excludes": [] "collapse": {"field": "teacher_id"}

2、Java语言的API

Java的API参考关键代码示例如下:

    public List<String> queryTeacherIds(List<Long> classIds, String studentName) {
    	List<String> idList = new ArrayList<>();
    		//自行获取客户端连接
            RestHighLevelClient client = esConf.getClient();
            BoolQueryBuilder mustBoolQueryBuilder = QueryBuilders.boolQuery();
            mustBoolQueryBuilder.must(QueryBuilders.termQuery("status", 2));
            BoolQueryBuilder shouldBoolQueryBuilder = QueryBuilders.boolQuery();
            if(CollectionUtils.isNotEmpty(classIds)){
            	shouldBoolQueryBuilder.should(QueryBuilders.termsQuery("class_id", classIds));
            if(StringUtils.isNotBlank(studentName)){
            	shouldBoolQueryBuilder.should(QueryBuilders.termsQuery("student_name",studentName));
            mustBoolQueryBuilder.must(shouldBoolQueryBuilder);
            String teacherId = "teacher_id";
            String [] includes = {teacherId};//指定查询哪些字段
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(mustBoolQueryBuilder).fetchSource(includes,null).collapse(new CollapseBuilder(teacherId));
            SearchRequest searchRequest = new SearchRequest(erpIndex).source(sourceBuilder);
            logger.info("searchRequest:{}", searchRequest.toString());
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            logger.info("searchResponse:{}", searchResponse.toString());
            if(searchResponse!=null && searchResponse.getHits().getHits().length > 0){
                SearchHits searchHits = searchResponse.getHits();
                SearchHit[] hits = searchHits.getHits();
                for(SearchHit hit:hits){
                    Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                    Object teacherIdObj = sourceAsMap.get(teacherId);
                    idList.add(String.valueOf(teacherIdObj));
        }catch ( Exception e){
            logger.error("getPopAllowanceIds err{}",e);
            Profiler.businessAlarm("AllowanceSkuEsServiceImpl.querySkuByPage.Exception", String.format("getErpAllowanceIds查询es出错:%s", e));
    	return idList;
				
假如我们有一个需要选择的对象,它有两个参数来唯一确定这个对象:vport和vip(一个vip可以对应多个vport), 除此之外,还有feature_type类型,set_info集群信息,cdate日期,feature_data特征值(数字) 我们的目标是选择出一段时间内,某个类型,某个set_info下的每个vip和vport标识对象的平均特征值。所以我们需要: 1.用query来筛选指定的某...
如果我们想在es实现sql 中的group by的查询统计效果 SELECT COUNT(id) FROM patientstudy GROUP BY hospitalId; 在kibana中执行命令 POST /patientstudy/_search?size=0 "aggs" : { "count" : { "terms" : { "field" : "hospitalId" } } 用java怎么实现
一、背景介绍 问题一:如何对elasticsearch的检索结果进行去重统计计数。类似mysql 的 select count(*) from a group by b。 问题二:如何对elasticsearch的检索结果去重后显示。类似mysql 的select distint(“name”) from a group by b。 ​ 统计计数需要借助elasticsearc...
ES从6.3开始已经支持SQL了,当然还有很多不完善的地方,比如对于嵌套查询,连表查询,但是对于单表而言,提供的SQL已经基本够用了。 这里只讲一下我在实际业务中遇到的一个问题,运营那边想要对时间进行分组查询,可以按年或是月或是日进行分组,为了能满足运营那边的要求,自己研究了一下在ESgroup by的使用方式。 首先当然是网上google了一下,看看有没有现成的资料可以用一下,找了半天发现...
SELECT DISTINCT field1,field2 FROM test_index.test_type SELECT field1,field2 FROM test_index.test_type GROUP BY field1,field2 2.而group by的查询,在es中我们可以用Aggregation(聚合)去实现,等价的DSL查询...
最近在使用es查询某个字段在特定查询条件下的某个字段的求和时,忘记了query语句是怎么写的,简单记录一下,方便自己和他人查阅。 一 什么是elasticsearchelasticsearch是一个分布式的使用 REST 接口的搜索引擎,简称为ES,它是面向文档的,可以存储整个对象或文档。 二:elasticsearch的几种操作 1对某个字段求和,相当于sql语句的: selectsum(字段名)fromtablewhere条件1 and 条件2 #对某个字段求和操作
上一篇我们总结了如何将MySQL的数据实时同步到Elasticsearch中,这一篇我们来总结一下当数据同步到Elasticsearch中后,如何使用Java API对Elasticsearch进行复杂查询,但实际工作中还没有遇到过特别复杂的SQL如何转化到Elasticsearch中,当然遇到这种情况一种解决方式是将数据库的查询结果直接存到一张表中,然后在Elasticsearch建立对应的索引,再对该索引进行查询;当然更直接的就是编写复杂的Java代码实现查询,这种情况我也还没有遇到。 前面我们已经讲过
public int getDailyLeaseBike2(OperateAreasBo operateArea, String type, String type1, Long stime, Long etime, String queryDateField) { BoolQuery...