BSON文档字符串转DateTime:MongoDB嵌套数组日期过滤问题求助
解决MongoDB嵌套数组的日期范围过滤问题
文档结构
MongoDB中存储的文档对应以下C#实体类:
public class BookingDocument{ public string Id {get;set;} public List<ActivityDocument> Activities {get;set;} public string Status {get;set;} } public class ActivityDocument { public string DateFrom {get;set;} public string Status {get;set;} }
当前处理逻辑
已实现的日期转换逻辑如下:
public async Task<List<BookingDocument>> ActivityBookingList(string start,string end) { DateTime startDate; DateTime endDate; startDate = DateTime.ParseExact(start + " " + "00:00:00", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); endDate = DateTime.ParseExact(end + " " + "00:00:00", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); // 待补充过滤逻辑 }
遇到的问题
尝试三种过滤方案均存在异常:
- 方案1:使用
$dateFromString时,报错"$dateFromString only supports an object as an argument, found: string" - 方案2:使用
$toDate时,报错"Unsupported conversion from array to date in $convert with no onError value" - 方案3:可返回结果,但仅检查
Activities数组的第一个元素
解决方案
核心需求是过滤出至少包含一个Activity的DateFrom落在指定日期范围内的BookingDocument,需正确处理字符串转日期并遍历数组所有元素,以下是基于MongoDB .NET驱动的实现:
public async Task<List<BookingDocument>> ActivityBookingList(string start, string end) { DateTime startDate = DateTime.ParseExact(start + " 00:00:00", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); DateTime endDate = DateTime.ParseExact(end + " 00:00:00", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); // 构建聚合管道 var pipeline = new BsonDocument[] { new BsonDocument("$match", new BsonDocument { { "Activities", new BsonDocument("$elemMatch", new BsonDocument { { "$expr", new BsonDocument("$and", new BsonArray { // 转换DateFromString并判断是否大于等于起始日期 new BsonDocument("$gte", new BsonArray { new BsonDocument("$dateFromString", new BsonDocument { { "dateString", "$DateFrom" }, { "format", "%Y-%m-%d" } // 需与DateFrom存储的格式一致,若带时间则改为"%Y-%m-%d %H:%M:%S" }), startDate }), // 转换DateFromString并判断是否小于等于结束日期 new BsonDocument("$lte", new BsonArray { new BsonDocument("$dateFromString", new BsonDocument { { "dateString", "$DateFrom" }, { "format", "%Y-%m-%d" } }), endDate }) }) }) } }) }; // 执行聚合查询并返回结果 var collection = _mongoDatabase.GetCollection<BookingDocument>("BookingList"); return await collection.Aggregate<BookingDocument>(pipeline).ToListAsync(); }
错误原因说明
- 方案1错误:
$dateFromString要求传入包含dateString、format等字段的对象,而非直接传入字符串字段引用,正确写法应为$dateFromString: { dateString: "$DateFrom", format: "..." } - 方案2错误:直接对
Activities数组使用$toDate,而非数组中每个元素的DateFrom字段,导致MongoDB尝试将整个数组转换为日期,触发类型转换错误 - 方案3错误:未使用
$elemMatch,直接通过Activities.DateFrom访问数组字段时,MongoDB默认仅检查数组第一个元素的对应字段
内容的提问来源于stack exchange,提问作者AG Mohamed
相关产品推荐
相关产品推荐

