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; }