zoukankan      html  css  js  c++  java
  • 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;
        }
  • 相关阅读:
    linux之scp
    Supervisor之浅谈
    Linux 命令之 2>&1 &
    python多线程实现异步
    python之多进程demo1
    二分查找(python)
    awk命令之小结1
    修改文件权限之chmod
    处理日期数据
    stack unstack pivot 数据的透视
  • 原文地址:https://www.cnblogs.com/xyzxy/p/14265916.html
Copyright © 2011-2022 走看看