前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记录使用mongoDB时遇到的有趣问题

记录使用mongoDB时遇到的有趣问题

作者头像
Blue_007
发布2023-10-21 12:38:38
1580
发布2023-10-21 12:38:38
举报
文章被收录于专栏:代码生涯代码生涯

一、前话

最近在开发金融类的k线、盘口业务,而这些业务的海量数据如何存储,公司的技术选型,选择了MongoDB。

而对k线这类业务来说,查询历史数据是必要的功能,所以我便开始编写对MongoDB进行查询的接口,也就是在这个时候,问题出现了。

前端在调用接口时会发过来两个时间戳(必填),一个是开始时间(startTime),另一个是结束时间(endTime),我需要显示指定时间里的数据,我心想:OK,太容易了,我直接闭眼敲…

二、代码-问题出现的场景

对参数的安全判断、验权等等代码我就不放上来了,这里采用了jpa方式查询,直接上关键代码:

代码语言:javascript
复制
public List<KLine> findAllKLine(Long startTime, Long endTime) {
    // 创建查询标准对象
    Criteria criteria = new Criteria();
    // 判断参数是否存在
    if (!ObjectUtils.isEmpty(from) || !ObjectUtils.isEmpty(to)) {
        // createTime为MongoDB文档中的一个时间类型的键值对,格式为“2018-05-11T05:58:51.122Z”
        criteria = criteria.and("createTime");
        // 开始时间
        if (!ObjectUtils.isEmpty(startTime)) {
            // 将时间戳转换为date类型
            criteria.gte(new Date(startTime));
        }
        // 结束时间
        if (!ObjectUtils.isEmpty(endTime)) {
            criteria.lte(new Date(endTime));
        }
    }
    // 封闭
    Query query = Query.query(criteria);
    // 排序规则:排序升序
    query.with(Sort.by(
        Sort.Order.asc("ts")
    ));

    // 开始查询
    List<KLine> list = mongoTemplate.find(query,KLine.class,"kline_"+xxx);

    // 直接返回,不做内容安全判断了
    return list;
}

一套下来是那么的丝滑!看着没问题,调用一下

因为modb数据库已经有大量的数据,只需要在数据库中选择两个时间段传递过来测试就行了,也就是这一套操作下来出去的问题: 我选择了一段时间,期待着他给我反馈这一段时间的数据,程序确实返回了数据,但是仔细去看这些数据就会发现时间对不上。 数据对不上,很痛苦,终究还是不太丝滑。

三、解决

我开始反复对时间戳进行修改,来确认是否是数据的问题,刚好我的同事(阿贵)过来了,他看了代码也感觉是非常奇怪,于是便回到工位去查询资料,而我也接着对线这个问题,直到同事(阿贵)他发来了一个图片:

重点:只要涉及到mongo的增删改查,它都会默认将时间-8,再进行操作。我立刻查看程序返回数据的时间,确实和我想要的数据时间相差8个小时,确实马虎了,没有注意到数据内容。

那么知道了问题在哪,就很好解决了:

代码语言:javascript
复制
public static final int TIME_PLUS_8_HOUR_MS = 28800000;

public List<KLine> findAllKLine(Long startTime, Long endTime) {
    // 创建查询标准对象
    Criteria criteria = new Criteria();
    // 判断参数是否存在
    if (!ObjectUtils.isEmpty(from) || !ObjectUtils.isEmpty(to)) {
        // createTime为MongoDB文档中的一个时间类型的键值对,格式为“2018-05-11T05:58:51.122Z”
        criteria = criteria.and("createTime");
        // 开始时间
        if (!ObjectUtils.isEmpty(startTime)) {
            // 时间戳+8个小时
            // 将时间戳转换为date类型
            criteria.gte(new Date(startTime+TIME_PLUS_8_HOUR_MS));
        }
        // 结束时间
        if (!ObjectUtils.isEmpty(endTime)) {
            criteria.lte(new Date(endTime+TIME_PLUS_8_HOUR_MS));
        }
    }
    // 封闭
    Query query = Query.query(criteria);
    // 排序规则:排序升序
    query.with(Sort.by(
        Sort.Order.asc("ts")
    ));
    
    // 开始查询
    List<KLine> list = mongoTemplate.find(query,KLine.class,"kline_"+xxx);
    
    // 直接返回,不做内容安全判断了
    return list;
}

好,记录完毕,感谢阿贵,愿你我一直在努力进步!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 代码生涯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前话
  • 二、代码-问题出现的场景
  • 三、解决
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档