Springboot-mongoTemplate踩坑之旅(一.BigDecimal,聚合查詢,排序,最值)
阿新 • • 發佈:2021-01-12
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 implementsConverter<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 必須手動注入,否則會失敗。
業務需求,採集器所有欄位進行求均值
程式碼實現
//機構id Criteria criteria = null; if (startTime!=null){ criteria= Criteria.where(QueryConst.DEVICE_ID) .gte(LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATETIME_PATTERN)) .lte(LocalDateTimeUtil.format(endTime, DatePattern.NORM_DATETIME_PATTERN)); } //指定裝置id if (deviceId!=null){ criteria=criteria.and(QueryConst.DEVICE_ID).is(deviceId); //構建聚合查詢求AVG MatchOperation match = Aggregation.match(criteria); List<AggregationOperation> operations=new ArrayList<>(); operations = mgdbDeviceMonitorRecordService.avgForFiled(MgdbDeviceMonitorRecord.class, QueryConst.EQUIPMENT_ID, operations); Aggregation agg = Aggregation.newAggregation(operations); AggregationResults<MgdbDeviceMonitorRecord> aggregate = mgdbDeviceMonitorRecordService.getMongoTemplate() .aggregate(agg, MgdbDeviceMonitorRecord.class, MgdbDeviceMonitorRecord.class); Document rawResults = aggregate.getRawResults(); }
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; }