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

设计与分析

先说需求:公司对接的客户要客制化的数据,我们要写接口从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取的是出现次数最多的一个作为最终的值

相关推荐
EatFan28 分钟前
一个二维码背后的系统设计:批次生成、绑定、扫码与数据统计怎么做?
java·后端·微信小程序·二维码·qrcode
石小石Orz33 分钟前
民间AI排行榜单新鲜出炉,Fable 5.1仅排第三
前端·后端·ai编程
小灰灰搞电子1 小时前
Rust Once 、OnceLock、LazyLock 一次性初始化详解
开发语言·后端·rust
我不会起名字3221 小时前
一天一道算法题(35):电话号码的字母组合
java·数据结构·后端·python·leetcode·go·回溯
星栈2 小时前
ADK-Rust 是什么?Rust 生态新一代 AI Agent 开发套件
后端·agent
盖伦发发2 小时前
业务开发常用设计模式:状态、策略、工厂、适配器、模板方法
后端·软件工程
程序员老赵2 小时前
Docker 部署 XXL-JOB:轻松搭建分布式任务调度平台
后端·docker·开源
用户233376852182 小时前
Docker镜像找不到排障实录-CRLF跨平台暗雷
后端
程序员cxuan3 小时前
从 0 到 1 速通 WorkBuddy
人工智能·后端·程序员
薛定谔的算法3 小时前
M01:环境搭建与第一个 Java 程序
后端