MongoDB时间范围查询返回空结果,寻求排查提示
MongoDB查询返回空数组的排查思路
问题场景
我有如下MongoDB集合数据:
[{ "_id": { "$oid": "63b79f9e5c98b4aa46719920" }, "time": { "$numberLong": "1672978334287" }, "tvl": 0.005495200757897796, "wethToken1": true },{ "_id": { "$oid": "63b79fad5c98b4aa46719921" }, "time": { "$numberLong": "1672978349046" }, "tvl": 0.010990401515795592, "wethToken1": true },{ "_id": { "$oid": "63b7a0ee5c98b4aa46719922" }, "time": { "$numberLong": "1672978670070" } }]
需要基于from(固定为Date.now())和to参数做时间范围查询,但执行下面的代码后,docArr始终返回空数组,怀疑问题出在查询条件部分:
const queryTVL = async (from) => { // const formatedFrom = NumberLong(from) // const formatedTo = NumberLong(to) try { const collection = await mongoClient.db("tangle-db").collection("tvl") const documents = await collection.find({ "time": { "$gt": from } }).toArray() let docArr = [] documents.map((data) => { console.log(data, 'data') docArr.push({ tvl: data.tvl, time: data.time }) }) console.log(docArr) return docArr } catch (error) { console.log(error, 'for getLastTVL') } }
排查思路
- 数据类型不匹配:集合中的
time字段存储为NumberLong类型,而Date.now()返回的是普通JavaScript数字,MongoDB会严格校验数据类型,直接用普通数字和NumberLong比较会导致匹配失败。取消代码中注释的const formatedFrom = NumberLong(from)这行,将from转换为NumberLong后再传入查询条件。 - 时间范围逻辑错误:
from是当前时间戳(比如现在是1700000000000左右),而集合内的time都是更早的历史时间戳(167开头),用$gt会查询比当前时间晚的记录,自然没有结果。如果要查询历史数据,应该调整为$lt: from;如果是结合to的范围查询,正确条件应为"time": {$gte: formatedTo, $lt: formatedFrom}(假设to是更早的时间)。 - 验证时间戳数值:打印
from的具体值,和集合内的time数值做对比,确认是否真的存在符合条件的记录。 - 检查字段与集合正确性:确认查询的集合名称是
tvl、字段名是time,没有拼写错误;同时注意集合中部分文档缺失tvl字段,后续处理需兼容这种情况。 - 直接在MongoDB客户端测试:用Mongo Shell或Compass执行原生查询,比如
db.tvl.find({time: {$gt: NumberLong(Date.now())}}),验证是否能返回数据,排除代码层面的问题。
内容的提问来源于stack exchange,提问作者Rodrigo Burgos
相关产品推荐
相关产品推荐

