BigDecimal使用mongoTemplate.save存储进数据库的是字符串类型,排序会出现问题,两种解决方式,
1.Query对象自定义collation
重新设置默认的collation属性.collation({"locale": "zh", numericOrdering:true})再排序。
语句如下:
db.getCollection(集合名称).find({}).collation({"locale": "zh", numericOrdering:true}).sort({"realTimeConsume":-1});
这样排序就按照数值来排序,就OK了。
2.配置转换器

法一有个弊端,在使用聚合查询的时候,无法配置,这里记录下法二,以及聚合查询方式

法二:
import org.bson.types.Decimal128;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;

import java.math.BigDecimal;

@ReadingConverter
@WritingConverter
public class BigDecimalToDecimal128Converter implements Converter<BigDecimal, Decimal128> {

    public Decimal128 convert(BigDecimal bigDecimal) {
        return new Decimal128(bigDecimal);
    }

}
import org.bson.types.Decimal128;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;

import java.math.BigDecimal;

@ReadingConverter
@WritingConverter
public class Decimal128ToBigDecimalConverter implements Converter<Decimal128, BigDecimal> {

    public BigDecimal convert(Decimal128 decimal128) {
        return decimal128.bigDecimalValue();
    }

}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.*;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: 农事云
 * @description: 芒果DBhepper配置项
 * @Author: Zhangyb
 * @CreateDate: 15:37
 * @UpdateUser:
 * @UpdateDate
 * @UpdateRemark:
 * @Version: 1.0
 */

@Configuration
//@ComponentScan(basePackages = {"com.bysk.base.mongodb"}) // 将芒果DB注入Spring
public class MongoConfig  {
    @Autowired
    private MongoDatabaseFactory mongoDatabaseFactory;

    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoMappingContext mongoMappingContext) {
        mongoMappingContext.setAutoIndexCreation(true);
        mongoMappingContext.afterPropertiesSet();
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDatabaseFactory);
        MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
        // 此处是去除插入数据库的 _class 字段
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        List<Object> list = new ArrayList<>();
        list.add(new BigDecimalToDecimal128Converter());//自定义的类型转换器
        list.add(new Decimal128ToBigDecimalConverter());//自定义的类型转换器
        converter.setCustomConversions(new MongoCustomConversions(list));
        return converter;
    }

    @Bean
    public MongoMappingContext mongoMappingContext() {
        //必须重新注入
        MongoMappingContext mappingContext = new MongoMappingContext();
        return mappingContext;
    }

}

注意;MongoMappingContext 必须手动注入,否则会失败。

业务需求,采集器所有字段进行求均值

代码实现

 


@Override
public MgdbDeviceMonitorRecord getAvgForTracingForMongoDb(Long deviceId, LocalDateTime startTime, LocalDateTime endTime) {
// query.collation()
//机构id
Criteria criteria = null;
if (startTime!=null){
criteria= Criteria.where(QueryConst.MONITOR_TIME)
.gte(LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATETIME_PATTERN))
.lte(LocalDateTimeUtil.format(endTime, DatePattern.NORM_DATETIME_PATTERN));
}
//指定设备id
MgdbDeviceMonitorRecord record=null;
if (deviceId!=null){
criteria=criteria.and(QueryConst.DEVICE_ID).is(deviceId);
//构建聚合查询求AVG
MatchOperation match = Aggregation.match(criteria);
List<AggregationOperation> operations=new ArrayList<>();
// Aggregation.newAggregation()
// TypedAggregation<MgdbDeviceMonitorRecord> Aggregation
operations.add(match);
operations = mgdbDeviceMonitorRecordService.avgForFiled(MgdbDeviceMonitorRecord.class, QueryConst.EQUIPMENT_ID, operations);
Aggregation agg = Aggregation.newAggregation(operations);
TypedAggregation<MgdbDeviceMonitorRecord> mgdbDeviceMonitorRecordTypedAggregation = Aggregation
.newAggregation(MgdbDeviceMonitorRecord.class, operations);
AggregationResults<MgdbDeviceMonitorRecord> aggregate1 = mgdbDeviceMonitorRecordService.getMongoTemplate()
.aggregate(mgdbDeviceMonitorRecordTypedAggregation, MgdbDeviceMonitorRecord.class);
record=aggregate1.getMappedResults().get(0);
}
return record;
}
 

 

    public List<AggregationOperation>  avgForFiled(Class<T> t,String groupFiled,List<AggregationOperation> operations) {
        Field[] fields = t.getDeclaredFields();
        String[] strArray=new String[fields.length];
        GroupOperation group = Aggregation.group(groupFiled);
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            try {
                String name = fields[i].getName();
                System.err.println(name);
                //排除不需要的字段
                strArray[i]=name;
                group=group.avg(name).as(name);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        operations.add(group);
        return operations;
    }