无法通过PHP查询MongoDB中的ISODate类型日期
解决MongoDB按ISODate日期范围查询失效的问题
嘿,我看你遇到了日期查询不生效的问题——其他字段的搜索都正常,唯独日期过滤没效果,大概率是日期类型不匹配加上查询语法的小失误导致的,咱们一步步来搞定它:
问题出在哪?
你现在传给MongoDB的$startDate是字符串格式(比如"2018-07-13"),但数据库里的createdDate是ISODate类型的对象。直接拿字符串和ISODate对比,MongoDB根本认不出来这是同一个维度的日期,自然查不到结果。另外,你把$gte的值放到数组里也是错的,$gte应该直接对应单个日期值,不是数组哦。
修正步骤
1. 把字符串日期转成MongoDB能识别的类型
在PHP里,你需要把用户输入的日期字符串转换成MongoDB的日期对象。如果用的是新版MongoDB扩展(mongodb/mongodb),就用MongoDB\BSON\UTCDateTime;要是旧版的mongo扩展,就用MongoDate。举个例子:
// 假设用户输入的起始日期是"2018-07-13",结束日期是"2018-07-20" // 先把字符串转成时间戳,加上时分秒确保范围准确 $startTimestamp = strtotime($startDate . " 00:00:00"); $endTimestamp = strtotime($endDate . " 23:59:59"); // 转成MongoDB UTCDateTime(需要毫秒级时间戳,所以乘1000) $startMongoDate = new MongoDB\BSON\UTCDateTime($startTimestamp * 1000); $endMongoDate = new MongoDB\BSON\UTCDateTime($endTimestamp * 1000); // 旧版扩展用这个: // $startMongoDate = new MongoDate($startTimestamp); // $endMongoDate = new MongoDate($endTimestamp);
2. 调整查询条件的格式
别再把日期塞数组里了,直接给$gte和$lte赋值对应的日期对象就行:
$mquery = []; // 有起始日期就加$gte条件 if (!empty($startDate)) { $mquery['createdDate']['$gte'] = $startMongoDate; } // 有结束日期就加$lte条件 if (!empty($endDate)) { $mquery['createdDate']['$lte'] = $endMongoDate; } // 执行查询 $result = $this->__mongo_collection->find($mquery);
验证一下
你可以先在MongoDB Shell里跑个测试查询,确认逻辑没问题:
db.your_collection.find({ createdDate: { $gte: ISODate("2018-07-13T00:00:00.000Z"), $lte: ISODate("2018-07-20T23:59:59.000Z") } })
如果Shell能查到结果,那调整后的PHP代码肯定也能正常工作。
额外小提示
- 记得校验用户输入的日期格式是否合法(比如
YYYY-MM-DD),可以用DateTime::createFromFormat来验证,避免无效日期搞崩查询。 - 如果你的集合数据量不小,给
createdDate加个索引能大幅提升查询速度:
db.your_collection.createIndex({createdDate: 1})
内容的提问来源于stack exchange,提问作者Gagan Deep
相关产品推荐
相关产品推荐

