java中使用ElasticSearch聚合查询代码实例(个人笔记,不喜勿喷)

PS→无奈:拥有梦想只是一种智力,实现梦想才是一种能力。

空闲之余就把先前做过的一个通过ElasticSearch的聚合来实现查询当月实际签到的天数记录一下,纯留下点记忆,大家勿喷

1.如果不了解elsticsearch聚合的概念可以自行网上查看一番,起码懂得概念以及使用方法。
我们的业务是需要查看某个人某个月的签到天数,不管一天签到多少次,只计算一次。根据签到天数计算获取的补贴数据入库。
elasticsearch依赖:

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-elasticsearch</artifactId>
	<version>3.0.0.RELEASE</version>
</dependency>
补贴入库接口:
/**
      * @Author: Qzli
      * @Description: 补贴入库接口
      * @Date: Create by 2018/12/10 13:23
      * @return:
      */
    @RequestMapping("/saveAllowance")
    public R saveAllowance(@RequestParam Map<String, Object> params){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        String organizationName = String.valueOf(params.get("organizationName"));  //调用方传过来的学校名称  例:蘑菇丁体验学院
        String organizationCode = String.valueOf(params.get("organizationCode"));  //调用方传过来的学校code  例:88888
        String roleType = String.valueOf(params.get("roleType"));  //调用方传过来的角色  例:student
        if(StringUtils.isEmpty(organizationName)){
            return R.error(SystemErrorCode.DATA_NOTHADE.getCode(),"学校名称不能为空");
        }
        if(StringUtils.isEmpty(organizationCode)){
            return R.error(SystemErrorCode.DATA_NOTHADE.getCode(),"学校CODE不能为空");
        }
        if(StringUtils.isEmpty(roleType)){
            return R.error(SystemErrorCode.DATA_NOTHADE.getCode(),"角色不能为空");
        }
        // 获取当前日期  例:2018-10
        Date now = new Date();
        Map<String, Integer> maps = DateUtils.getMonthInfo(now);  //获取当前月的工作日(不考虑节假日的情况下)
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int days = maps.get("workDaysAmount");  //获取当前月的工作日(不考虑节假日的情况下)
        String dateTime = format.format(now);
        String sst = dateTime+"-01";
        SimpleDateFormat sDateFormat=new SimpleDateFormat(DateUtils.DATE_PATTERN);
        Date sdate = null;  //开始日期
        try {
            sdate = sDateFormat.parse(sst);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date edate = DateUtils.addDateMonths(sdate,1);  //结束日期
        List<UserIndex> userIndexList = queryLikeUserInfo.searchStudentList(organizationName,organizationCode,roleType);//获取深职院的学生
        int count=0;
        int count1=0;
        boolean flag;
        for(int i = 0;i<userIndexList.size();i++){//循环获取学生
            GxyStudentAllowanceEntity gae = new GxyStudentAllowanceEntity();
            gae.setYear(BigDecimal.valueOf(year));  //年份
            gae.setMonth(BigDecimal.valueOf(month));//月份
            gae.setPfId(userIndexList.get(i).getPfid());//学生pfid
            gae.setSyncFlag(BigDecimal.valueOf(0));//同步标记
            gae.setStandardWorkingDay(BigDecimal.valueOf(days));// 标准工作日天数
            if (gae.getPfId()!=null){  //判断该学生的pfid是否为空
                //从es里获取签到天数(不排除周末以及是否上下班等等)
                int signCount = queryLikeUserInfo.querySign(gae.getPfId(),"practiceSign",DateUtils.formatTo(sdate),DateUtils.formatTo(edate),"1").intValue();
                // 从es里面获取计入补贴的实际工作天数
                int workCount = queryLikeUserInfo.querySign(gae.getPfId(),"practiceSign",DateUtils.formatTo(sdate),DateUtils.formatTo(edate),"2").intValue();
                if(workCount>days){  //判断实际工作天数是否大于正常工作日天数
                    gae.setActualWorkingDay(BigDecimal.valueOf(days)); //实际工作日天数
                }else{
                    gae.setActualWorkingDay(BigDecimal.valueOf(workCount));  //计入补贴的实际工作天数
                }
                gae.setSignCount(BigDecimal.valueOf(signCount));  //学生总共签到的天数(不排除周末以及是否上下班等等)
                int sum = 650*workCount;
                long allowance = Math.round((sum+0.0)/days);  //应发补贴算法
                gae.setAllowance(BigDecimal.valueOf(allowance)); //应发补贴
            }else{  // 为空的话就是未绑定用户 都默认设置为0
                gae.setSignCount(BigDecimal.valueOf(0));
                gae.setActualWorkingDay(BigDecimal.valueOf(0));
                gae.setAllowance(BigDecimal.valueOf(0));
            }
            // 根据年、月、学生pfid  验证数据库是否存在
            GxyStudentAllowanceEntity entity = gxyStudentAllowanceService.selectOne(new EntityWrapper<GxyStudentAllowanceEntity>()
                    .eq("YEAR",gae.getYear())
                    .eq("MONTH",gae.getMonth())
                    .eq("PF_ID",gae.getPfId()));
            if (entity!=null){
                flag = gxyStudentAllowanceService.update(gae,new EntityWrapper<GxyStudentAllowanceEntity>()
                        .eq("GXY_STUDENT_ALLOWANCE_ID",entity.getGxyStudentAllowanceId()));
                if(flag){
                    count++;
                }
            }else{
                flag = gxyStudentAllowanceService.insert(gae);
                if(flag){
                    count1++;
                }
            }
        }
        logger.info("更新:"+count+"条记录");
        logger.info("插入:"+count1+"条记录");
        return R.ok();
    }

从es里获取签到天数:

/**
      * @Author: Qzli
      * @Description: 根据用户id、类型(签到)、开始时间、结束时间 到es里面查询签到天数
      * @Date: Create by 2018/11/28 14:26
      * @param: 签到天数
      * @return:
      */
    public Long querySign(String userId,String type,String startTime,String endTime,String flag) {
        // 测试一把  https://blog.csdn.net/qq_28988969/article/details/81565765
        AggregationBuilder aggregationBuilder = AggregationBuilders.dateHistogram("dayAgg")  //聚合名字
                .field("publishtime")       // 需要聚合分组的字段名称, 类型需要为date, 格式没有要求
                .dateHistogramInterval(DateHistogramInterval.DAY)     // 按什么时间段聚合, 这里是按月份, 可用的interval在上面给出
                .format("yyyy-MM-dd")   // 返回值格式化
                .minDocCount(0L);       // 为空的话则填充0,强制返回所有 buckets,即使 buckets 可能为空。
//                .extendedBounds(new ExtendedBounds("2018-10-01", "2018-11-01"));//为了得到全月数据,我们需要告诉 Elasticsearch 我们想要全部 buckets, 即便那些 buckets 可能落在最小日期 之前 或 最大日期 之后
        SearchRequestBuilder searchRequestBuilder = null;
        if("1".equals(flag)){  //1:计算总的签到天数(不排除周末以及是否上下班等等)
            searchRequestBuilder = elasticsearchTemplate.getClient()
                    .prepareSearch("article")  //索引名
                    .setTypes("json")               //索引类型
                    .setSize(0)                   // 不显示具体的内容
                    .setQuery(boolQuery()
                            .must(QueryBuilders.matchPhraseQuery("pfid", userId))           //用户id
                            .must(QueryBuilders.matchPhraseQuery("formtype", type))         //类型为签到
                            .must(QueryBuilders.rangeQuery("orderbytime").from(startTime).to(endTime)))
                    .addAggregation(aggregationBuilder);
        }else{  //2:计算实际出勤天数
            searchRequestBuilder = elasticsearchTemplate.getClient()
                    .prepareSearch("article")  //索引名
                    .setTypes("json")               //索引类型
                    .setSize(0)                   // 不显示具体的内容
                    .setQuery(boolQuery()
                            .must(QueryBuilders.matchPhraseQuery("pfid", userId))           //用户id
                            .must(QueryBuilders.matchPhraseQuery("formtype", type))         //类型为签到
                            .must(QueryBuilders.boolQuery()
                                    .should(QueryBuilders.matchPhraseQuery("tagarray", "$mgonwork$"))//签到类型为上班
                                    .should(QueryBuilders.matchPhraseQuery("tagarray", "$mgoffwork$"))  //或者为下班mgoffwork
                                    .should(QueryBuilders.matchPhraseQuery("tagarray", "$mglegwork$")))  //或者为外勤mglegwork
                            .must(QueryBuilders.matchPhraseQuery("tagarray", "$1$"))  //已确认的签到
                            .must(QueryBuilders.rangeQuery("orderbytime").from(startTime).to(endTime)))
                    .addAggregation(aggregationBuilder);
        }
        SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();  //执行查询
        Aggregations aggs = searchResponse.getAggregations(); //聚合
        Histogram agg = aggs.get("dayAgg");  //获取聚合自定义名称
        long count = 0;  //计入补贴的签到天数
        for (Histogram.Bucket entry : agg.getBuckets()) {
            System.out.println(entry.getKeyAsString() + "签到" + entry.getDocCount() + "次");
            if (entry.getDocCount()>0){
                count++;
            }
        }
            return count;
        }

elasticsearch客户端连接代理插件:putty 

代理说明:

127.0.0.1:9300 --> 114.215.66.118 --> 120.27.26.68:9300
最终在你代码本地使用127.0.0.1:9300这个地址来访问es
用es head就一样的配置9200
第一步  在《会话》中添加 114.215.66.118     端口: 22
第二步  在《通道》中添加 120.27.26.68:9300    120.27.26.68:9200
点击添加 
最后点打开  输入账号,密码就登录进来了。

然后本地就可以访问了,启动修改本地es地址 ;

es查看用的是es_site来查看(打开es_site——点击index.html):

以下数据是在测试服的一些测试数据:(查看es数据更为直观,也可以用条件查询来判断代码查询数据是否正确)

这个没有什么直观的效果。鄙人自己做个备忘录。望大神们勿喷

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值