statsBaseInfoService2.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. 'use strict';
  2. const Service = require('egg').Service;
  3. class StatsBaseInfoService2 extends Service {
  4. // 计算匹配的时间段下 过滤车型车系和驾驶模式后 两个维度分布下 数据之和 [x,y,z]
  5. async dece({ type, startTime, endTime, seriesCode, modelCode, mode }) {
  6. const { ctx } = this;
  7. const cond = [{ $match: {} }];
  8. if (seriesCode) {
  9. cond[0].$match['data._id.series_code'] = seriesCode;
  10. }
  11. if (modelCode) {
  12. cond[0].$match['data._id.model_code'] = modelCode;
  13. }
  14. const dict = ctx.helper.statusInfoDict.statsSpDeceCnt;
  15. const obj = {};
  16. const project = { data: [] };
  17. if (mode) {
  18. for (let j = 1; j < dict.superNum + 1; j++) {
  19. for (let i = 1; i < dict.num + 1; i++) {
  20. const key = dict.v.replace('=', j).replace('=', i);
  21. obj[`${j}${i}`] = { $sum: `$data.${dict.k}.${mode}.${key}` };
  22. project.data.push([ j - 1, i - 1, `$${j}${i}` ]);
  23. }
  24. }
  25. } else {
  26. for (let j = 1; j < dict.superNum + 1; j++) {
  27. for (let i = 1; i < dict.num + 1; i++) {
  28. const key = dict.v.replace('=', j).replace('=', i);
  29. const sumArr = dict.mode.map(item => {
  30. return `$data.${dict.k}.${item}.${key}`;
  31. });
  32. const sum = { $add: sumArr };
  33. obj[`${j}${i}`] = { $sum: sum };
  34. project.data.push([ j - 1, i - 1, `$${j}${i}` ]);
  35. }
  36. }
  37. }
  38. const agg = [
  39. { $match: ctx.helper.getTimeRangMatch(startTime, endTime) },
  40. { $unwind: '$data' },
  41. ...cond,
  42. { $group: { _id: null, ...obj } },
  43. { $project: project },
  44. ];
  45. const result = await ctx.model.Local.StatsBaseInfoModel2.aggregateNGroup(agg);
  46. return result.data || [];
  47. }
  48. // 基本方法 计算匹配的时间段下 过滤车型车系和驾驶模式 后时间分组下 维度分布分组数据之和
  49. async statsWithMode({ type, startTime, endTime, seriesCode, modelCode, mode }, vString) {
  50. const { ctx } = this;
  51. const cond = [{ $match: {} }];
  52. if (seriesCode) {
  53. cond[0].$match['data._id.series_code'] = seriesCode;
  54. }
  55. if (modelCode) {
  56. cond[0].$match['data._id.model_code'] = modelCode;
  57. }
  58. const dict = ctx.helper.statusInfoDict[vString];
  59. const obj = {};
  60. const project = { data: [] };
  61. if (mode) {
  62. for (let i = 1; i < dict.num + 1; i++) {
  63. const key = dict.v.replace('=', i);
  64. obj[i] = { $sum: `$data.${dict.k}.${mode}.${key}` };
  65. project.data.push({ _id: i + '', count: `$${i}` });
  66. }
  67. } else {
  68. for (let i = 1; i < dict.num + 1; i++) {
  69. const key = dict.v.replace('=', i);
  70. const sumArr = dict.mode.map(item => {
  71. return `$data.${dict.k}.${item}.${key}`;
  72. });
  73. const sum = { $add: sumArr };
  74. obj[i] = { $sum: sum };
  75. project.data.push({ _id: i + '', count: `$${i}` });
  76. }
  77. }
  78. const agg = [
  79. { $match: ctx.helper.getTimeRangMatch(startTime, endTime) },
  80. { $unwind: '$data' },
  81. ...cond,
  82. { $group: ctx.helper.getTimeGroup(type, obj) },
  83. { $project: project },
  84. ];
  85. return await ctx.model.Local.StatsBaseInfoModel2.aggregateFix(agg);
  86. }
  87. // 计算匹配的时间段下 过滤车型车系后 两个维度分布下 数据之和 [x,y,z]
  88. async acceAndAs({ type, startTime, endTime, seriesCode, modelCode }, vString) {
  89. const { ctx } = this;
  90. const cond = [{ $match: {} }];
  91. if (seriesCode) {
  92. cond[0].$match['data._id.series_code'] = seriesCode;
  93. }
  94. if (modelCode) {
  95. cond[0].$match['data._id.model_code'] = modelCode;
  96. }
  97. const dict = ctx.helper.statusInfoDict.statsSpAcceCnt.multi[vString];
  98. const obj = {};
  99. const project = { data: [] };
  100. for (let j = 1; j < dict.superNum + 1; j++) {
  101. for (let i = 1; i < dict.num + 1; i++) {
  102. const key = dict.v.replace('=', j).replace('=', i);
  103. obj[`${j}${i}`] = { $sum: `$data.${dict.k}.${key}` };
  104. project.data.push([ j - 1, i - 1, `$${j}${i}` ]);
  105. }
  106. }
  107. const agg = [
  108. { $match: ctx.helper.getTimeRangMatch(startTime, endTime) },
  109. { $unwind: '$data' },
  110. ...cond,
  111. { $group: { _id: null, ...obj } },
  112. { $project: project },
  113. ];
  114. const result = await ctx.model.Local.StatsBaseInfoModel2.aggregateNGroup(agg);
  115. return result.data || [];
  116. }
  117. // 基本方法 计算匹配的时间段下 过滤车型车系后时间分组下 维度分布分组数据之和
  118. async stats({ type, startTime, endTime, seriesCode, modelCode }, vString) {
  119. const { ctx } = this;
  120. const cond = [{ $match: {} }];
  121. if (seriesCode) {
  122. cond[0].$match['data._id.series_code'] = seriesCode;
  123. }
  124. if (modelCode) {
  125. cond[0].$match['data._id.model_code'] = modelCode;
  126. }
  127. const dict = ctx.helper.statusInfoDict[vString];
  128. const obj = {};
  129. const project = { data: [] };
  130. for (let i = 1; i < dict.num + 1; i++) {
  131. const key = dict.v.replace('=', i);
  132. obj[i] = { $sum: `$data.${dict.k}.${key}` };
  133. project.data.push({ _id: i + '', count: `$${i}` });
  134. }
  135. const agg = [
  136. { $match: ctx.helper.getTimeRangMatch(startTime, endTime) },
  137. { $unwind: '$data' },
  138. ...cond,
  139. { $group: ctx.helper.getTimeGroup(type, obj) },
  140. { $project: project },
  141. ];
  142. return await ctx.model.Local.StatsBaseInfoModel2.aggregateFix(agg);
  143. }
  144. // 统计清洗
  145. async statistics({ timeRangData, initData, isForceUpdate }) {
  146. const { ctx } = this;
  147. const hasData = await ctx.service.statisticsService.saveBefore(ctx.model.Local.StatsBaseInfoModel2,
  148. { ...initData });
  149. if (hasData && !isForceUpdate) {
  150. return;
  151. }
  152. initData.start_time = new Date();
  153. const data = await this.group(timeRangData);
  154. ctx.logger.info('任务进行group');
  155. await this.ctx.service.statisticsService.save(this.ctx.model.Local.StatsBaseInfoModel2,
  156. { ...initData, data }, isForceUpdate);
  157. }
  158. async group({ startTime, endTime }) {
  159. const { ctx } = this;
  160. const result = this.getCond(ctx.helper.getStatusInfoArr());
  161. const agg = [
  162. { $match: ctx.helper.getTimeRangMatch(startTime, endTime, 'start_time') },
  163. { $lookup: { from: 't_vehicle_record', localField: 'vin', foreignField: 'vin', as: 'car' } },
  164. { $unwind: { path: '$car', preserveNullAndEmptyArrays: true } },
  165. { $group: {
  166. _id: { series_code: '$car.series_code', model_code: '$car.model_code' },
  167. ...result.cond,
  168. } },
  169. { $project: result.projcet },
  170. ];
  171. return await ctx.model.StatsBaseInfoModel.aggregateFix(agg);
  172. }
  173. // dbStr数据库字段名称 //localStr本地形成字段名称 //分几段 //是否存在驾驶模式那一层
  174. getCond(arr) {
  175. // dbStr = 'stats_acce_cnt.dr_mode_auto.ar=', num = 10
  176. const cond = {};
  177. const projcet = {};
  178. arr.forEach(item => {
  179. if (item.superNum) {
  180. for (let j = 1; j < item.superNum + 1; j++) {
  181. for (let i = 1; i < item.num + 1; i++) {
  182. const str = item.dbStr.replace('=', j).replace('=', i);
  183. const key = str.replace(/\./g, '');
  184. cond[key] = { $sum: `$${str}` };
  185. projcet[str] = `$${key}`;
  186. }
  187. }
  188. } else {
  189. for (let i = 1; i < item.num + 1; i++) {
  190. const str = item.dbStr.replace('=', i);
  191. const key = str.replace(/\./g, '');
  192. cond[key] = { $sum: `$${str}` };
  193. projcet[str] = `$${key}`;
  194. }
  195. }
  196. });
  197. return { cond, projcet };
  198. }
  199. }
  200. module.exports = StatsBaseInfoService2;