You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoTemplate查询两个日期间数据无结果问题求助

问题:MongoDB日期范围查询返回空结果

问题详情

MongoDB中的数据格式如下:

{
  "_id": {
    "$oid": "669e141c218c685d8483e0c8"
  },
  "artifact": "dummy data for development",
  "createTime": "7-11-2024 07:48:48"
}

使用MongoTemplate生成的查询语句:

{ "createTime" : { "$gte" : "07-01-2024", "$lte" : "07-24-2024"}}

对应的Java代码:

@Autowired
MongoTemplate mongoTemplate;

Query query = new Query();
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
query.addCriteria(Criteria.where("createTime").gte(sdf.format(startDate)).lte(sdf.format(endDate)));

List<Entity> result = mongoTemplate.find(query, Entity.class);

执行后返回空结果,在Mongo Compass中执行该查询语句也无结果。

原因分析

  1. 字符串格式不匹配:数据中的createTime月份是单数字格式(如7-11-2024),而查询条件使用双数字月份格式(如07-01-2024)。MongoDB对字符串做字典序比较时,"7-"的ASCII码大于"07-",因此"7-11-2024 07:48:48"会被判定为大于"07-24-2024",无法被$lte条件匹配。
  2. 时间精度缺失:数据中的createTime包含时分秒信息,但查询条件仅为日期字符串,即使格式匹配,也可能漏掉当天带时分秒的后续数据。

解决方案

方案一:将createTime改为Date类型(推荐)

将字符串类型的日期改为MongoDB原生的Date类型,是最规范的做法,能彻底避免字符串比较的各种问题。

  1. 更新现有数据:使用MongoDB命令将字符串转成Date类型
db.collection.updateMany(
  {},
  [
    {
      $set: {
        createTime: {
          $dateFromString: {
            dateString: "$createTime",
            format: "%m-%d-%Y %H:%M:%S"
          }
        }
      }
    }
  ]
)

(注意替换collection为你的实际集合名称)

  1. 修改Java实体类:将createTime字段类型改为Date
import java.util.Date;

public class Entity {
    private String artifact;
    private Date createTime;
    
    // getter和setter方法
}
  1. 简化查询代码:直接用Date对象进行范围查询,无需格式化字符串
@Autowired
MongoTemplate mongoTemplate;

Query query = new Query();
query.addCriteria(Criteria.where("createTime").gte(startDate).lte(endDate));

List<Entity> result = mongoTemplate.find(query, Entity.class);

方案二:统一字符串格式(临时方案)

如果无法修改字段类型,需要确保查询条件的字符串格式与数据完全一致,并处理时分秒的精度问题:

@Autowired
MongoTemplate mongoTemplate;

Query query = new Query();
// 使用与数据一致的单数字月份格式
SimpleDateFormat dateFormat = new SimpleDateFormat("M-dd-yyyy");
// 处理结束日期,拼接当天最后一刻的时分秒,确保包含当天所有数据
SimpleDateFormat fullDateFormat = new SimpleDateFormat("M-dd-yyyy HH:mm:ss");
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
endCalendar.set(Calendar.HOUR_OF_DAY, 23);
endCalendar.set(Calendar.MINUTE, 59);
endCalendar.set(Calendar.SECOND, 59);

query.addCriteria(Criteria.where("createTime")
        .gte(dateFormat.format(startDate))
        .lte(fullDateFormat.format(endCalendar.getTime())));

List<Entity> result = mongoTemplate.find(query, Entity.class);

内容的提问来源于stack exchange,提问作者Shailesh Vikram Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:57:08