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

设计与分析

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

相关推荐
葫芦和十三1 小时前
图解 MongoDB 28|块与迁移:balancer 怎么均衡数据
后端
葫芦和十三1 小时前
图解 MongoDB 27|分片策略:范围分片 vs 哈希分片
后端·mongodb·agent
paopaokaka_luck2 小时前
英语单词学习系统的设计与实现(基于艾宾浩斯遗忘曲线的智能复习机制、语音朗读、多题型测试与错题自动收录、Echarts图形化分析)
vue.js·spring boot·后端·echarts
我叫黑大帅2 小时前
MySQL 并发插入竞态问题:原子写入实践指南
后端·mysql·面试
zhangxingchao3 小时前
AI大模型核心八:从 Agent Skill、长文档 RAG 到知识库更新与训练策略
前端·人工智能·后端
我叫黑大帅4 小时前
别再手动写 updated_at了,这坑我踩过
后端·面试·go
zhangxingchao4 小时前
AI大模型核心七:从 Workflow、RAG、记忆治理到幂等性
前端·人工智能·后端
犀利豆5 小时前
AI in Harness(二)
java·人工智能·后端
IT_陈寒5 小时前
Python装饰器竟然偷偷改了函数名?这个坑我爬了三天
前端·人工智能·后端
bkl_92136 小时前
GPT-Image-2 文生图:如何稳定生成完整的人物全身照?
后端·gpt·restful