MongoDB多字段条件查询失效排查:按类型过滤过期数据
MongoDB 5.0.2 查询未按类型匹配过期字段问题排查与解决
问题原因
你的查询逻辑存在核心漏洞:没有将type字段与对应过期字段的条件绑定。当前的$or条件会匹配所有满足任一过期字段小于指定日期的文档,完全忽略了文档的type属性。比如一个type为event的文档,只要它的regular_end_date符合条件,就会被错误返回,这和你的需求完全不符。
正确查询写法
需要为每个$or分支添加type的匹配条件,确保只有对应类型的文档才会检查对应的过期字段:
1. find 查询
db.data.find({ "$or": [ { "type": "project", "project_end_time": { "$lt": ISODate("2022-12-27T10:09:49.753Z") } }, { "type": "regular", "regular_end_date": { "$lt": ISODate("2022-12-27T10:09:49.753Z") } }, { "type": "event", "$expr": { "$lt": [ { "$getField": { "field": "date", "input": { "$last": "$events" } } }, ISODate("2022-12-27T10:09:49.753Z") ] } } ] })
2. 聚合管道查询
db.data.aggregate([ { $match: { "$or": [ { "type": "project", "project_end_time": { "$lt": ISODate("2022-12-27T10:09:49.753Z") } }, { "type": "regular", "regular_end_date": { "$lt": ISODate("2022-12-27T10:09:49.753Z") } }, { "type": "event", "$expr": { "$lt": [ { "$getField": { "field": "date", "input": { "$last": "$events" } } }, ISODate("2022-12-27T10:09:49.753Z") ] } } ] } } ])
补充说明
- 每个
$or子条件都同时限制了type和对应过期字段,确保只有类型匹配的文档才会被检查对应字段。 - 对于
event类型,你原本使用$expr配合$last和$getField获取数组最后一个元素date的逻辑是正确的,只需添加type: "event"的条件即可修正匹配逻辑。
内容的提问来源于stack exchange,提问作者Denny Pradipta
相关产品推荐
相关产品推荐

