企业中的聚合逻辑是怎么实现的

设计与分析

先说需求:公司对接的客户要客制化的数据,我们要写接口从Solr中查询出数据,然后同标聚合

由于公司有写好的Solr查询的数据平台,直接使用数据平台导出对应时间的数据,然后我们查表进行处理

以结果为导向,客户需要每一条标文中的招标单位是否首次招标,还是需要Solr查询,只是数据平台不能满足

以此,来抽离出一个接口专门查询每一条标文中的招标单位是否首次查询

是否首次招标接口

此接口来根据标文中的招标单位查询Solr中是否有对应记录,有则不是首次招标

来写代码:

less 复制代码
     @GetMapping(value = "baoLiFirstTender")
     @ApiOperation(value = "数据首次招标", notes = "数据首次招标")
     @ResponseBody
     public void baoLiFirstTender(@RequestParam(value = "tableName") String tableName) {
         paoShuJuService.baoLiFirstTender(tableName);
     }
ini 复制代码
     /**
      * 数据处理
      * @param tableName
      */
     public void baoLiFirstTender(String tableName) {
         String gid = "0";
         List<PaoShujuEntity> paoShujuEntities = new ArrayList<>();
         //查询数据
         List<JSONObject> list = paoShuJuMapper.getData(tableName, gid);
         paoShujuEntities = JSONObject.parseArray(JSON.toJSONString(list), PaoShujuEntity.class);
         List<String> tenderList = paoShujuEntities.stream().map(PaoShujuEntity::get招标单位).distinct().collect(Collectors.toList());
         get首次招标(tenderList);
     }

拿到数据平台所有的标文中的招标单位去进行查询,写入Mongo中,get首次招标(tenderList)代码逻辑过长,单独抽离出来:

ini 复制代码
     private void get首次招标(List<String> tenderList){
         SolrClient solrClient = SpringContextHolder.getBean(OPPRTUNITY_BASE_ALL, SolrClient.class);
         SolrQuery solrQuery = new SolrQuery();
         solrQuery.setQuery("projectType:4");
         List<TenderCidEntity> entityList = new ArrayList<>();
         for (String 招标单位 : tenderList) {
             String sign = get是否首次招标(solrQuery, solrClient, 招标单位, null, null);
             TenderCidEntity entity = new TenderCidEntity();
             entity.set招标单位(招标单位);
             entity.set标文id(sign);
             entityList.add(entity);
             if (entityList.size() > 200){
                 mongoTemplate.insert(entityList, "北京数据");
                 entityList.clear();
             }
         }
         mongoTemplate.insert(entityList, "北京数据");
     }

对每一条招标单位进行Solr查询,然后封装实体,追加到集合中,然后200为一组插入Mongo数据库

聚合接口

需求:根据标文信息同标聚合,转换为需要的数据

less 复制代码
     @GetMapping(value = "baoLi")
     @ApiOperation(value = "保利数据导出", notes = "保利数据导出")
     @ResponseBody
     public void baoLi(@RequestParam(value = "tableName") String tableName) {
         paoShuJuService.baoLi(tableName);
     }

关键代码:

arduino 复制代码
             Map<String, List<PaoShujuEntity>> map = paoShujuEntities.stream().collect(Collectors.groupingBy(PaoShujuEntity::get项目id));
 ​

先根据项目id聚合成一个map进行处理

scss 复制代码
  map.forEach((gid, list) ->{
       getFieldsValue(paoShujuEntity, filedMap);
       get通用规则(filedMap, paoShujuEntity, list);
  })
typescript 复制代码
 //根据每一条标文数据实体,通过反射拿到其属性和对应的值(多个值是因为同一个项目id下的多个标文id,标文id即这个数据实体)
 public static void getFieldsValue(PaoShujuEntity obj, Map<String, List<Object>> filedMap) {
     //拿到实体的class对象
     Class<? extends PaoShujuEntity> objClass = obj.getClass();
     //拿到class对象的的所有属性(包括私有属性)
     Field[] fields = objClass.getDeclaredFields();
     for (Field field : fields) {
         //反射对象在使用时抑制Java语言访问检查(私有也可以访问),使得可以获取属性值
         field.setAccessible(true);
         String name = field.getName();
         Object fieldValue = field.get(obj);
     }
 }

拿到每一个项目id下的所有标文实体的属性和其对应的值后,进行通用规则处理,按照值出现最多的来作为最终的val值:

typescript 复制代码
     private void get通用规则(Map<String, List<Object>> filedMap, PaoShujuEntity paoShujuEntity, List<PaoShujuEntity> list){
         Set<Map.Entry<String, List<Object>>> entries = filedMap.entrySet();
         //公共方法set属性值
         for (Map.Entry<String, List<Object>> entry : entries) {
             String key = entry.getKey();
             List<Object> value = entry.getValue();
             //计算每一个属性值出现的次数
             Map<String, Integer> oneFieldMap = getOneFieldMap(value);
             //按照次数最多确定最终val值
             Object finalValue = getFinalFiledValue(oneFieldMap, list);
             if (finalValue == null) {
                 continue;
             }
             //反射属性赋值
             setObject(key, finalValue, paoShujuEntity);
         }
     }

所以总结:就是根据项目id聚合,然后将同一个项目id下的所有标文id取的是出现次数最多的一个作为最终的值

相关推荐
舒一笑19 分钟前
如何优雅统计知识库文件个数与子集下不同文件夹文件个数
后端·mysql·程序员
IT果果日记20 分钟前
flink+dolphinscheduler+dinky打造自动化数仓平台
大数据·后端·flink
Java技术小馆31 分钟前
InheritableThreadLoca90%开发者踩过的坑
后端·面试·github
寒士obj41 分钟前
Spring容器Bean的创建流程
java·后端·spring
数字人直播2 小时前
视频号数字人直播带货,青否数字人提供全套解决方案!
前端·javascript·后端
shark_chili2 小时前
提升Java开发效率的秘密武器:Jadx反编译工具详解
后端
武子康2 小时前
大数据-75 Kafka 高水位线 HW 与日志末端 LEO 全面解析:副本同步与消费一致性核心
大数据·后端·kafka
YANGZHAO2 小时前
Docker零基础入门:一文搞定容器化核心技能
后端·docker
字节跳跃者2 小时前
SpringBoot + MinIO + kkFile 实现文件预览,这样操作更安全!
java·后端·程序员
我是哪吒2 小时前
分布式微服务系统架构第167集:从零到能跑kafka-redis实战
后端·面试·github