如何使用字符串检索MongoDB文档中createdAt日期字段的数据
问题原因
你当前的写法无法匹配日期类型的createdAt字段,是因为MongoDB中Date类型存储的是ISODate对象而非普通字符串,正则表达式只能用于匹配字符串类型的字段值,对Date类型直接使用正则不会生效。
解决方案
根据你的使用场景可以选择以下两种方案:
方案1:聚合转字符串模糊匹配(支持任意日期片段搜索)
如果需要支持用户输入任意日期片段(比如只输入年份2021、月份11也能匹配),可以用MongoDB聚合的$dateToString操作将createdAt转为指定格式的字符串后再做正则匹配,代码示例如下:
// 查询条件构造 const queryPipeline = title ? [ { $match: { $or: [ // 原有字符串字段匹配逻辑不变 { title: { $regex: new RegExp(title), $options: "i" } }, { author: { $regex: new RegExp(title), $options: "i" } }, // 新增日期字段匹配逻辑 { $expr: { $regexMatch: { // 这里format参数要和用户输入的日期格式保持一致 // 你示例输入为「年-日-月」格式,所以用%Y-%d-%m,常用的年-月-日可改为%Y-%m-%d input: { $dateToString: { format: "%Y-%d-%m", date: "$createdAt" } }, regex: title, options: "i" } } } ] } } ] : []; // 执行查询时用aggregate代替原有的find方法 const result = await 你的Model名.aggregate(queryPipeline);
方案2:日期范围匹配(性能更高,适合规范日期输入)
如果你的搜索栏前端是用日期选择器输入、可以保证输入的是合法完整日期,推荐用日期范围查询,性能远高于聚合查询,无需改动原有查询逻辑:
let condition = {}; if (title) { const orArr = [ { title: { $regex: new RegExp(title), $options: "i" } }, { author: { $regex: new RegExp(title), $options: "i" } } ]; // 尝试将输入转为合法日期 const inputDate = new Date(title); if (!isNaN(inputDate.getTime())) { // 构造当日0点到当日23:59:59的时间范围 const dayStart = new Date(inputDate.setHours(0, 0, 0, 0)); const dayEnd = new Date(inputDate.setHours(23, 59, 59, 999)); orArr.push({ createdAt: { $gte: dayStart, $lte: dayEnd } }); } condition.$or = orArr; } // 原有find查询逻辑不变 const result = await 你的Model名.find(condition);
内容的提问来源于stack exchange,提问作者Chathushaka Lochana
相关产品推荐
相关产品推荐

