[关闭]
@yanglfyangl 2018-06-01T03:58:59.000000Z 字数 2192 阅读 559

支持引擎之 -- 统计分析引擎

需求简述

统计分析引擎的由来主要是为了支持各种复杂的统计及分析需求。

主要的统计维度有:

  • 按时间统计(固定日期。。。最近几天。。。)
  • 按状态统计(各种状态)
  • 按类型统计(各种类型)
  • 按位置统计(城市/区。。。)
  • 按阶段(时间阶段,人数阶段,活跃值阶段。。。)
  • ......

主要的排序维度有:

  • 按时间
  • 按人数
  • 按位置或距离
  • 按等级
  • ......

还需要支持变化统计:

  • 等级 变化列表
  • 趣豆 变化列表
  • XXX 变化列表

实现方式

类定义

  1. class TimeSatisQueryVo:{
  2. public String KEY;
  3. public Date startTime;
  4. public Date endTime;
  5. }
  6. class TagSatisQueryVo:{
  7. public String KEY;
  8. public Date startTime;
  9. public Date endTime;
  10. }
  11. 。。。。。。
  12. class AnalysisEngine:{
  13. //初始化部分
  14. public void getInstance(){};
  15. public void loadRules(){}; // 注:如果Rules发生变化,可能会导致数据重新处理,慎重。
  16. //数据更新部分
  17. public void addOrUpdateData(T){};
  18. public void deleteData(String ID){};
  19. //数据统计部分
  20. public List<T> queryStatistics(){}; //
  21. public List<T> queryOrder(){}; //
  22. public List<T> queryChanges(){}; //
  23. public List<T> complexQuery(){}; //复杂查询。(能支持的就是基于上面的查询的交并集)
  24. }

调用示例

初始化配置文件

  1. {
  2. "statistics":[
  3. {
  4. key:""
  5. type:"TIME" //如果是时间,则每天的结果计算后放到一起。
  6. field:"" //指DTO或Map中对应的字段名。
  7. },
  8. {
  9. type:"TAG"
  10. field:""
  11. }
  12. ],
  13. "Order":[
  14. {
  15. type:"TIME" //如果是时间,每天的数据放到一起。
  16. field:""
  17. },
  18. {
  19. type:"POSITION"
  20. field:""
  21. },
  22. "Changes":[
  23. {
  24. type:"TIME" //如果是时间,每天的数据放到一起。
  25. Interval:"Week" // 每周的
  26. field:""
  27. },
  28. }

数据传入引擎

  1. //对于每个输入Bean,需要对应一个分析引擎。
  2. Class CrowdAnalysisEngine:{
  3. void example(){
  4. AnalysisEngine.Load(BeanCrowdAnalysisJson);
  5. AnalysisEngine.addOrUpdateData(userBean);
  6. AnalysisEngine.deleteData(userBean.getID());
  7. }
  8. }

addOrUpdateData的逻辑

  1. public addOrUpdateData(){
  2. for (statistics list) {
  3. if(type == "TIME"){
  4. //主要逻辑是按规则将数据按天进行统计。
  5. //这样获取过去多少天,或更复杂的统计的时候,就可以进行简单的加减法就可以了。
  6. //key值的定义
  7. String key = "statistics" + "Today Date"+ [item].field;
  8. value = KVDB.getKey(key);
  9. KVDB.setValue(key, value + [item].field.data);
  10. }
  11. if(type == "TAG"){
  12. //主要逻辑是按规则将数据按标签进行计算并存储。
  13. //key值的定义
  14. String key = "Order" + [item].field;
  15. value = KVDB.getKey(key);
  16. KVDB.setValue(key, value + [item].field.data);
  17. }
  18. }
  19. for (Order list) {
  20. 和上面的逻辑基本是一样的。
  21. }
  22. for (Change list) {
  23. if(type == "TIME" && intervel == "week") {
  24. //主要逻辑是将数据每周都存一份到zset中,获取数据时取交集。
  25. //如果数据量过大的话,则批量交给Spark处理,处理的结果存在KV库中。
  26. //key值的定义
  27. String key = "Order" + [item].field;
  28. value = KVDB.getKey(key);
  29. KVDB.setValue(key, value + [item].field.data);
  30. }
  31. }
  32. }

query的逻辑

  1. public List<String> queryStatistics(TimeSatisQueryVo vo){
  2. //根据Vo找出对应的Key来;
  3. //根据Vo找出对应的时间来。
  4. //如果需要取出多个后相加,则相加。
  5. //计算结果返回给前端。
  6. }
  7. public List<String> complexQuery(List<QueryVo> voList){
  8. // 复杂查询就是根据各种vo来进行查询(并行查询)
  9. // 查询的结果还是放到存到缓存中的
  10. // 进行并集操作
  11. }

基本实现逻辑

最核心的实现逻辑是:

  • 对每个配置的项,存到不同K-V set或zSet中,取的时候,直接取(用空间换时间)
  • 将基本数据按ID存一份,一旦出现配置项改变的情况,则基于基础数据重新生成一份。
  • 对于复杂查询,简化成简单查询后,通过交并集操作来进行。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注