版本 | 修订记录 | 日期 | 修订者 |
---|---|---|---|
1.0 | 初稿 | 2019-07-31 | 翟智刚 |
[TOC]
计算指标规则定义说明
计算指标的规则定义以json字符串的方式存储于指标定义表的regular字段,具体模型定义、计算流程、以及示例见下面说明。
1、模型定义
参数名 | 参数含义 | 取值范围及说明 |
---|---|---|
CONFIG | 可选。指标参数配置。 | 数组。该参数用于WEB前台进行指标阈值参数配置。详情见下表。 |
DEF | 必选。源指标与计算指标数据依赖关系定义。 | 数组。 每个元素为一个源指标信息说明的json对象。 详细说明见< |
COND | 必选。 脚本是否可执行的判断条件。 |
字符串。 一个可以执行的JS表达式,返回值为true或false。 |
JS | 必选。计算脚本。 | 字符串。 根据注入源对象缓存值、内置对象等信息进行指标计算的JS脚本。 脚本必须返回一个number值。 |
CONFIG说明
参数名 | 参数含义说明 |
---|---|
TITLE | 必选。参数标题。字符串类型。 |
CODE | 必选。参数名。字符串类型。代表参数表中参数名。此值不能轻易改变,改变需要修改代码。 |
DEFAULT_VALUE | 必选。参数默认值。number类型。 |
说明:原生指标计算时也会用到此CONFIG配置。
DEF参数定义
参数名 | 参数含义 | 取值范围及说明 |
---|---|---|
M | 必选。源指标编码。 | 字符串。 |
OBJ | 必选。对象模式。 | 字符串。SINGLE/单对象,MULTI/多对象。 多对象用于不同对象类型指标之间的计算关系。 |
PERIOD | 必选。周期模式。 | 字符串。 SINGLE/单周期,MULTI多周期 表示源指标采集多少个周期的点才开始计算指标的计算。 |
SIZE | 可选。预留点个数 | 整数。 取值范围0~100,默认值为0(代表全部清除) 不为零表示计算完成后,清理源指标缓存时,从队列尾部预留点的个数。 只有多周期时此值配置有效。 |
JS&COND内置对象说明
对象名 | 对象说明 |
---|---|
$P | 用户自定义参数表注入 |
$R | 运行时动态参数注入,详细说明见$R表说明。 |
N** | 源指标缓存值注入对象,下面简称N。 单对象单周期时,N为单值,源指标的值。 单对象多周期时,N为一维数组,维度为周期点个数。 多对象单周期时,N为一维数组,维度为对象实例个数。 多对象多周期时,N为二维数组,1维度为对象实例个数,2维度为周期点个数。 说明:多对象时不支持多指标配置。 |
$F | 内置函数对象。公共函数都绑定在此对象上。 |
$R内置函数说明
函数名 | 函数含义说明 |
---|---|
OBJ_**_NUM | 表示指标编码(本文内都表示指标编码,不再赘述)。 该属性表示在多对象时,缓存区已经存在的有指标值的对象个数。 |
GW_NUM | 基站总数(GATEWAY_NUM) |
NODE_NUM | 节点总数(NODE_NUM) |
NIG_NUM | 节点组内节点总数(NODE_IN_GROUP_NUM),仅在对象类型为节点组时有此值。 |
NG_NUM | 节点组总数(NODE_GROUP_NUM) |
$F内置函数说明
函数名 | 函数含义说明 |
---|---|
exist | 判断内置对象是否存在 |
boolRatio1 | 布尔值数组求真占比 |
boolRatio0 | 布尔值数组求假占比 |
sumproduct | 加权求和 |
sumaverage | 加权平均 |
sum | 求和 |
average | 平均 |
说明:函数详细用法说明见本文档附录2
2、计算流程
- 每个指标值产生后,根据源指标与计算指标配置关系,判断该指标是否为某个计算指标的源指标。
- 如果为真,则根据关系配置信息进行源指标值缓存,将指标值推入缓冲队列。
- 缓存操作完成后,执行COND。
- 如果为真,则执行JS,返回结果为该计算指标的值。
- 指标值计算完成后,根据SIZE值进行缓存清理。
3、配置示例
2061指标计算
{
"DEF": [
{ "M":"2047", "OBJ":"SINGLE", "PERIOD":"SINGLE"},
{ "M":"2049", "OBJ":"SINGLE", "PERIOD":"SINGLE"}
],
"COND":"$F.exist(N2047) && $F.exist(N2049)",
"JS":"var val = (N2047==0?0:(N2047-2049)*100/N2047);val.toFixed(1);"
}
2002指标计算
{
"DEF": [
{ "M":"2001","SIZE":11, "OBJ":"SINGLE", "PERIOD":"MULTI"}
],
"COND":"$F.exist(N2001) && N2001.length>=12",
"JS":"$F.boolRatio1(N2001, 1);"
}
2003指标计算
{
"DEF": [
{ "M":"2001","SIZE":0, "OBJ":"SINGLE", "PERIOD":"MULTI"}
],
"COND":"$F.exist(N2001) && N2001.length>=12",
"JS":"$F.boolRatio1(N2001, 1);"
}
1004指标计算
{
"DEF": [
{ "M":"3001", "OBJ":"MULTI", "PERIOD":"SINGLE"}
],
"COND":"$F.exist(N3001) && N3001.length>=$R.OBJ_3001_NUM",
"JS":"$F.sum(N3001);"
}
4、计算指标计算流程
附录1、各种维度组合支持情况
指标 | 对象 | 周期 | 滑窗 | 分段 | 说明 |
---|---|---|---|---|---|
单 | 单 | 单 | 不涉及 | 支持 | |
单 | 单 | 多 | 支持 | 支持 | 单指标单对象多周期滑窗式计算指标,单指标单对象多周期分段式计算指标 |
单 | 多 | 单 | 不涉及 | 支持 | 单指标多对象单周期计算指标 |
单 | 多 | 多 | 支持 | 支持 | |
多 | 单 | 单 | 不涉及 | 支持 | 多指标单对象单周期计算指标 |
多 | 单 | 多 | 支持 | 支持 | 多指标单对象多周期分段式计算指标 |
多 | 多 | 单 | 不涉及 | 支持 | |
多 | 多 | 多 | 支持 | 支持 |
附录2、计算指标内置函数
exist
function exist(v) {
return typeof(v) != 'undefined' && v != null && (Array.isArray(v) ? v.length > 0 : true);
}
boolRatio1
布尔量数组求真占比。源指标汇集数据集为一维数组,其值为整型,且只有0,1两种取值,例如:[1,0,0,1,1],该规则value=(count(1)/size).toFixed(fixed)。fixed为保留小数位数,四舍五入。
/**
* 布尔量数组求真占比
* @param arr
* @precision, 保留几位小数
* @returns {number}
*/
function boolRatio1(arr, precision) {
var sum = 0;
for (var i in arr) {
if (arr[i] >= 1) {
sum++;
}
}
var val = sum * 100 / arr.length;
return precision==undefined?val:val.toFixed(precision);
}
boolRatio0
布尔量数组求假占比。源指标汇集数据集为一维数组,其值为整型,且只有0,1两种取值,例如:[1,0,0,1,1],该规则value=(count(0)/size).toFixed(fixed)。fixed为保留小数位数,四舍五入。
/**
* 布尔量数组求假占比
* @param arr
* @precision, 保留几位小数
* @returns {number}
*/
function boolRatio0(arr,precision) {
var sum = 0;
for (var i in arr) {
if (arr[i] < 1) {
sum++;
}
}
var val = sum * 100 / arr.length;
return precision==undefined?val:val.toFixed(precision);
}
sumproduct
加权求和。对一维数据进行加权求和。形如:sumproduct(array, [coef])。array为一维或二维数组。coef为权值,如果没有给coef值,则默认为1,等效于sum函数;如果coef为单值则所有元素权值相同;如果coef为一维数组,则与arr的某个维度等长。如果coef为二维数组,则系数全匹配。
/**
* 加权求和
* @param arr
* @param coef 系数矩阵
* @returns {number}
*/
function sumproduct(arr, coef) {
var sum = 0;
if (Array.isArray(arr) && !Array.isArray(arr[0])) {
for (var i in arr) {
if (coef == undefined || coef == null) {
sum += arr[i];
}
else if (Array.isArray(coef)) {
sum += arr[i] * coef[i];
}
else {
sum += arr[i] * coef;
}
}
}
else if (Array.isArray(arr) && Array.isArray(arr[0])) {
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[0].length; j++) {
if (coef == undefined || coef == null) {
sum += arr[i][j];
}
else if (Array.isArray(coef) && !Array.isArray(coef[0])) {
if (coef.length == arr[0].length) {
sum += arr[i][j] * coef[j];
}
else if (coef.length == arr.length) {
sum += arr[i][j] * coef[i];
}
else {
sum += arr[i][j] * coef;
}
} else if (Array.isArray(coef) && Array.isArray(coef[0])) {
sum += arr[i][j] * coef[i][j];
} else {
sum += arr[i][j];
}
}
}
} else {
sum = 0;
}
return sum;
}
sumaverage
加权平均。对一维数据进行加权平均。形如:sumaverage(array, [coef])。array为一维数组。coef为权值,如果没有给coef值,则默认为1,等效于average函数;如果coef为单值则所有元素权值相同;如果coef为数组,则长度必须与array等长。
/**
* 加权平均
* @param arr
* @param coef
* @param precision
*/
function sumaverage(arr, coef, precision) {
var sum = sumproduct(arr, coef);
var count;
if (Array.isArray(arr) && !Array.isArray(arr[0])) {
count = arr.length;
} else if (Array.isArray(arr) && Array.isArray(arr[0])) {
count = arr.length * arr[0].length;
} else {
count = 1;
}
var val = sum / count;
return precision == undefined ? val : val.toFixed(precision);
}
sum
求和。对一维数据进行求和。
/**
* 求和
* @param arr
*/
function sum(arr) {
return sumproduct(arr);
}
average
平均。对一维数据进行平均。
/**
* 平均
* @param arr
* @param precision, 保留几位小数
*/
function average(arr, precision) {
return sumaverage(arr, 1, exist(precision) ? precision : 1);
}
max
求数组的最大值。
/**
* 求数组最大值
* @param arr, 一维数组或二维数组
* @returns {number}
*/
function max(arr) {
var maxnum = -Infinity;
if(!exist(arr)) return 0;
if (Array.isArray(arr) && !Array.isArray(arr[0])) {
maxnum = Math.max.apply(null, arr);
}else if(Array.isArray(arr) && Array.isArray(arr[0])){
for(var i=0;i<arr.length;i++){
var tmp = Math.max.apply(null, arr[i]);
if(tmp>maxnum){
maxnum = tmp;
}
}
}
return maxnum;
}
min
求数组的最小值。
/**
* 求数组最小值
* @param arr
* @returns {number}
*/
function min(arr) {
var minnum = Infinity;
if(!exist(arr)) return 0;
if (Array.isArray(arr) && !Array.isArray(arr[0])) {
minnum = Math.min.apply(null, arr);
}else if(Array.isArray(arr) && Array.isArray(arr[0])){
for(var i=0;i<arr.length;i++){
var tmp = Math.min.apply(null, arr[i]);
if(tmp<minnum){
minnum = tmp;
}
}
}
return minnum;
}