在Mongo库中的数据如下
- 字段含义
- Kpa 压力
- temperature 温度
- ts 时间戳
{
Kpa:0.7161
temperature:20
ts:1626685796539
}
{
Kpa:0.774
temperature: 80
ts: 1626685797027
}
{
Kpa:0.8319
temperature: 60
ts: 1626685798025
}
需求
- 求出 平均值 最大值 最小值 最大值时间点 最小值时间点 或者其它字段
解
- 如果只求出 平均值 最大值 最小值 可以直接使用
Aggregation
中的函数avg
max
min
例如
Aggregation.group().avg("Kpa").as(String.format("平均值#%s", "Kpa")).max("Kpa").as(String.format("最大值#%s", "Kpa"))
.min("Kpa").as(String.format("最小值#%s", "Kpa"));;
难点在于最大值时间点 最小值时间点
因为在统计的时候需要显示出最大值和最小值的时间点 或者 其它字段
所以就有了另一种方式 使用mapReduce
- map.js 存放位置
resources
目录下
function() {emit('Kpa', {'ts':this.ts,'v':this.Kpa});}
- reduce.js 存放位置
resources
目录下
function(key,values) {
const map = {};
let avg=0;
for (let i = 0; i < values.length; i++){
avg+=values[i].v
if(i == 0){
map['min'] = values[i].v
map['min_ts'] = values[i].ts
map['max'] = values[i].v
map['max_ts'] = values[i].ts
}
if(map['min']>values[i].v){
map['min'] = values[i].v
map['min_ts'] = values[i].ts
}
if(map['max']<values[i].v){
map['max'] = values[i].v
map['max_ts'] = values[i].ts
}
}
avg = (avg/values.length).toFixed(4);
map['avg'] = avg;
return map;
}
reduce.js
运行时function(key,values)
数据内容格式key=Kpa
values的数据格式[{v:0.7161,ts: 1626685798025 },{v:0.7161,ts: 1626685797027 },{v:0.7161,ts:1626685796539}]
Java
String[] tags = {"Kpa","temperature"};
// 在map.js文件中是写死的 这里改成动态的
StringBuffer mapFunction = new StringBuffer();
mapFunction.append("function() {");
for (String tag : tags) {
mapFunction.append(String.format("emit('%s', {'ts':this.ts,'v':this.%s});", tag, tag));
}
mapFunction.append("}");
MapReduceResults<Document> reduceResults = mongoTemplate.mapReduce(query, PropertiesConfig.getCollection_history(),
mapFunction.toString(),
"classpath:reduce.js",
(new MapReduceOptions()).actionReduce(),
Document.class);
- 打印Document
temperature: {min=20.0, min_ts=1626685796539, max=80.0, max_ts=1626685797027, avg=53.3333}
Kpa:{min=0.7161, min_ts=1626685796539, max=0.8319, max_ts=1626685798025, avg=0.7740}