Springboot-mongoTemplate踩坑之旅(一.BigDecimal,聚合查詢,排序,最值)


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM