MongoDB聚合查询返回空结果但数据库存在匹配记录问题求助
MongoDB查询返回空结果的原因及解决方案
问题原因
- 方法调用错误:
find()方法不支持传入聚合管道数组格式的参数,包含$match的管道参数仅可用于aggregate()聚合方法,find()仅接收单个查询条件对象作为首个入参。 - 时间格式非法:ISO 8601时间规范的小时取值范围为
00-23,不存在24:01:00的写法,2021-08-15T24:01:00Z实际等价于2021-08-16T00:01:00Z,MongoDB解析非法时间字符串时会直接判定条件不匹配。 - 数据类型不匹配:如果数据库中
estimatedArrivalDate字段存储的是ISODate日期类型而非字符串类型,直接用字符串做$lt/$gt比较会返回不匹配。 - 字段值匹配偏差:如果嵌套字段
complianceReference为数组类型,或者字段名拼写有误、字段值存在大小写/首尾空格差异,也会导致匹配失败。
修复方案
方案1:使用普通find查询(优先推荐,语法更简洁)
将所有查询条件合并为单个对象传入find(),修正时间格式和类型:
db.portcall.find({ "vesselCode": "Q3Y", "arrivalVoyageCode": "128S", "complianceReference.type": "Advance Manifest", "complianceReference.loadPort": "EGPSDTM", "estimatedArrivalDate": { "$lt": ISODate("2021-08-16T00:01:00Z"), "$gt": ISODate("2021-08-15T22:01:00Z") } })
方案2:使用aggregate聚合查询
如果后续需要叠加其他聚合操作,改用aggregate()方法传入管道:
db.portcall.aggregate([ { "$match": { "vesselCode": "Q3Y", "arrivalVoyageCode": "128S", "complianceReference.type": "Advance Manifest", "complianceReference.loadPort": "EGPSDTM", "estimatedArrivalDate": { "$lt": ISODate("2021-08-16T00:01:00Z"), "$gt": ISODate("2021-08-15T22:01:00Z") } } } ])
额外排查步骤
如果修改后仍返回空结果,可按以下步骤定位问题:
- 先执行
db.portcall.findOne({"vesselCode": "Q3Y"})确认基础条件有匹配数据,再逐一添加其他查询条件,定位到触发匹配失败的条件 - 检查字段名拼写、字段值的大小写、首尾空格是否和数据库中存储的内容完全一致
- 验证
estimatedArrivalDate的存储类型,执行typeof db.portcall.findOne({"vesselCode": "Q3Y"}).estimatedArrivalDate,如果返回object说明是日期类型,必须用ISODate()构造函数包裹比较值
内容的提问来源于stack exchange,提问作者madhu
相关产品推荐
相关产品推荐

