如何在MongoDB C#流畅聚合API中用$toLong转日期为时间戳?
使用C#流畅聚合API实现MongoDB的$toLong日期转换
我正尝试将MongoDB聚合管道转换为C#等效实现,需要用内置的$toLong操作符把ISODate转成Unix时间戳。因为文档数量多达数百万,客户端用.ToList().Select(x => ConvertToTimestamp(x.date))的转换方式完全不可行。
示例文档
[ { "value": 100, "date": ISODate("2022-03-26T04:38:28.044Z") }, { "value": 50, "date": ISODate("2022-03-26T04:38:28.044Z") }, { "value": 23, "date": ISODate("2022-03-26T04:38:28.044Z") }, { "value": 199, "date": ISODate("2022-03-26T04:38:28.044Z") } ]
原生MongoDB聚合查询
db.collection.aggregate({ $project: { date: { $toLong: "$date" }, value: 1, } })
预期输出
[ { "_id": ObjectId("5a934e000102030405000000"), "date": NumberLong(1648269508044), "value": 100 }, { "_id": ObjectId("5a934e000102030405000001"), "date": NumberLong(1648269508044), "value": 50 }, { "_id": ObjectId("5a934e000102030405000002"), "date": NumberLong(1648269508044), "value": 23 }, { "_id": ObjectId("5a934e000102030405000003"), "date": NumberLong(1648269508044), "value": 199 } ]
C#实现方案
1. 使用BsonDocument直接构建管道(无强类型)
这种方式完全对应原生MongoDB查询,确保转换逻辑在数据库端执行:
// 获取目标集合 var collection = mongoDatabase.GetCollection<BsonDocument>("collection"); // 构建聚合管道 var pipeline = new BsonDocument[] { new BsonDocument("$project", new BsonDocument { { "date", new BsonDocument("$toLong", "$date") }, { "value", 1 } }) }; // 执行聚合查询 var result = collection.Aggregate<BsonDocument>(pipeline).ToList();
2. 强类型实体映射
如果需要将结果直接映射到C#实体类,先定义对应的实体结构:
// 原始文档实体(对应MongoDB中的原始数据结构) public class OriginalDocument { [BsonId] public ObjectId Id { get; set; } [BsonElement("date")] public DateTime Date { get; set; } [BsonElement("value")] public int Value { get; set; } } // 转换后的文档实体(对应聚合后的输出结构) public class TransformedDocument { [BsonId] public ObjectId Id { get; set; } [BsonElement("date")] public long DateTimestamp { get; set; } [BsonElement("value")] public int Value { get; set; } }
然后使用流畅API执行聚合并完成类型映射:
var collection = mongoDatabase.GetCollection<OriginalDocument>("collection"); var result = collection.Aggregate() // 用BsonDocument定义投影逻辑,对应$toLong操作 .Project(new BsonDocument { { "date", new BsonDocument("$toLong", "$date") }, { "value", 1 } }) // 将聚合结果映射到强类型实体 .As<TransformedDocument>() .ToList();
关键说明
- 两种方案均在数据库端完成日期到Unix时间戳的转换,彻底避免客户端加载数百万数据带来的性能问题。
- 使用强类型时,需确保实体类的
[BsonElement]属性与MongoDB的字段名完全匹配,避免映射失败。
内容的提问来源于stack exchange,提问作者emiliojazzar
相关产品推荐
相关产品推荐

