MongoDB(Node.js+Mongoose)日期比较查询返回null问题排查
解决MongoDB(Mongoose)日期区间查询返回null的问题
嘿,我来帮你搞定这个日期查询的坑!你的问题主要出在两个地方:日期条件逻辑写反了,还有数组字段的多条件匹配方式不对,下面一步步给你拆解和修正:
1. 先修正日期比较的逻辑(最关键的错误)
你要找的是「当前日期处于fromdate和todate之间」的广告,也就是:fromdate ≤ 当前日期 ≤ todate
但你写的查询条件完全搞反了:
"advertisment.fromdate": { $gte: currentDate }, // 要求fromdate≥当前日期(你的fromdate是2010年,肯定不满足) "advertisment.todate": { $lte: currentDate }, // 要求todate≤当前日期(你的todate是2030年,也不满足)
正确的日期条件应该是:
"advertisment.fromdate": { $lte: currentDate }, // fromdate早于/等于当前日期 "advertisment.todate": { $gte: currentDate } // todate晚于/等于当前日期
2. 修复数组元素的多条件匹配逻辑
直接给数组的子字段单独加条件(比如"advertisment.active": true + "advertisment.fromdate": {...}),MongoDB会理解为:数组里只要有某个元素满足active:true,同时有某个元素满足日期条件,就会返回整个文档,但你要的是同一个广告元素同时满足所有条件。
这时候需要用$elemMatch来把多个条件绑定到数组的同一个元素上:
方案1:查询包含符合条件元素的文档(返回整个数组)
let currentDate = new Date(); Setting.findOne( { "advertisment": { $elemMatch: { active: true, fromdate: { $lte: currentDate }, todate: { $gte: currentDate } } } }, 'advertisment' ) .then(data => { console.log(data); // 注意:这里返回的是整个advertisment数组,如果只想拿到符合条件的元素,看方案2 }) .catch(err => console.log(err))
方案2:只返回数组中符合条件的元素(用聚合管道)
如果不想返回整个数组,只想提取出满足条件的广告元素,可以用$filter在聚合管道里过滤:
let currentDate = new Date(); Setting.aggregate([ // 先筛选出包含符合条件广告的文档 { $match: { "advertisment": { $elemMatch: { active: true, fromdate: { $lte: currentDate }, todate: { $gte: currentDate } } } } }, // 再过滤出数组中真正符合条件的元素 { $project: { advertisment: { $filter: { input: "$advertisment", as: "ad", cond: { $and: [ { $eq: ["$$ad.active", true] }, { $lte: ["$$ad.fromdate", currentDate] }, { $gte: ["$$ad.todate", currentDate] } ] } } } } } ]) .then(data => { console.log(data); }) .catch(err => console.log(err))
3. 额外修复:Schema里的default值问题
你的Schema中fromdate的default写的是Date.now(),这会导致Schema定义时就把这个时间固定下来,所有新创建的文档都会用同一个固定时间,而不是创建文档时的当前时间。应该改成不带括号的Date.now,这样每次创建文档时才会调用这个函数生成当前时间:
const SettingSchema = new Schema({ advertisment: [ { name: { type: String, required: true }, fromdate: { type: Date, default: Date.now }, // 去掉括号! todate: { type: Date }, active:{ type:Boolean } } ] });
这样调整后,你的查询应该就能正常返回符合条件的文档了!
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

